-2006-10-08 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * Documentation/user/page.itely (Two-pass vertical spacing): add
- documentation for two-pass spacing technique.
-
-2006-10-06 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/convert-ly.txt: new file; new
- storage place for this file (moved from bugs/ CVS).
-
-2006-10-06 Jürgen Reuter <reuter@ipd.uka.de>
-
- * lily/note-head.cc: Fixed programming_error message.
-
-2006-10-06 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-grobs.scm (pure-conversion): move pure-callback
- further into body.
-
- * scm/script.scm (default-script-alist): set avoid-slur for turn,
- marcato, stopped, thumb.
-
-2006-10-05 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/completion-note-heads-engraver.cc (process_music): don't
- skimp on memory usage.
-
- * lily/beam.cc (set_stem_lengths): do set_stemend for invisible
- stems too. Fixes #5
-
- * lily/parenthesis-engraver.cc (acknowledge_grob): set parent of
- parenthesis item. This fixes premature Y-extent triggering. Fixes
- issue #95.
-
- * VERSION (PATCH_LEVEL): bump version.
-
-2006-10-04 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/advanced-notation.itely: added
- info about instrument names for piano or other contexts,
- thanks Marcus!
-
-2006-10-04 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * mf/feta-bolletjes.mf (solfa_quarter_width): use
- solfa_base_notewidth as unit for non-DO-notes too.
-
- * input/mutopia/W.A.Mozart/mozart-hrn-3.ly: update email.
-
- * VERSION: release 2.9.21
-
- * Documentation/topdocs/NEWS.tely (Top): simpler, more clearer
- override.
-
-2006-10-04 Mats Bengtsson <mabe@drongo.s3.kth.se>
-
- * python/lilylib.py (progress): Minor fix.
-
-2006-10-04 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/note-name-engraver.cc: doc engraver.
-
- * scm/output-lib.scm (hairpin::calc-grow-direction): new function.
-
- * lily/dynamic-engraver.cc (process_music): don't set grow-direction.
-
- * scm/define-grobs.scm (all-grob-descriptions): calc duration-log
- by callback.
-
- * lily/stem-engraver.cc (make_stem): don't set duration-log
-
- * scripts/lilypond-book.py (Lilypond_file_snippet.my_system):
- write snippet-names binary.
-
- * python/lilylib.py (system): use os.system for mingw32
-
- * scripts/lilypond-book.py (bindir): use os.pathsep for prepending
- to $PATH.
-
- * scm/backend-library.scm: update email address.
-
- * Documentation/topdocs/NEWS.tely (Top): add duration-log override
- example.
-
- * scm/define-grobs.scm (all-grob-descriptions): use callback to
- calc dot count.
-
- * lily/dots-engraver.cc (class Dots_engraver): new engraver:
- handle dot creation separately.
-
- * lily/tab-note-heads-engraver.cc (process_music): idem.
-
- * lily/drum-note-engraver.cc (process_music): idem.
-
- * lily/note-heads-engraver.cc (process_music): idem.
-
- * lily/rest-engraver.cc: don't set duration-log.
-
- * scm/output-lib.scm (string-number::calc-text): new function.
- (note-head::calc-duration-log): new function.
-
- * lily/fingering-engraver.cc (make_script): remove 'text setting.
-
- * scm/output-lib.scm (fingering::calc-text): new function.
-
-2006-10-04 Mats Bengtsson <mabe@drongo.s3.kth.se>
-
- * scripts/lilypond-book.py: Fix typo gs-load-font -> gs-load-fonts
- and include-eps-font -> include-eps-fonts
-
-2006-10-03 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/multi-measure-rest-engraver.cc: use internalBarNumber
-
- * lily/timing-translator.cc: list properties.
- (start_translation_timestep): update internalBarNumber too.
-
- * scm/define-context-properties.scm
- (all-user-translation-properties): add internalBarNumber.
-
- * input/regression/spacing-no-note.ly: new file.
-
- * buildscripts/output-distance.py (link_file): verbosity for OSError.
-
- * lily/book.cc: #include cleanup.
-
- * lily/include/lily-guile-macros.hh: add assert to
- scm_or_str2symbol(SCM).
-
- * VERSION (PATCH_LEVEL): bump version.
-
- * lily/spacing-spanner.cc (musical_column_spacing): handle
- musical->nonmusical spacing case, where there is no spacing
- wish. Fixes issue #61.
-
- * lily/pango-font.cc (text_stencil): allow 'tight' bounds.
- (pango_item_string_stencil): use logical rect horizontally (to
- preserve spaces), ink_rect vertically (for time signatures).
-
- * lily/font-metric.cc (word_stencil): new interface function
-
- * input/regression/utf-8-mixed-text.ly: new file.
-
- * lily/percent-repeat-engraver.cc (listen_percent): remove
- spurious warning.
-
- * lily/phrasing-slur-engraver.cc (acknowledge_script): only ack
- non-dynamic scripts. Fixes #30.
-
- * lily/slur.cc (outside_slur_callback): make offset_scm optional.
-
- * lily/beam.cc (rest_collision_callback): make prev_offset optional.
-
- * lily/grob-closure.cc (chain_offset_callback): don't pass 0 but
- SCM_UNDEFINED for non-existent data.
-
- * lily/side-position-interface.cc (general_side_position): allow
- optional current_offset argument for chaining, so combinations of side-position
- and outside slur callback don't add up. Fixes issue #92.
-
- * lily/pango-font.cc (pango_item_string_stencil): use
- logical_rect. This prevents spaces after words from disappearing,
- issue #72.
-
- * VERSION: release 2.9.20
-
-2006-10-02 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-grob-properties.scm (all-user-grob-properties):
- mention stencil as user settable.
-
-2006-10-02 Joe Neeman <joeneeman@gmail.com>
-
- * Documentation/user/page.itely (Page formatting):
- document auto-first-page-number
-
- * lily/page-breaking.cc (find_chunks_and_breaks):
- * lily/paper-score.cc (calc_breaking): Follow changes to the
- Constrained_breaking interface
-
- * lily/constrained-breaking.cc (calc_subproblem): run the main loop
- here backwards, as an optimisation
- (initialize): new function; move most of the code in resize () here
- (combine_demerits): cache ragged_right_
- (Constrained_breaking): constructor now takes the Paper_score
-
-2006-10-02 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/lexer.ll, lily/parser.yy: Add EXPECT_NO_MORE_ARGS token, to
- avoid parser lookahead for 0-ary functions.
-
- * lily/translator.cc: Extract event classes from
- IMPLEMENT_TRANSLATOR_LISTENER for documentation generation.
-
-2006-10-02 Heikki Junes <hjunes@gmail.com>
-
- * po/fi.po: Fix spaces, commas etc. in Finnish translation using
- KBabel fix tool.
-
-2006-10-01 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * scm/layout-page-layout.scm (page-breaking-wrapper): new
- function. Call the page breaking function selected in the
- `page-breaking' \paper variable, then the post processing function
- chosen using the `page-post-process' \paper variable.
- (line-height): new function. Return the height of a system.
- (line-minimum-position-on-page): new function. Return the position
- of a system on page (using the previous line position), only
- considering between system padding.
- (stretchable-line?): new function. Says whether a line can be
- stretched (ie. is not a title nor a single staff system).
- (page-maximum-space-left): new function. Computes space left on a
- page, when all systems are separated by their padding.
-
- * lily/page-breaking.cc (breaking::make_pages): Move page post
- processing function call to page breaking wrapper (common to all
- page breakers).
-
- * lily/paper-book.cc (book::pages): call the page breaking
- wrapper, instead of the page breaker directly
-
- * ly/paper-defaults.ly: Add \paper variables for page breaking
- wrapper and page post processing function. Make
- `write-page-layout' value depend on the 'dump-tweaks option. Add a
- `system-maximum-stretch-procedure' variable for holding a function
- computing the maximum stretch a system allows.
-
- * scm/layout-page-dump.scm (write-page-breaks): computes the
- stretch to apply to systems on a page to minimize left
- space. Dump this stretch length.
-
- * ly/music-functions-init.ly (spacingTweaks): implement it. Read
- the system-stretch property of the tweak data to stretch the
- system.
- (includePageLayoutFile): Void function which includes the
- generated page-layout file if it exists and if the page layout
- dumping is not asked.
- (scoreTweak): if the score tweak named by the argument exists,
- return it.
-
-2006-10-01 Joe Neeman <joeneeman@gmail.com>
-
- * lily/page-spacing.cc (compress_lines, uncompress_solution):
- handle correctly the case where there are multiple \noPageBreaks
- in a row.
-
-2006-09-30 Laura Conrad <lconrad@laymusic.org>
-
- * abc2ly.py adds segno (S) and Coda (O) to articulations.
-
- * abc2ly.py fix so that entering " -- " will translate to a -- in
- the lilypond instead of a " - - "
-
-2006-09-30 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/align-interface.cc: fix typo
-
- * lily/dynamic-text-spanner.cc (print): Add a special case for
- trill spanner right sides.
-
- * scm/define-grobs.scm (all-grob-descriptions): set padding to 0.1
-
- * lily/align-interface.cc (get_extents_aligned_translates): add
- support for padding variable.
-
- * lily/break-align-interface.cc (self_align_callback): oops: use
- loop variable in guard.
-
- * input/regression/repeat-percent-grace.ly: new file.
-
- * lily/percent-repeat-engraver.cc (start_translation_timestep):
- remember first currentCommandColumn of a grace run. Fixes issue 70.
-
- * lily/percent-repeat-iterator.cc (class Percent_repeat_iterator):
- move class definition to CC file.
-
- * lily/multi-measure-rest.cc (percent): use robust_relative_extent()
-
- * lily/slash-repeat-engraver.cc (listen_percent): don't warn for
- measure-long repeats.
-
- * flower/include/international.hh: include stdarg.h
-
-2006-09-30 Joe Neeman <joeneeman@gmail.com>
-
- * lily/page-turn-page-breaking.cc (calc_demerits): now that we allow
- put_systems_on_pages to return an empty result, we need to assign
- demerits properly in that case.
- (put_systems_on_pages): Make the number of pages depend on the
- evenness of page_number. Add auto-first-page-number.
- (calc_subproblem): ensure that the page-number is even for the
- left-hand page. Warn if the first page-turn doesn't fit onto the
- first (right-hand) page.
-
- * lily/page-spacing.cc (solve): bug: demerits_ would always be inf
- (min_page_count): make this publicly accessible
- (min_page_count): fix a bug when there are forced page breaks that
- was introduced when I made this loop run backwards
- (space_systems_on_n_pages, space_systems_on_n_or_one_more_pages):
- replace space_systems_on_min_pages with these two. The logic in
- space_systems_on_min_pages was getting too convoluted and is better
- contained in page-turn-page-breaking.
-
- * lily/page-turn-engraver.cc (breakable_column): remove an always-true
- conditional
- (breakable_column): typo
-
- * lily/source-file.cc (get_line): fix off-by-one error
- and clean up some of the logic
-
-2006-09-29 Joe Neeman <joeneeman@gmail.com>
-
- * lily/page-breaking.cc (make_pages): honour the first-page-number
- property
-
-2006-09-27 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): bump version.
-
-2006-09-26 Pal Benko <benko.pal@gmail.com>
-
- * scm/parser-clef.scm: add petrucci-f3 and -f4 clefs
- (the latter is the same as petrucci-f which is kept for compatibility)
-
-2006-09-26 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/part-combine-iterator.cc: solo1-event -> solo-one-event
-
-2006-09-26 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/global-context.cc (run_iterator_on_me): break out of loop
- if moment doesn't increase.
-
- * scm/define-grob-properties.scm (all-user-grob-properties): add
- forced property.
-
- * lily/accidental.cc (after_line_breaking): read forced property.
-
- * lily/accidental-engraver.cc (process_acknowledged): set 'forced
- property.
-
- * input/regression/accidental-forced-tie.ly: new file.
-
-2006-09-25 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * ly/engraver-init.ly: set ignoreFiguredBassRest in Staff context.
-
- * lily/figured-bass-engraver.cc: only listen to rest events if
- ignoreFiguredBassRest is not set.
-
- * scm/define-context-properties.scm
- (all-user-translation-properties): add ignoreFiguredBassRest property
-
-2006-09-24 Joe Neeman <joeneeman@gmail.com>
-
- * lily/paper-book.cc (get_system_specs):
- (set_system_penalty): fix breakbefore.
- We used to set a penalty on the system after the break, now we
- set a permission on the system before the break
-
- * lily/grob-property.cc: add scm debugging hooks into
- property modification
-
- * lily/context-property.cc:
- * lily/engraver.cc:
- rename make_foo_from_properties to internal_make_foo and
- move it from context-property.cc to a member function of
- Engraver.
-
- * lily/include/lily-guile-macros.hh:
- overload ly_symbol2scm macro so that there is no more need
- to use internal_foo
-
- * lily/volta-repeat-iterator.cc:
- * lily/tweak-engraver.cc:
- * lily/tuplet-bracket.cc:
- * lily/span-bar-engraver.cc:
- * lily/script-engraver.cc:
- * lily/prob-scheme.cc:
- * lily/pointer-group-interface.cc:
- * lily/parser.yy:
- * lily/grob-scheme.cc:
- * lily/grob-property.cc:
- * lily/context.cc:
- * lily/context-property.cc:
- * lily/break-substitution.cc:
- * lily/break-align-engraver.cc:
- * lily/axis-group-interface.cc:
- * lily/align-interface.cc:
- remove calls to internal_FOO
-
- * lily/system-start-delimiter-engraver.cc:
- * lily/parenthesis-engraver.cc:
- * lily/accidental-engraver.cc:
- remove calls to make_foo_from_properties
-
-2006-09-23 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/programming-iterfaces.itely: fix
- def-music-function -> define-music... leftover.
-
-2006-09-23 Joe Neeman <joeneeman@gmail.com>
-
- * lily/page-spacing.cc (min_page_count): by running the loop
- backwards, we can calculate ragged_last properly.
-
-2006-09-22 Mats Bengtsson <mabe@drongo.s3.kth.se>
-
- * ly/titling-init.ly (scoreTitleMarkup): Rename (typo!?)
- printfirst-page-number -> print-first-page-number
-
- * python/convertrules.py: corresponding rule.
-
- * Documentation/user/page.itely (Page formatting): Document the
- default values of all page layout parameters.
-
-2006-09-22 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/lexer.ll: remove limitation on music function arity. New
- mode extratoken, which inserts extra EXPECT_* tokens after
- MUSIC_FUNCTION token. Junk all MUSIC_FUNCTION_* tokens.
-
- * lily/parser.yy: Change grammar for music function accordingly.
-
- * lily/include/lily-parser.hh: New method get_state, new member
- hidden_state. Works around a problem when parser fetches
- MUSIC_FUNCTION token but not the following EXPECT_* token.
-
- * lily/translator.cc, lily/context.cc:, lily/translator-group.cc:
- remove try_music
-
- * lily/*-engraver.cc, lily/*-performer.cc: Remove all remaining
- references to Music; use ASSIGN_EVENT_ONCE everywhere
-
- * lily/grob-info.cc: junk *music_cause
-
- * lily/music.cc: copy eventified articulations to stream event
-
- * lily/part-combine-iterator.cc: Cleanup using enums
-
- * lily/translator-group.cc: Junk OldMusicEvent, and associated
- methods
-
- * lily/include/engraver.hh: Junk music.hh include
-
- * lily/stream-event.cc: Changed constructors
-
-2006-09-21 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/tweaks.itely (Fitting music onto fewer
- pages): change settings to avoid warning messages.
-
-2006-09-21 Mats Bengtsson <mabe@drongo.s3.kth.se>
-
- * Documentation/user/tweaks.itely (Fitting music onto fewer
- pages): Add between-system-space setting.
-
-2006-09-21 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/accidental-placement.cc (calc_positioning_done): don't
- trigger Y-extent calculation too early. Use pure_height instead.
-
- * lily/scale.cc (LY_DEFINE): new file.
-
-2006-09-20 Joe Neeman <joeneeman@gmail.com>
-
- * lily/page-breaking.cc (find_chunks_and_breaks): ignore breaks
- that happen at the start of a score: having a zero-length
- chunk was messing up min_system_count calculations.
-
- * lily/source-file.cc (get_line): lower_bound, not
- binary_search. Fixes problem where point-and-click would
- always point to the first line.
-
-2006-09-20 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/accidental-placement.cc (calc_positioning_done): also put
- stems into accidental support.
-
- * lily/tie-engraver.cc (process_music): also set tieMelismaBusy if
- event_ detected.
-
- * scm/script.scm (default-script-alist): avoid-slur and
- slur-padding for portato script.
-
- * lily/stem-tremolo.cc (translated_stencil): new function.
- (height): use new function. Fixes tremolos on whole notes.
-
- * lily/slur-scoring.cc (get_best_curve): don't crash if no optimal
- slur found.
-
-2006-09-19 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scripts/abc2ly.py (try_parse_comment): idem.
-
- * scripts/lilypond-book.py (find_toplevel_snippets): use 'foo' in
- bar_string iso. string.find()
-
- * lily/*.cc: idem.
-
- * lily/slur.cc (get_curve): always use scm_is_pair() looping
- scheme lists.
-
-2006-09-18 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/basic-notation.itely: add bug
- warning about ties and octavation/clef.
-
-2006-09-18 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): release 2.9.18
-
-2006-08-29 Milan Zamazal <pdm@brailcom.org>
-
- * elisp/lilypond-mode.el (LilyPond-command-alist): Don't try to
- figure out midi file names right here.
-
-2006-09-17 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/framework-ps.scm (dump-stencil-as-EPS): naming pad-eps-boxes.
-
- * scm/backend-library.scm: option naming: gs-font-load*s*
-
- * scm/framework-eps.scm (dump-stencils-as-EPSes): rename option to
- include-eps-fonts
-
-2006-09-17 Joe Neeman <joeneeman@gmail.com>
-
- * scm/define-music-types.scm (music-descriptions): remove
- BreakEvent and fix {Page,Line}{Break,Turn}Event so
- Music::to_event doesn't complain.
-
- * lily/accidental-placement.cc (ape_compare):
- * lily/semi-tie.cc (compare):
- * lily/note-column.cc (shift_compare): replace by XXX_less
-
- * lily/tie-formatting-problem.cc (set_chord_outline):
- * lily/tie-column.cc (calc_positioning_done):
- * lily/system.cc (post_processing)
- (get_paper_system):
- * lily/stem.cc (note_head_positions)
- (calc_positioning_done):
- * lily/spanner.cc (do_break_processing)
- (find_broken_piece):
- * lily/span-bar.cc (print):
- * lily/semi-tie-column.cc (calc_positioning_done):
- * lily/rest-collision.cc (calc_positioning_done):
- * lily/program-option.cc (get_help_string):
- * lily/note-collision.cc (get_clash_groups):
- * lily/new-fingering-engraver.cc (position_scripts):
- * lily/keyword.cc (Keyword_table):
- * lily/hara-kiri-group-spanner.cc (request_suicide):
- * lily/grob-pq-engraver.cc (stop_translation_timestep):
- * lily/accidental-placement.cc (calc_positioning_done):
- (stagger_apes):
- * lily/beam.cc (get_beam_segments):
- * lily/grob-array.cc (remove_duplicates):
- use new vector_sort
-
- * input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily:
- ragged-last-bottom = ##f (test the new page breaker)
-
- * flower/include/std-vector.hh (vector_sort): use STL sort stuff
-
- * scm/define-context-properties.scm
- (all-internal-translation-properties): remove properties that
- were used to communicate page-turn stuff to the paper-column
- engraver.
-
- * lily/lily-guile.cc (robust_scm2string): new function
-
- * lily/paper-column-engraver.cc: Clean up page turn stuff
-
- * lily/page-turn-engraver.cc: Re-write the page turn logic here
- instead of cluttering up paper-column-engraver.cc
-
-2006-09-17 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * scm/layout-page-dump.scm (scm): export utility function names,
- to allow user writing cutsom dumping functions.
-
- * scm/layout-page-layout.scm: export utility function names to
- enable custom page breaking function writing. Tabify.
- (line-next-space): use ?-suffix only for predicates
- (page-maximum-space-to-fill): new function. Return the space
- between first and bottom system of a page, to give to
- space-systems.
- (space-systems): use a space-to-fill argument (for instance as
- computed by page-maximum-space-to-fill) instead of computing
- internaly this space with the page height. That way, the caller
- can adjust the space to use.
- (make-page-from-systems, walk-paths): compute space to fill before
- calling space-systems.
-
-2006-09-17 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/script.scm (default-script-alist): set paddings for every
- type here, increase for portato mark.
-
- * scm/lily.scm (define-scheme-options): typo: add s, so it is
- -dinclude-eps-fonts
-
-2006-09-16 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-grobs.scm (all-grob-descriptions): oops, typo:
- use spanner::set-spacing-rods
-
- * lily/note-column.cc: reformat.
-
- * lily/rest-collision.cc (calc_positioning_done): fix whole/half
- step positioning for note/rest combinations.
-
- * input/regression/rest-note-collision.ly: new file.
-
- * scm/define-grobs.scm (all-grob-descriptions): add
- springs-and-rods
-
- * flower/include/std-vector.hh: switch off again.
-
- * VERSION (PATCH_LEVEL): bump to 2.9.18
-
- * flower/include/std-string.hh: idem.
-
- * flower/include/std-vector.hh (_GLIBCXX_DEBUG): set if NDEBUG not set.
-
-2006-09-15 Mats Bengtsson <mabe@drongo.s3.kth.se>
-
- * ly/engraver-init.ly: Make FiguredBass accepted in GrandStaff and
- PianoStaff.
-
-2006-09-08 Joe Neeman <joeneeman@gmail.com>
-
- * Documentation/user/page.itely: update page breaking documentation
-
-2006-09-07 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/note-collision.cc (calc_positioning_done): only access
- first head if available.
-
- * lily/tuplet-engraver.cc: add tupletFullLengthNote to description.
-
- * scm/framework-ps.scm (output-preview-framework): use new name.
-
- * lily/program-option.cc (internal_set_option): use new names.
-
- * Documentation/user/SConscript (lilypond_book_flags): update -d
- variable names.
-
- * Documentation/user/lilypond-book.itely (Inserting LilyPond
- output into other programs): new variable names.
-
- * scm/lily.scm (define-scheme-options): uniformize var names.
-
- * lily/tuplet-engraver.cc (listen_tuplet_span): verify that
- tuplets_ is non-empty before popping.
-
-2006-09-07 Joe Neeman <joeneeman@gmail.com>
-
- * lily/spanner.cc (find_broken_piece):
- * lily/spacing-spanner.cc (get_columns):
- * lily/source-file.cc (get_line):
- * lily/simple-spacer.cc (get_column_description):
- * lily/keyword.cc (lookup):
- use the new binary search.
-
- * flower/include/std-vector.hh: replace binary_search with
- a more STL-like version
-
-2006-09-04 Michael Welsh Duggan <md5i@cs.cmu.edu>
-
- * lily/tie-performer.cc: remove unused last_event_ property.
- (class Tie_performer): add now_tied_heads_ property for
- partially-tied heads.
- (acknowledge_audio_element): when adding an Audio_note, put the
- note in now_tied_heads_ if the audio note is partially tied.
- (stop_translation_timestep): always include entries in
- now_tied_heads_ in heads_to_tie_.
-
- * lily/drum-note-performer.cc (process_music): look for tie-events
- in the articulations; pass to Audio_note constructor.
-
- * lily/note-performer.cc (process_music): look for tie-events in
- the articulations; pass to Audio_note constructor.
-
- * lily/audio-item.cc (Audio_note): Initialize tie_event_ in
- constructor.
-
- * lily/include/audio-item.hh (class Audio_note): add tie_event_.
- include initializer in constructor.
-
-2006-09-02 Joe Neeman <joeneeman@gmail.com>
-
- * lily/simple-spacer.cc (get_line_forces): Ignore loose columns
- unless they are breakable. This fixes discrepancies between the forces
- calculated here and the forces calculated in get_line_configuration.
-
- * lily/grob.cc (pure_relative_y_coordinate): fix some
- mis-estimation that was happening with piano staves.
-
- * lily/constrained-breaking.cc (resize): don't choke if we get a
- measure that won't fit on a line.
- (combine_demerits): don't consider uniformity when ragged
-
- * lily/page-spacing.cc (solve): why the f* were there two of these?
- (calc_subproblem): properly handle the case where a system is taller
- than the page.
-
- * lily/system.cc (get_paper_system): ensure that all the permissions
- and penalties are passed to the paper systems.
-
- * lily/page-breaking.cc (create_system_list): support system-count.
-
- * scm/define-grobs.scm (pure-print-callbacks): add
- ly:script-interface::print
-
- * lily/page-spacing.cc (min_page_count): fix calculation of min
- pages if we are ragged and there are non-zero springs.
-
- * scm/layout-page-layout.scm: if the pure-height estimates are under
- the real height, allow space-systems to ignore padding if it is
- needed in order to fit the systems on one page
-
- * lily/optimal-page-breaking.cc (try_page_spacing): fix reading
- ragged properties
- (solve): fix performance problem. Make sure we always get at least
- one solution
-
- * lily/page-breaking.cc (make_pages): include write-page-breaks
- and page-stencil
-
- * lily/paper-score.cc (calc_breaking): remove Gourlay breaker
-
- * scm/define-grobs.scm: add the new slur-callback
- fix pure-relevant to not exclude grobs whose extent is already
- calculated
-
- * ly/paper-defaults.ly: make ly:optimal-breaking the new default
- page breaker
-
- * lily/slur.cc (pure_height): new callback to estimate the height
- of a slur
-
-2006-09-02 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/invoking.itely: small update on
- MacOS X notes; thanks Trevor!
-
-2006-09-01 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (MY_PATCH_LEVEL): release 2.9.17
-
- * lily/lexer.ll: accept EOF in all states.
-
- * lily/tempo-performer.cc (Tempo_performer): initialize last_tempo_.
-
- * lily/source-file.cc (Source_file): always 0-terminate character
- array, to prevent Flex from barfing.
-
- * lily/global-context.cc (get_output): robustness: don't crash if
- no Score context found.
-
- * lily/include/book.hh (class Book): idem.
-
- * lily/include/context-def.hh (struct Context_def): idem.
-
- * lily/include/score.hh (class Score): don't derive from Input.
-
- * lily/book.cc (Book): add a copy ctor.
-
- * buildscripts/output-distance.py (FileLink.calc_distance): count
- orphans in distance too.
-
- * python/midi.c (midi_parse_track): robustness: don't read past
- end of string.
-
- * ly/performer-init.ly: add Control_track_performer, move
- Tempo_performer and Time_signature_performer to Score.
-
- * lily/score-performer.cc (acknowledge_audio_elements): override
- from base class: add to audio-columns
-
- * lily/control-track-performer.cc (add_text): new file: generate
- the control track.
-
- * lily/performance.cc: move output_header_track to
- Control_track_performer ()
-
- * lily/midi-walker.cc (Midi_walker): get channel in constructor.
-
- * lily/include/midi-item.hh (class Midi_channel_item): insert
- class into hierarchy, for items that can have a channel setting. Dehungarify.
-
- * lily/include/performer.hh (class Performer): remove
- play_element(); move functionality into announce/acknowledge.
-
- * lily/audio-staff.cc (output): remove channel_ from Midi_track.
-
- * lily/tie-engraver.cc (stop_translation_timestep): only wipe
- heads_to_tie_ if there are new heads to tie. Fixes polyphony in ties.
-
-2006-08-28 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/tie-engraver.cc (stop_translation_timestep): robustness for
- ambituses.
-
- * lily/all-font-metrics.cc: remove TFM support.
-
- * lily/include/tfm.hh: remove TFM support, TFM reader.
-
- * lily/include/binary-source-file.hh: remove Binary_source_file.
-
-2006-08-27 Graham Percival <gpermus@gmail.com>
-
- * Documentation/topdocs/NEWS.itely: add @c marker for
- stuff I've processed.
-
- * Documentation/user/ various: info from NEWS.
-
-2006-08-27 Joe Neeman <joeneeman@gmail.com>
-
- * lily/paper-column-engraver.cc (finalize): Oops, this change
- should have gone in on 2006-08-23
-
-2006-08-26 Mats Bengtsson <mabe@s3.kth.se>
-
- * scripts/lilypond-book.py (LATEX_INSPECTION_DOCUMENT): Use double
- quotes to quote arguments. Fixes Windows problem.
-
- * python/lilylib.py (progress): idem
-
-2006-08-26 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scripts/musicxml2ly.py: fix for importing
- minor key signatures from MusicXML. (Phillip Kirlin)
-
-2006-08-24 Phillip Kirlin <pkirlin@acm.org>
-
- * python/musicxml.py:
- (Attributes.get_key_signature): now correctly retrieves mode from
- MusicXML.
-
-2006-08-25 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/parser.yy (output_def_body): take ownership of identifier
- back to C++.
-
- * Documentation/user/advanced-notation.itely (Metronome marks):
- update use of \tempo in \midi.
-
- * VERSION: release 2.9.16
-
-2006-08-24 Erik Sandberg <mandolaerik@gmail.com>
-
- * input/mutopia/*: upgrade to new midi tempo syntax (repairs make
- web partially)
-
-2006-08-24 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * input/regression/tie-chord-partial.ly: clarify example.
-
- * scm/define-music-properties.scm (all-music-properties): remove
- untied.
-
- * ly/music-functions-init.ly: remove \untied.
-
- * lily/tie-engraver.cc (struct Head_event_tuple): store both
- stream events and music events.
- (stop_translation_timestep): search acknowledged heads for
- tie-event.
-
- * input/regression/tie-chord-partial.ly: new file.
-
- * scm/define-markup-commands.scm (char): use ly:wide-char->utf-8
- for \char markup command.
-
- * scm/define-event-classes.scm (unlistened-music-event-classes): idem.
-
- * scm/define-music-types.scm (music-descriptions): consistency:
- Use solo-{one,two}-event iso. solo-[12]-event.
-
- * lily/part-combine-engraver.cc (process_music):
- Use solo-{one,two}-event iso. solo-[12]-event.
-
- * ly/declarations-init.ly (partCombineListener): add Timing as
- alias
-
- * flower/std-string.cc (string_copy): use copy ()
-
- * lily/source-file.cc (Source_file): use copy(). Remove contents_str0()
-
-2006-08-24 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/changing-defaults.itely, global.itely,
- lilypond-book.itely, page.itely: minor changes from mailist.
-
-2006-08-23 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * buildscripts/mutopia-index.py (allfiles): filter lily-XXX and
- snippet-map
-
- * scm/define-context-properties.scm
- (translator-property-description): robustness: detect type errors
- in property definitions.
-
- * lily/parser.yy (score_body): protect SCORE_IDENTIFIER result
- after getting it from SCM.
-
- * lily/smobs.cc (protect_smob): switch off fancy smob protection
- for now.
-
- * lily/include/performer.hh (class Performer): strip get_tempo()
- method.
-
- * lily/midi-def.cc: strip file.
-
- * lily/lexer.ll (Lily_lexer): don't protect hash key separately.
-
- * lily/include/context-def.hh (struct Context_def): use
- VIRTUAL_COPY_CONSTRUCTOR().
-
- * lily/source-file.cc: smobification.
-
- * lily/include/source-file.hh (class Source_file): smobify
- Source_file. Trim redundant members.
-
- * lily/parser.yy (Lily_lexer::try_special_identifiers): unprotect
- clones after creation. This plugs a huge memory leak.
-
- * python/convertrules.py (FatalConversionError.sub_tempo):
- complete rule for \midi{ \tempo }
-
- * input/mutopia/J.S.Bach/wtk1-fugue2.ly (bassdux): idem.
-
- * input/mutopia/F.Schubert/morgenlied.ly (pianoLH): update tempo.
-
-2006-08-23 Joe Neeman <joeneeman@gmail.com>
-
- * input/regression/optimal-page-breaking-hstretch.ly: test for
- ragged-last-bottom also
-
- * lily/paper-column-engraver.cc (finalize): make the end of a score
- breakable by default. This is to balance out a change in behaviour
- of the page-turn-breaker which no longer makes the end of a score
- breakable.
-
- * lily/paper-book.cc (pages): set the systems_ once the pages are
- broken
-
- * lily/page-turn-page-breaking.cc (calc_subproblem): use the new
- Page_breaking interface.
-
- * lily/page-breaking.cc (class Page_breaking): make the interface
- more consistent and provide abstractions for dealing with
- Line_divisions.
-
- * lily/optimal-page-breaking.cc (solve): use a more straightforward
- algorithm. Use the new interface to Page_breaking.
-
- * lily/page-spacing.cc: better support for ragged-bottom and
- ragged-last-bottom
-
-2006-08-22 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * python/convertrules.py (conv): warning on \tempo{}
-
- * ly/performer-init.ly: set tempoWholesPerMinute.
-
- * ly/midi-init.ly: remove \midi
-
- * lily/tempo-performer.cc: look at tempoWholesPerMinute to set
- MIDI tempo.
-
- * lily/metronome-engraver.cc (process_music): use tempoUnitCount
- tempoUnitDuration for determining what to print.
-
- * lily/lyric-extender.cc: typo.
-
- * lily/parser.yy (output_def_body): disallow \tempo in \midi{}
-
- * lily/duration-scheme.cc (LY_DEFINE): ly:duration-length: new
- function.
-
- * scm/lily.scm (define-scheme-options): alphabetize, add eps-pad-boxes.
-
- * scm/framework-ps.scm (dump-stencil-as-EPS): only pad boxes if
- eps-pad-boxes is set.
-
- * scripts/lilypond-book.py (main): use -deps-pad-boxes.
-
- * THANKS: update sponsors.
-
- * ly/english.ly: quarter tone naming (thanks, Trevor Baca)
-
- * Documentation/topdocs/NEWS.tely (Top): doc new feature.
-
- * input/regression/tie-chord-untied.ly: new file.
-
- * lily/tie-engraver.cc (acknowledge_note_head): check 'untied property.
-
- * scm/define-music-properties.scm (all-music-properties): add
- 'untied property.
-
- * buildscripts/mutopia-index.py (allfiles): look for .ly rather
- than .ly.txt.
- (headertext_nopics): sanitize no-examples text.
-
- * scm/page.scm (make-page-stencil): don't rely on extents of
- page-stencil. This fixes spurious space around .EPS files produced
- with the EPS backend.
-
-2006-08-21 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/stencil-scheme.cc (LY_DEFINE): make extent arguments optional.
-
- * lily/hara-kiri-engraver.cc (process_music): remember
- keepAliveInterfaces after processing \set
-
- * lily/lyric-extender.cc (print): support left/right-padding for
- extenders.
-
- * scm/documentation-generate.scm (string-append): revert lilypond/
- path, doc why.
-
-2006-08-20 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/lilypond.tely: clarification to
- license presentation (not to actual license).
-
- * Documentation/user/basic-notation.itely,
- instrument-notation.itely: minor changes.
-
- * input/ {regression, test}/+.ly: clarification to
- text (you can click on examples). Thanks, Mats!
-
- * input/manual/bar-lines.ly: adds ||: repeats.
-
-2006-08-20 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * make/ly-vars.make (OMF_FILES): strip ps.gz from OMF_FILES
-
- * scm/documentation-lib.scm (texi-file-head): category LilyPond.
-
- * Documentation/user/lilypond.tely: strip lilypond/ from info
- links, rename to category LilyPond
-
- * lily/pango-font.cc (description_string): new function.
-
- * VERSION: release 2.9.15
-
- * lily/spacing-engraver.cc (stop_translation_timestep): use
- Dscho's fix for spacing spanner.
-
- * scm/define-music-types.scm (music-descriptions): use
- apply-output-event for ApplyOutputEvent
-
- * lily/output-property-engraver.cc (listen_apply_output): rename
- from listen_layout_instruction.
-
- * lily/piano-pedal-engraver.cc (struct Pedal_type_info): new
- function protect()
-
-2006-08-19 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/lily.scm (lilypond-all): option read-file-list: substitute
- commandline args with contains, split by \n.
-
- * scripts/lilypond-book.py (Lilypond_file_snippet.my_system):
- write snippet-names file, call with -dread-file-list. Fixes
- command limitations on 64-bit systems.
-
- * input/regression/stencil-color-rotation.ly: new file.
-
- * lily/include/translator.hh (struct Acknowledge_information):
- revert: don't use Protected_scm in global objects, as GUILE can't
- handle gc_unprotect from automated destructors on MacOS X.
-
- * lily/grob.cc (get_print_stencil): use retval.expr() as base for
- color, not the original stencil. Fixes combinations of
- color/transparency/rotation.
-
- * scripts/lilypond-book.py (main): add --formats=eps for
- texinfo/latex.
-
- * lily/spacing-engraver.cc (stop_translation_timestep): don't
- crash if spacing_ is nonexistent.
-
-2006-08-14 Mats Bengtsson <mabe@s3.kth.se>
-
- * scripts/lilypond-book.py (output): Remove obsolete(!?)
- \catcode`\@=12 in the LaTeX output.
-
-2006-08-11 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-music-types.scm (music-descriptions):
- use sustain-event iso. sustain-pedal-event.
-
-2006-08-11 Joe Neeman <joeneeman@gmail.com>
-
- * scripts/convert-ly.py: honour the -n command-line switch
-
-2006-08-10 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/output-lib.scm (bar-line::calc-glyph-name): add dashed liine
- break specification.
-
-2006-08-10 Joe Neeman <joeneeman@gmail.com>
-
- * Documentation/user: convert-ly the user manual
-
-2006-08-09 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * stepmake/aclocal.m4: version check patch (thanks MWD)
-
- * ly/music-functions-init.ly: robustness. Don't crash if
- currentBarNumber is not a number.
-
- * VERSION (PATCH_LEVEL): bump.
-
-2006-08-08 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * stepmake/aclocal.m4: better version check; handle fooX.Y
- binaries too.
-
- * ly/performer-init.ly: instrument name fixup.
-
- * input/manual/chord-names-jazz.ly (banterProperties):
- instrumentName update
-
- * scm/define-event-classes.scm (lambda): use ly:is-listened-event-class
-
- * lily/ly-module.cc (ly_module_symbols): use ly_hash_table_keys
-
- * lily/translator.cc (LY_DEFINE): ly:is-listened-event-class: new
- function. Use hash tables to check membership.
-
- * lily/general-scheme.cc (LY_DEFINE): new function.
-
- * lily/piano-pedal-engraver.cc (struct Pedal_type_info): idem
-
- * lily/include/translator.hh (struct Acknowledge_information): add
- Protected_scm
-
- * ly/music-functions-init.ly: change name to BreathingEvent
-
- * input/regression/*.ly: apply it.
-
- * python/convertrules.py (conv): better instrumentName conversion
- rule.
-
- * scm/define-music-types.scm (music-descriptions): add
- line-break-event to LineBreakEvent music
-
- * lily/music.cc (to_event): don't crash if music type not set.
-
- * lily/spacing-loose-columns.cc (set_loose_columns): don't barf if
- spacing not set.
-
- * lily/spacing-engraver.cc (stop_translation_timestep): set
- spacing for proportional notation too.
-
- * scm/translation-functions.scm (format-bass-figure): inspect
- stream-event.
-
- * scripts/lilypond-book.py (bindir): add bindir to $PATH.
-
-2006-08-08 Joe Neeman <joeneeman@gmail.com>
-
- * lily/include/constrained-breaking.hh: add Line_details (Prob*)
-
- * scm/page.scm (make-page): make it friendlier to call (esp. from C++)
-
- * scm/layout-page-layout.scm (make-page-from-systems): new function
- (optimal-page-breaks): use the new page-breaking calling convention
-
- * scm/define-context-properties.scm (all-user-translation-properties):
- add revokePageTurns
-
- * lily/paper-column-engraver.cc (stop_translation_timestep): add
- revokePageTurns functionality. If there is a special barline within
- the breakable region, break there instead of at the end of the region.
-
- * lily/paper-book.cc (pages): use the new page-breaking calling
- convention
-
-2006-08-07 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/lexer.ll, lily/source-file.cc: Add \sourcefileline command
-
- * scripts/lilypond-book.py: insert \sourcefileline command in
- output, so lilypond error messages refer to the spot in the
- original .lytex / .itely sourcefile.
-
-2006-08-04 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/spacing-loose-columns.cc (set_loose_columns): oops: use
- space to next column for distance to fixed col.
-
- * VERSION (PACKAGE_NAME): release 2.9.14
-
- * lily/pitched-trill-engraver.cc (make_trill): do set_parent also
- if no accidental.
-
- * lily/accidental-engraver.cc (process_acknowledged): don't create
- accidental for trill span event. This fixes spurious accidentals
- on trills.
-
-2006-08-04 Mats Bengtsson <mabe@s3.kth.se>
-
- * scm/define-grob-properties.scm (all-user-grob-properties):
- Clarify documentation of side-axis and direction. Thanks to Paul
- for the inspiration.
-
- * lily/bar-line.cc: Add documentation for "||:" also in the
- interface documentation.
-
-2006-08-04 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/spacing-loose-columns.cc (set_loose_columns): bugfix.
-
- * lily/paper-column.cc (set_system): new function.
-
- * lily/spacing-engraver.cc (stop_translation_timestep): store
- SpacingSpanner refs in Paper_column.
-
- * lily/spacing-loose-columns.cc (set_loose_columns): rewrite
- compute loose clique spacing using GraceSpacing/SpacingSpanner.
-
-2006-08-03 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/beam-engraver.cc (listen_beam): add method for
- Grace_beam_engraver too.
-
-2006-08-03 Mats Bengtsson <mabe@s3.kth.se>
-
- * python/convertrules.py: Fix indentation bug that broke
- conversion of files older than 1.3.117.
- Fix escape error in the description for 2.9.6.
-
-2006-08-02 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/*-engraver.cc: convert all try_music functions to listen_*
- functions.
-
- * lily/piano-pedal-engraver.cc: some additional cleanups: use
- enums to represent pedal types, and calculate more data statically.
-
- * scm/part-combiner.scm (recording-group-emulate): create a
- softcoded substitute for recording-group-engraver.cc.
-
- * lily/music.cc: make a common transpose function for events and
- music
-
- * ly/declarations-init.ly: change melisma/melismaEnd. Eliminates
- ManualMelismaEvent, and obsoletes Melisma_translator.
-
-2006-08-02 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * input/test/instrument-name-align.ly: update version.
-
-2006-08-02 Mats Bengtsson <mabe@s3.kth.se>
-
- * Documentation/user/lilypond-book.itely (Invoking lilypond-book):
- Doc the --pdf flag to lilypond-book.
-
-2006-07-31 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * Documentation/topdocs/NEWS.tely (Top): add description.
-
- * input/regression/tuplet-full-length-note.ly: add file.
-
- * lily/instrument-name-engraver.cc (acknowledge_axis_group):
- always store axis group.
-
-2006-07-27 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * input/regression/instrument-switch.ly: new file.
-
- * lily/instrument-switch-engraver.cc (process_music): new file.
-
- * ly/engraver-init.ly: add Instrument_switch_engraver
-
- * ly/music-functions-init.ly: \instrumentSwitch
-
- * scm/define-context-properties.scm
- (all-user-translation-properties): add instrumentCueName
-
- * scm/define-grobs.scm (all-grob-descriptions): add InstrumentSwitch
-
-2006-07-26 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * ly/music-functions-init.ly: music function \transposition.
-
- * lily/parser.yy (command_element): softcode \transposition.
-
- * lily/fall-engraver.cc (process_music): delta-pitch -> delta-step.
- (process_music): oops.
-
- * lily/instrument-name-engraver.cc (start_spanner): new
- function. Create spanner when property changes.
- (stop_spanner): new function.
-
- * python/convertrules.py (conv): add rule.
-
- * lily/instrument-name-engraver.cc: shortVocalName iso. vocNam,
- shortInstrumentName iso. instr.
-
- * scm/output-ps.scm (dashed-line): add phase argument to
- dashed-line.
-
- * lily/bar-line.cc (dashed_bar_line): new function.
- (compound_barline): support \bar "dashed".
-
- * lily/lily-parser-scheme.cc (LY_DEFINE): only write
- --output=DIR to DIR/BASE if it is a dir.
-
- * flower/file-name.cc (file_part): new function
- (dir_part): new function
-
- * lily/lily-parser-scheme.cc (LY_DEFINE):
-
- * DEDICATION: update
-
-2006-07-25 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/instrument-name-engraver.cc: formatting.
-
- * python/convertrules.py (conv): bugfix for \epsfile.
-
-2006-07-25 Joe Neeman <joeneeman@gmail.com>
-
- * lily/grob.cc:
-
- * lily/gourlay-breaking.cc: Oops, these should have been included
- in my last commit
-
-2006-07-24 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scripts/*.py (program_name): cleanup relocation snippets.
-
- * scripts/convert-ly.py (datadir): remove LILYPONDPREFIX support.
-
-2006-07-24 Joe Neeman <joeneeman@gmail.com>
-
- * scm/define-grobs.scm (all-grob-descriptions): make NonMusicalPaperColumn
- page-breakable by default
-
- * scm/layout-page-layout.scm (space-systems): fix bug where the force isn't
- correctly calculated for a single-system page
-
- * scm/lily-library.scm (interval-sane?): also check that the first number is no
- bigger than the second number
-
- * lily/simple-spacer.cc (solve): allow compression even when ragged (but we
- acknowledge that we aren't satisfying constraints)
-
- * lily/hara-kiri-group-spanner.cc (request_suicide): give equal treatment to
- non-Items
-
- * lily/grob.cc (pure_height): add minimum-Y-extent
-
- * lily/gourlay-breaking.cc (solve): don't ignore a compression force, even if we're
- ragged
-
- * lily/constrained-breaking.cc: convert code to use new Matrix class
- (get_best_solution): new function
-
- * scm/page.scm (make-page-stencil): don't crash if we annotate-layout when there
- is a page with no systems
-
-2006-07-23 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): release 2.9.13
-
- * scm/define-grobs.scm (all-grob-descriptions): remove stray
- assignment.
-
-2006-07-21 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * Documentation/topdocs/NEWS.tely (Top): doc new features.
-
- * scm/output-lib.scm (grace-spacing::calc-shortest-duration): new
- function.
-
- * scm/define-grob-properties.scm (all-user-grob-properties):
- remove grace-space-factor.
-
- * scm/define-grob-interfaces.scm (grace-spacing-interface): add
- grace-spacing-interface
- (spacing-options-interface): add.
-
- * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): add Grace_spacing_engraver
-
- * lily/spacing-options.cc (get_duration_space): move function from spacing-basic.cc
-
- * lily/spacing-basic.cc (note_spacing): do init_from_grob on
- GraceSpacing object.
-
- * lily/note-spacing.cc: fix prop list formatting
-
- * lily/beaming-pattern.cc (de_grace): new function. Sensible
- beaming for grace notes too.
-
- * input/regression/spacing-grace.ly: update.
-
- * lily/grace-spacing-engraver.cc: new file.
-
- * lily/spacing-spanner.cc: add strict-grace-spacing.
-
-2006-07-20 Graham Percival <gpermus@gmail.com>
-
- * lily/parser.yy: compile fix.
-
-2006-07-20 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-grobs.scm (all-grob-descriptions): typo.
-
- * scm/framework-eps.scm (dump-stencils-as-EPSes): just strip
- .eps extension from includegraphics.
-
- * scripts/lilypond-book.py (main): add support for --pdf.
-
- * lily/spacing-spanner.cc (calc_common_shortest_duration): use
- callback to compute common shortest duration.
- (set_springs): typo.
-
- * scm/define-grob-properties.scm (all-user-grob-properties): add
- strict-grace-spacing.
-
- * lily/spacing-determine-loose-columns.cc (is_loose_column):
- support float_grace_columns_.
-
- * lily/spacing-options.cc (init_from_grob): new file.
-
- * Documentation/topdocs/NEWS.tely (Top): doc tupletFullLengthNote.
-
- * input/regression/spacing-loose-grace.ly: new file.
-
- * Documentation/topdocs/NEWS.tely (Top): document new feature.
-
- * lily/tuplet-engraver.cc (struct Tuplet_description): read
- tupletFullLengthNote too. Choose right bound depending on value.
-
- * input/regression/tuplet-full-length-note.ly: new file.
-
-2006-07-19 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/*-performer.cc: Converted try_music to listen_*
-
- * lily/grob-info.cc, lily/engraver.cc: represent the cause of grob
- as a stream-event internally. Introduce event_cause (), deprecate
- music_cause ().
-
- * scm/define-music-types.scm: Removed BusyPlayingEvent
-
-2006-07-19 Mats Bengtsson <mabe@s3.kth.se>
-
- * Documentation/user/advanced-notation.itely (Font selection):
- Document how to get a list of available fonts using 'lilypond
- -dshow-available-fonts blabla'.
-
-2006-07-19 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * GNUmakefile.in: filter lily-XXX.pdf files.
-
- * scm/define-grob-interfaces.scm (bend-after-interface): add thickness.
-
- * scm/define-grob-properties.scm (all-internal-grob-properties):
- remove delta-pitch. Use delta-position everywhere.
-
- * scm/output-lib.scm (fall::print): use new order.
-
- * scm/output-ps.scm (path): reorder arguments.
-
- * scm/output-svg.scm (path): support for path primitive.
-
- * input/regression/bend-after.ly: new file.
-
- * Documentation/user/GNUmakefile ($(outdir)/%.pdf): foolproof
- recipe for eps -> pdf conversion.
-
-2006-07-19 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/parser.yy, lily/lexer.ll: added some simplifications by
- Angelo Contardi.
-
-2006-07-19 Graham Percival <gpermus@gmail.com>
-
- * input/manual/screech-boink.ly: moved to here.
-
- * input/screech-boink.ly: deleted.
-
- * scm/define-grob-properties.scm: clarify doc string.
-
-2006-07-19 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * Documentation/topdocs/NEWS.tely (Top): doc new feature.
-
- * scm/output-ps.scm (path): define path.
-
- * scm/define-stencil-commands.scm
- (ly:register-stencil-expression): add path.
-
- * scm/define-music-properties.scm (all-music-properties): add delta-pitch.
-
- * ly/engraver-init.ly: add Fall_engraver
-
- * lily/parser.yy (music_function_event): allow musicfunction
- without music arg as music_function_event.
-
- * lily/grob-scheme.cc (LY_DEFINE):
- ly:grob-robust-relative-extent. New function.
-
- * scm/define-grobs.scm (all-grob-descriptions): add BendAfter
-
- * scm/define-music-types.scm (music-descriptions): add BendAfterEvent.
-
- * scm/output-lib.scm (fall::print): new function
-
- * lily/fall-engraver.cc (stop_fall): new file.
-
- * ly/music-functions-init.ly: alphabetise.
-
- * Documentation/user/GNUmakefile (OUT_PNG_IMAGES): pdf iso. eps as
- base.
-
-2006-07-17 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PATCH_LEVEL): bump version. Release 2.9.12
-
- * Documentation/user/lilypond-book.itely (Invoking lilypond-book):
- doc pdftex usage.
-
- * lily/translator-group.cc (connect_to_context): non const error message.
-
- * Documentation/user/GNUmakefile ($(outdir)/%.pdf): update to use PDF
-
- * scm/paper.scm (internal-set-paper-size): define landscape to #f
- if unset.
-
- * scm/framework-ps.scm (convert-to-pdf): swap h and w in case of landscape.
-
- * stepmake/stepmake/texinfo-rules.make: strip DVI support.
-
- * scm/framework-eps.scm (dump-stencils-as-EPSes): generate
- systems.pdftex too.
-
- * scm/backend-library.scm (postscript->pdf): use -dEPSCrop for PDF.
-
- * make/lilypond-vars.make (TEXINPUTS): add pdf output format.
-
- * Documentation/topdocs/NEWS.tely (Top): add pdftex note.
-
- * scm/output-ps.scm (resetrotation): use gsave/grestore for rotation.
-
- * lily/main.cc (parse_argv): don't overwrite previous --formats string.
-
- * scm/backend-library.scm (postscript->pdf): strip .eps too.
-
-2006-07-14 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * scm/layout-page-layout.scm: Define module, tidy code, use more
- functions iso. a single big one.
-
- * scm/layout-page-dump.scm: move page dump functions used in two
- pass spacing to this file. Define module.
-
- * scm/lily.scm (ly:load): don't load layout-page-layout.scm
- (separate module)
-
- * ly/paper-defaults.ly: use module layout-page-layout.
-
-2006-07-14 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/music.cc: Revised MusicEvent event class. It now contains
- event data directly instead of encapsulating it in music. The
- previously used class is renamed to OldMusicEvent.
-
- * lily/stream-event.cc: Stream events are now probs.
-
- * lily/translator-group.cc, lily/translator.cc: Translators can
- now listen directly to stream events, by using macros
- [DECLARE,IMPLEMENT]_TRANSLATOR_LISTENER.
-
- * lily/arpeggio-engraver.cc: Converted to use new event system
-
- * THANKS: Corrected spelling mistake.
-
-2006-07-12 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/SConscript, make/lilypond-vars.make,
- input/GNUmakefile: doc build looks in input/manual instead
- of input/test/
-
- * input/manual/ GNUmakefile, SConscript: build files for
- input/manual/
-
- * input/test/ various: some files moved to input/manual/
-
- * Documentation/user/basic-notation.itely: small updates;
- thanks Kieren and Charles!
-
-2006-07-12 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): release 2.9.11
-
- * Documentation/topdocs/NEWS.tely (Top): update prop value
-
- * Documentation/user/basic-notation.itely (Tuplets): new property
- value.
-
-2006-07-11 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * python/convertrules.py (conv): tweaks.
-
- * VERSION (PATCH_LEVEL): bump version.
-
- * python/convertrules.py (conv): add rule for
- tupletNumberFormatFunction.
-
- * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): remove
- tupletNumberFormatFunction.
-
- * scm/define-grobs.scm (all-grob-descriptions): calc TupletNumber
- text through 'text callback.
-
- * lily/time-scaled-music-iterator.cc (construct_children): copy
- tweaks generated events.
-
- * scm/define-context-properties.scm
- (all-user-translation-properties): remove tupletNumberFormatFunction
-
- * lily/tuplet-engraver.cc (process_music): don't read
- tupletNumberFormatFunction
-
- * scm/output-lib.scm (tuplet-number::calc-fraction-text): new
- function.
-
-2006-07-11 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/global-context-scheme.cc: Separated ly:run-translator into
- smaller pieces.
-
- * lily/score-engraver.cc, lily/score-performer.cc,
- scm/define-context-properties.scm: Make paper/midi output
- accessable as a context property.
-
- * lily/score-translator.cc, lily/score-context.cc: Removed.
-
-2006-07-07 Guido Amoruso <guidonte@katamail.com>
-
- * scm/ps-to-png.scm (Module):
- * scm/framework-tex.scm (Module):
- * scm/framework-ps.scm (Module):
- * scm/backend-library.scm (Module):
- * scm/framework-ps.scm: invoke gs with "-dDEVICEWIDTHPOINTS" and
- "dDEVICEHEIGHTPOINTS".
-
-2006-07-04 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/ various: general improvements to
- "working with lilypond files" section.
-
-2006-07-03 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/sequential-iterator.cc: Change the default get_music_list
- to read elements-callback music property
-
- * scm/define-music-types.scm, scm/music-functions.scm: Cleaner
- processing of multimeasure rests. Softcoded
- sequential-music-iterator.
-
- * lily/sequential-music-iterator.cc: Removed.
-
-2006-06-28 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/basic-notation.itely: clarify \repeatTie.
-
-2006-06-27 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/parser.yy: Wrap non-post-events in EventChords before
- assigning them to identifiers.
-
-2006-06-27 Mats Bengtsson <mabe@s3.kth.se>
-
- * lily/bar-line.cc (compound_barline): Fix parenthesis error,
- gives correct vertical placement of \bar ":" in all staff
- sizes. Thanks Martial!
-
-2006-06-26 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/invoking.itely : minor update from mailist.
-
-2006-06-26 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/ various: Introduce stream events of types Prepare,
- OneTimeStep, CreateContext, AnnounceNewContext, RemoveContext,
- ChangeContext, SetProperty, RevertProperty, Override and Revert.
-
- * lily/global-context*.cc: Time is now -inf before iteration
- starts.
-
- * lily/include/context.hh: Removed unique_, init_
-
- * Documentation/topdocs/NEWS: Make the feathered beam example
- avoid triggering a bug.
-
-2006-06-24 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/ various: small additions from mailist.
-
-2006-06-22 Mats Bengtsson <mabe@s3.kth.se>
-
- * ly/performer-init.ly: Add some missing links in the context
- hierarchy for MIDI output. There are probably some more missing!
-
-2006-06-21 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/ various: minor spelling fixes;
- thanks Dave Luttinen!
-
- * Documentation/user/ various: small clarifications;
- thanks Anthony Youngman!
-
-2006-06-20 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * po/fr.po: add \n appropriately.
-
- * lily/lexer.ll: remove ? from version-seen?
-
-2006-06-19 John Mandereau <john.mandereau@free.fr>
-
- * po/fr.po; update translation, by Jean-Charles Malahieude and
- John Mandereau.
-
-2006-06-19 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * THANKS: add Markus Schneider.
-
- * lily/tab-staff-symbol-engraver.cc: derive from Engraver, not
- Staff_symbol_engraver
-
- * ly/engraver-init.ly (AncientRemoveEmptyStaffContext): don't
- replace staff_engraver
-
- * lily/staff-symbol-engraver.cc (stop_spanner): announce end of
- spanner.
-
- * lily/staff-collecting-engraver.cc
- (acknowledge_end_staff_symbol): new function
-
- * lily/volta-engraver.cc (acknowledge_end_staff_symbol): new function.
-
- * lily/staff-collecting-engraver.cc
- (acknowledge_end_staff_symbol): new function.
-
- * lily/main.cc: switch on relocation by default.
-
-2006-06-18 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/spacing-spanner.cc (musical_column_spacing): set
- compound_fixed_note_space to 0.0. Document why.
-
- * lily/simple-spacer.cc (is_sane): also have a kludge for numeric
- range of inverse_hooke_
- (Simple_spacer): init completely.
- (fits): const
- (get_line_configuration): don't use cols.resize(); it introduces
- initialized data.
-
- * scm/framework-ps.scm (dump-page): add setstrokeadjust.
-
- * ps/music-drawing-routines.ps: remove selectfont L1 hack.
-
- * lily/beaming-pattern.cc (best_splitpoint_index): urg, 2nd
- try. Divide by beatlength.
-
- * input/regression/beaming-ternary-metrum.ly: update doc.
- add beatLength hack.
-
- * scm/music-functions.scm (make-time-signature-set): add
- standard-beat-grouping.
-
-2006-06-17 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * input/regression/tie-whole.ly: new file.
-
- * lily/tie-formatting-problem.cc (set_column_chord_outline): don't
- cross center of note head in case of invisible stem.
-
-2006-06-16 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/ various: small fixes from mailist.
-
-2006-06-16 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/breathing-sign.cc (offset_callback): idem.
-
- * lily/align-interface.cc (align_to_fixed_distance): remove
- hungarian suffix.
-
- * lily/beaming-pattern.cc (count_factor_twos): oops. We want
- x%2==0.
-
-2006-06-15 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): release 2.9.9
-
- * ly/lilypond-book-preamble.ly: add \version
-
-2006-06-14 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scripts/lilypond-book.py (PREAMBLE_LY): include
- lilypond-book-preamble.ly
-
- * lily/stem.cc (get_beaming): return max of 0 and
- scm_ilength. Fixes slurring from/to beams.
-
- * ly/lilypond-book-preamble.ly: new file.
-
- * lily/slur.cc: add inspect-index feature.
-
-2006-06-13 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/tutorial.itely: trivial fix.
-
-2006-06-13 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/parser.yy, scm/ly-syntax-constructors.scm: Produce almost
- all non-event music in the parser via MAKE_SYNTAX.
-
- * lily/parser-scheme.cc: Add ly:parser-error function
-
- * scm/paper.scm: fix typo
-
-2006-06-13 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * THANKS: add RT.
-
- * lily/font-config.cc (init_fontconfig): add warning if cache_file
- is null.
-
- * buildscripts/output-distance.py (test_compare_signatures):
- timing routines.
- (read_signature_file): use new signature format.
-
- * scm/stencil.scm (write-system-signature): simpler signature
- format.
-
- * lily/stem.cc (calc_stem_end_position): calc quantized-positions
- for beamed case.
-
- * lily/note-spacing.cc (stem_dir_correction): don't inspect
- stem_end_position, but estimate instead.
-
- * lily/tuplet-bracket.cc (calc_positions): look at
- stem-end-position for tuplet bracket slope. Fixes sloped tuplet
- brackets narrower than beams.
-
- * lily/lexer.ll: set version-seen? even if version is
- INVALID.
-
- * lily/rest.cc (y_offset_callback): bugfix: decide position
- override based on scm_is_number(). Fixes \rest on center staff
- line.
-
- * lily/beaming-pattern.cc (best_splitpoint_index): fix beaming
- patterns for 16th triplets.
-
-2006-06-10 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/ page.itely, global.itely: editing
- and reorg.
-
- * Documentation/user/ various: findex -> funindex.
-
-2006-06-10 Erik Sandberg <mandolaerik@gmail.com>
-
- * lily/time-scaled-music-iterator.cc: Use tupletSpannerDuration to
- insert extra tuplet events.
-
-2006-06-10 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/programming-interfaces.itely: add
- info from NEWS.
-
- * python/convertrules.py: add annotatefoo -> annotate-foo
- rules.
-
- * Documentation/user/global.itely: start editing.
-
- * Documentation/user/page.itely: major editing, new spacing
- docs.
-
-2006-06-10 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/define-markup-commands.scm (wordwrap-markups): use
- output-def 'line-width if undefined.
-
- * HACKING: trim outdated info.
-
-2006-06-09 Mats Bengtsson <mabe@s3.kth.se>
-
- * scm/define-grobs.scm (all-grob-descriptions): Add
- line-spanner-interface to all grobs that already have
- text-spanner-interface or dynamic-text-spanner-interface
-
- * scm/page.scm: Rename annotate{headers,systems,page}->
- annotate-*
-
- * input/regression/page-spacing.ly,
- input/regression/page-layout-manual-position.ly: idem
-
-2006-06-09 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/line-spanner.cc: cleanup property list.
-
- * scripts/lilypond-book.py (find_toplevel_snippets): don't use
- generator expressions (2.3 compat).
-
-2006-06-09 Mats Bengtsson <mabe@s3.kth.se>
-
- * lily/vertical-align-engraver.cc: Make sure that the
- align{Above,Below}Context properties are included in the automatic
- documentation.
-
-2006-06-08 Joe Neeman <joeneeman@gmail.com>
-
- * scm/paper-system.scm (paper-system-annotate): also annotate the
- estimated pure-Y-extent
-
- * scm/define-grobs.scm: add pure-Y-extent and pure-Y-offset functions
-
- * lily/system.cc (break_into_pieces): set the estimated height
- of each child system
-
- * lily/stem.cc (pure_height): new pure-Y-extent callback
-
- * lily/staff-symbol-referencer.cc (callback): don't destroy
- the staff-position property
-
- * lily/hara-kiri-group-spanner.cc (request_suicide): split
- consider_suicide into two functions
-
- * lily/constrained-breaking.cc (resize): use the new pure
- callbacks to estimate the height of a system
-
- * lily/axis-group-interface.cc (pure_group_height): new
- side-effect-free VerticalAxisGroup height-callback
-
- * lily/align-interface.cc (get_extents_aligned_translates):
- split align_elements_to_extents into two functions
- (get_pure_child_y_translation): new function
-
- * lily/grob.cc: new functions for pure-Y-extent and pure-Y-offset
-
- * lily/item.cc: new functions pure_is_visible and spanned_rank_iv
-
- * lily/paper-score.cc: cache break_indices and columns
-
- * lily/side-position-interface.cc: new pure-Y-extent callbacks
-
-2006-06-08 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/font-config.cc (init_fontconfig): do the init if
- cache_file, but don't look at cache_file.
-
- * input/regression/quote-tie.ly: new file.
-
- * lily/tie-engraver.cc (struct Head_event_tuple): add end_moment_
- to Head_event_tuple, so we deal gracefully with ties on
- cue-endings.
-
- * lily/pango-font.cc (pango_item_string_stencil): type correctness
- for FcChar8*
-
-2006-06-08 Graham Percival <gpermus@gmail.com>
-
- * input/test/ smart-transpose.ly, reverse-music.ly:
- \applyMusic to music functions update, thanks Michael!
-
-2006-06-07 Graham Percival <gpermus@gmail.com>
-
- * input/test/ add-staccato.ly, add-text-script.ly,
- unfold-all-repeats.ly, music-box.ly: \applyMusic to
- music functions update, thanks to Michael Meixner.
-
- * Documentation/user/music-glossary.tely: small fix
- from Francisco.
-
- * Documentation/user/ various: minor additions from mailist.
-
- * Documentation/user/lilypond.tely, basic-notation.itely:
- small test of @funindex. (works here)
-
- * input/test/font-table.ly: reduce size to partially
- de-ugly version in manual.
-
- * Documentation/user/page.itely: new file (split former
- "global issues" into "page settings" and "non-musical
- output".
-
- * Documentation/user/ various: fix @ref{}s to match
- new chapter names (above).
-
-2006-06-07 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * SConstruct (LILYPONDPREFIX): Bootstrap fix.
-
-2006-06-06 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/advanced-notation.itely: add example
- for segno/coda on barline.
-
- * tex/texinfo.tex: merge from upstream.
-
-2006-06-06 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * scripts/lilypond-book.py (process_snippets): Argument fix.
-
- * SConstruct:
- * buildscripts/builder.py:
- * lily/SConscript:
- * mf/SConscript:
- * Documentation/user/SConscript: More SCons fixes.
-
-2006-06-03 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * lily/font-config.cc (init_fontconfig): Only initialize if
- global cache_file is found.
-
-2006-06-06 Erik Sandberg <mandolaerik@gmail.com>
-
- * ly/music-functions-init.ly: Updated \overrideProperty to use the
- new \applyOutput.
-
-2006-06-06 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * VERSION (PACKAGE_NAME): release 2.9.8
-
- * lily/ledger-line-engraver.cc (stop_translation_timestep): new
- function. Delay ledger modifying ledgered grobs to
- stop_translation_timestep(), to ensure that we're ledgering
- according to the new spanner.
- (acknowledge_staff_symbol): don't check for non-NULL
- staff_sym->get_bound()
-
- * lily/staff-symbol-engraver.cc (start_spanner): set left bound on
- creation.
-
- * Documentation/pictures/GNUmakefile (XPM_FILES): src-wildcard for
- pictures too.
-
- * GNUmakefile.in (dist-toplevel-txt-files): dist aclocal.m4
- directly from srcdir/stepmake/aclocal.m4
-
- * Documentation/misc/GNUmakefile (TEXTS): use src-wildcard for
- disting MISC files.
-
- * lily/simple-spacer.cc (get_column_desc): desc -> description.
-
-2006-06-06 Joe Neeman <joeneeman@gmail.com>
-
- * lily/simple-spacer.cc (get_line_configuration): add
- keep-inside-line rods
- (struct Column_desc): add constructor
- (struct Rod_desc): add constructor
- (get_line_forces): check for forced page breaks here too
-
- * lily/instrument-name-engraver.cc (acknowledge_axis_group): prevent
- support/elements cycles between InstrumentNames and AxisGroups
-
-2006-06-06 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * config.make.in (METAFONT): remove MAKEINFO_VERSION
-
- * stepmake/stepmake/topdocs-targets.make (make-txt-files): define
- make-txt-files target.
-
- * stepmake/stepmake/toplevel-targets.make (do-top-doc): use
- make-txt-files target.
-
- * configure.in (LINK_GXX_STATICALLY): $srcdir for readlink.py
-
- * stepmake/stepmake/generic-vars.make (distdir): create dist in
- top-build-dir.
-
-2006-06-06 Jürgen Reuter <reuter@ipd.uka.de>
-
- * Documentation/user/instrument-notation.itely,
- input/regression/breathing-sign-ancient.ly,
- input/test/divisiones.ly: Removed redundant property settings for
- vaticana contexts.
-
- * ly/gregorian-init.ly: Rewrote \versus and \responsum in order to
- fix lyrics alignment problems. They are implemented now as scheme
- functions that add the appropriate unicode char to the first lyric
- event rather than adding a separate lyric event. Minor edit of
- comments.
-
-2006-06-06 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * GNUmakefile.in (dist-toplevel-txt-files): new target. Don't
- pollute src dir with built .txt files, but install directly from
- Documentation/topdocs/out/
-
- * buildscripts/output-distance.py
- (ComparisonData.create_html_result_page): put version/directories
- in table header.
-
- * Documentation/topdocs/NEWS.tely (Top): document spacing section
- feature.
-
- * configure.in (LINK_GXX_STATICALLY): use readlink.py to resolve links.
- Patch by Karl Hammar
-
- * buildscripts/readlink.py: add file.
- Patch by Karl Hammar
-
-2006-06-06 Joe Neeman <joeneeman@gmail.com>
-
- * lily/tuplet-number.cc (print): prevent stencil from being
- garbage collected.
-
-2006-06-05 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * scm/stencil.scm (write-system-signature): explicitly
- -well, superfluously- close output port.
-
- * buildscripts/output-distance.py (main): oops. Add extra argument.
-
-2006-06-05 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/music-glossary.tely: clarified example
- from Francisco Vila, thanks!
-
-2006-06-05 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * input/regression/spacing-section.ly: new file.
-
- * lily/input.cc (programming_error): new function.
-
- * lily/spacing-engraver.cc (try_music): new function. Accept
- spacing-section-event
-
- * lily/spacing-spanner.cc (set_springs): take slices of all
- columns for spacing.
-
- * lily/include/paper-column.hh (class Paper_column): add
- Paper_column::compare.
-
- * ly/spanners-init.ly (newSpacingSection): add newSpacingSection.
-
- * scm/define-music-types.scm (music-descriptions): add
- SpacingSectionEvent
-
- * lily/music-iterator.cc (report_event): use programming_error for
- sending non-event error.
-
- * lily/input.cc (programming_error): new function
-
- * buildscripts/output-distance.py (main): use compare-XXX for
- compare files.
- (main): --threshold option, default at 0.30
-
- * output-distance.py (main): add --threshold option.
-
-2006-06-04 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * scm/paper-system.scm (paper-system-annotate): fix problem when
- annotating an empty system
-
-2006-06-04 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * GNUmakefile.in: reinstate old web tar/copying.
-
-2006-06-03 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/lyric-combine-music-iterator.cc (find_voice): return 0 if
- nothing changes. (Erik S)
-
- * lily/percent-repeat-iterator.cc (get_music_list): fix repeat
- count. (Erik S)
-
-2006-05-28 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
- * scm/define-markup-commands.scm (whiteout): do not force
- foreground color of argument markup to black.
-
- * scm/stencil.scm (annotate-y-interval): put arrow dimension at
- the left of the arrow, instead of below the arrow name, so that,
- when two little arrows are vertically stacked, their dimensions
- and name should not overlap. Add a color key parameter.
-
- * scm/paper-system.scm (paper-system-annotate): Annotate
- next-space+next-padding instead of next-space. Annotate space
- between next-padding and next-space+padding, respectively, and
- following system extent and refpoint-Y-extent. Use colors.
-
- * scm/page.scm (annotate-page): translate annotations slightly to
- the right.
-
-2006-06-03 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * lily/figured-bass-position-engraver.cc (acknowledge_end_slur):
- fix for x-staff slurs. Thanks Joe!
-
- * buildscripts/output-distance.py
- (SystemLink.output_expression_change_count): keep track of changed
- details, and dump in details html page.
-
- * input/regression/figured-bass-staff.ly: add note about setting
- properties in Staff context.
-
- * lily/figured-bass-position-engraver.cc (acknowledge_slur):
- add slurs and ties to support too.
-
- * buildscripts/output-distance.py (main): set dest_dir
- argument. Add --max-count option.
-
-2006-06-02 Jürgen Reuter <reuter@ipd.uka.de>
-
- * ly/gregorian-init.ly: Converted to utf-8. Added memorable
- shortcuts for special unicode chars that are useful in chant
- notation. Revised exisiting and added new comments.
-
-2006-06-02 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * make/mutopia-rules.make: remove duplicate recipe.
-
-2006-06-02 Werner Lemberg <wl@gnu.org>
-
- * tex/texinfo.cnf: Fix typo (\euro -> \minus).
- Add support for U+0132 (IJ) and U+0133 (ij).
-
-2006-06-02 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * buildscripts/output-distance.py (FileLink): new class. collect
- info systems from one .ly file.
- (FileLink.link_files_for_html): further tweaks.
-
-2006-06-02 Graham Percival <gpermus@gmail.com>
-
- * tex/texinfo.tex: partial fix for @funindex.
-
- * Documentation/user/macros.tely: uncomment @funindex (doesn't
- break anything).
-
-2006-06-02 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * make/mutopia-vars.make (ly_examples): replace .ly.txt with .ly
-
- * tex/texinfo.tex (sectionheading, q.v.): call \quoteexpand for
- @example too. Backportme.
-
-2006-06-02 Graham Percival <gpermus@gmail.com>
-
- * tex/texinfo.cnf: added UTF-8 support for texinfo; patch
- from Werner Lemberg.
-
-2006-06-02 Paco (Francisco Vila) <fravd@ya.com>
-
- * Documentation/user/music-glossary.tely: additional spanish
- updates and a lyrics fix in an example.
-
-2006-06-02 Jürgen Reuter <reuter@ipd.uka.de>
-
- * scm/define-grob-properties.scm: Previous patch contained
- spurious line from another patch not yet committed. Fixed.
-
- * scm/define-grob-properties.scm: Add missing doc strings for
- ancient notation.
-
-2006-06-01 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * buildscripts/output-distance.py
- (ComparisonData.write_text_result_page): separate the scores, sort
- by geo_score.
-
- * scm/framework-eps.scm (output-classic-framework): start at 1 for
- system signatures.
-
- * buildscripts/output-distance.py (me_path): use argv[0] for
- sys.path extension
- (ComparisonData.img_cell): use colored borders.
-
- * scm/stencil.scm (write-system-signature): escape newlines too.
- (write-system-signature): use (1,-1) interval for empty interval
-
-2006-01-01 Graham Percival <gpermus@gmail.com>
-
- * Documentation/user/music-glossary.tely: Spanish updates
- from Francisco Vila.
-
- * Documentation/user/lilypond-book.itely: addition from
- Vaclav Smilauer.
-
- * Documentation/user/ various: edits, small additions
- from mailist, etc.
-
-2006-06-01 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * GNUmakefile.in (tree-lib-prefix-current):
- (tree-share-prefix-current): Use version number in tree, add
- `current' symlinks.
-
-2006-06-01 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * GNUmakefile.in: write VERSION, again.
-
- * make/mutopia-rules.make ($(outdir)/%.png $(outdir)/%.pdf
- $(outdir)/%.ly $(outdir)/%.ps): dump sigs for normal files too.
-
- * stepmake/aclocal.m4: robuster version detection.
-
- * buildscripts/output-distance.py
- (ComparisonData.create_html_result_page): copy only if file
- exists, fixup src paths.
-
- * stepmake/bin/add-html-footer.py (built): junk gulp_file()
-
-2006-06-01 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * stepmake/aclocal.m4: Robustification for (gcc) version detection.
- Another datarootdir reto.
-
- * cygwin/postinstall-lilypond.sh: Do not fail if info docs aren't
- available. This should be moved to postinstall-lilypond-doc.
-
-2006-05-31 Han-Wen Nienhuys <hanwen@lilypond.org>
-
- * GNUmakefile.in: simplify local-WWW-post.
- remove -type l from find.
-
- * buildscripts/output-distance.py (ComparisonData.compare_trees):
- fixes. Don't follow symlinks.
- (ComparisonData.create_html_result_page): remove previous results.
- insert ../python in path.
-
- * scripts/lilypond-book.py (PREAMBLE_LY): spacing fixes.
-
-2006-05-31 Jan Nieuwenhuizen <janneke@gnu.org>
-
- * config.make.in (datadir): Add datarootdir to silence autoconf.
-
- * stepmake/aclocal.m4: Update for autoconf-2.59d.
-
2006-05-31 Erlend Aasland <erlenda@gmail.com>
* dynamic-engraver.cc: fix bug (dynamics collide with accidentals)
- * scm/output-ps.scm (repeat-slash): fix a bug that made repeat
- slash beams too wide.
-
-2006-05-30 Han-Wen Nienhuys <hanwen@lilypond.org>
+ * scm/output-ps.scm (repeat-slash): fix a bug that made repeat slash beams
+ too wide.
- * VERSION: release 2.9.7
-
2006-05-30 Jan Nieuwenhuizen <janneke@gnu.org>
* lily/relocate.cc (read_relocation_dir): Do not blindly
* ly/Welcome-to-LilyPond-MacOS.ly: include in LilyPond, so version
number stays up to date. Backportme.
-2006-05-30 Mats Bengtsson <mabe@s3.kth.se>
+2006-05-30 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/basic-notation.itely (Bar lines): Document
the "||:" bar type.
* Documentation/topdocs/NEWS.tely (Top): add hairpinToBarline feature.
-2006-05-16 Mats Bengtsson <mabe@s3.kth.se>
+2006-05-16 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Instrument names):
Modified obsolete instruction on how to move instrument names away
* Documentation/user/ various: small fixes.
-2006-05-12 Mats Bengtsson <mabe@s3.kth.se>
+2006-05-12 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/programming-interface.itely (Markup
programmer interface): Remove duplicate text.
* lily/relocate.cc (framework_relocation): remove old relocation stuff.
-2006-05-01 Mats Bengtsson <mabe@s3.kth.se>
+2006-05-01 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/define-grob-properties.scm (all-user-grob-properties):
Correct typo, thanks to Eduardo.
* python/convertrules.py (conv): indent 4 for python files.
-2006-04-29 Mats Bengtsson <mabe@s3.kth.se>
+2006-04-29 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/changing-defaults.itely (Creating contexts):
Clarify \new semantics.
* scm/define-context-properties.scm (all-user-translation-properties):
* Documentation/user/global.itely (Page formatting): Compile fix.
-2006-04-09 Mats Bengtsson <mabe@s3.kth.se>
+2006-04-09 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Polymetric
notation): Update the example to use the "+" symbol and add link
* lily/pango-font.cc (pango_item_string_stencil): only use uXXX
glyphnames if we have a ttf font.
-2006-03-30 Mats Bengtsson <mabe@s3.kth.se>
+2006-03-30 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Font selection):
Corrected reference to the font-family-override.ly example.
* Documentation/user/global.itely: small fix from mailist.
-2006-03-14 Mats Bengtsson <mabe@s3.kth.se>
+2006-03-14 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/lilypond-book.py (LATEX_INSPECTION_DOCUMENT): Use the
file descriptor returned by tempfile.mkstemp() when writing
* ly/engraver-init.ly: init rehearsalMarkAlignSymbol to staff-bar.
-2006-03-12 Mats Bengtsson <mabe@s3.kth.se>
+2006-03-12 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/instrument-notation.itely (Setting simple
songs): Added \book{...} around the full example, so the separate
* lily/main.cc:
* configure.in: Cosmetic fixes.
-2006-01-04 Mats Bengtsson <mabe@s3.kth.se>
+2006-01-04 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/music-glossary.tely (Pitch names): Added
Spanish pitch names and durations, thanks to Ernesto Gancedo
* lily/all-font-metrics.cc (kpathsea_find_file): use (scm
kpathsea) module.
-2005-11-29 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-29 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Setting automatic
beam behavior): Correct a few typos. Thanks to David Bobroff.
* python/midi.c: doc module.
-2005-11-22 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-22 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/global.itely (Creating MIDI files): Fix
compilation problem.
* lily/clef-engraver.cc (inspect_clef_properties): reset
localKeySignature for clef changes.
-2005-11-17 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-17 Mats Bengtsson <mabe@drongo.s3.kth.se>
* python/midi.c: PyMIDINIT_FUNC isn't defined in Python < 2.3
add dummy definition that works in Linux and add information in
* Documentation/user/music-glossary.tely (dal segno): Updated
example to version >=2.6.
-2005-11-16 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-16 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/instrument-notation.itely (Printing chord
names): Reorder \chordmode and \repeat in one example.
* scripts/lilypond-book.py (main): use commands.mkarg () to quote
shell arguments.
-2005-11-10 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-10 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/examples.itely (Piano templates): Minor
modification to the Piano centered lyrics example.
* scm/define-grob-properties.scm (all-user-grob-properties):
remove [XY]-offset-callbacks add [YX]-offset
-2005-11-02 Mats Bengtsson <mabe@s3.kth.se>
+2005-11-02 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/define-grobs.scm (all-grob-descriptions): Added space-alist
entry for time signatures after breathing signs. Bug report by
* lily/include/horizontal-bracket.hh (struct Horizontal_bracket):
new file.
-2005-10-04 Mats Bengtsson <mabe@s3.kth.se>
+2005-10-04 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/lilypond-book.py: Bug fix, put the quote around the
actual score for LaTeX documents.
* scm/define-music-types.scm (music-descriptions): set length and
start-callback for QuoteMusic
-2005-09-15 Mats Bengtsson <mabe@s3.kth.se>
+2005-09-15 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/tie.cc (get_configuration): Replace fabs -> abs for integer
arguments. Fixes compilation error with gcc 3.3.
* Documentation/user/advanced-notation.itely,
basic-notation.itely: minor changes.
-2005-08-31 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-31 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/framework-eps.scm (dump-stencils-as-EPSes): Insert a
\linebreak between each .eps file if \betweenLilyPondSystem is
* scm/define-markup-commands.scm (null): add null markup.
-2005-08-25 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-25 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/item.cc: Add documentation of center-invisible
* lily/skyline.cc: fix ASCII art.
-2005-08-22 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-22 Mats Bengtsson <mabe@drongo.s3.kth.se>
* python/convertrules.py (string_or_scheme): Fix spelling error
* lily/include/performer-group.hh: rename.
-2005-08-18 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-18 Mats Bengtsson <mabe@drongo.s3.kth.se>
* input/test/script-abbreviations.ly: Removed some old LaTeX
left overs.
input/regression/ to input/no-notation. Be sure to call
`display-lily-init' before trying to use the display function.
-2005-08-16 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-16 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/lilypond-book.py (option_definitions): Don't localize
the empty string. Fixes bug when --psfonts was used with
* tex/GNUmakefile (INSTALLATION_FILES): Remove enc symlink setup,
encoding files are already removed.
-2005-08-15 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-15 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Instrument names):
Document a workaround for instrument names that collide with
* Documentation/user/advanced-notation.itely: add markup
example to Text spanners.
-2005-08-12 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-12 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/basic-notation.itely (Ties): Add example of
tying a tremolo to a chord. Thanks to Steve Doonan.
do_shift if script inside slur, even if slur not contained in
script y-extent. Increment k in loop.
-2005-08-11 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-11 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/define-markup-commands.scm: Improved regexp to search for
EPS bounding boxes and corrected call to ly:warning.
expressions): doc for \displayLilyMusic. Also some precisions in
"Markup construction in Scheme"
-2005-08-10 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-10 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/define-markup-commands.scm (normal-text): Added 2 new
markup commands, \normal-text and \medium (the latter thanks to
* Documentation/user/basic-notation.itely: reword multi-measure
rest discussion in Rests.
-2005-08-08 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-08 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/programming-interface.itely (Markup
construction in Scheme): Corrected example and tried to clarify
* mf/feta-generic.mf: add feta-arrow.
-2005-08-03 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-03 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/lilypond-book.itely (An example of a
musicological document): Added flag -o to dvips for people who use
* ly/declarations-init.ly (center): escape to Scheme. Fixes
spurious #<Music FingerEvent> errors. Backportme.
-2005-08-03 Mats Bengtsson <mabe@s3.kth.se>
+2005-08-03 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/programming-interface.itely (Markup
construction in Scheme): Corrected markup syntax in the
* Documentation/user/lilypond.itely: change encoding to utf-8.
-2005-07-01 Mats Bengtsson <mabe@s3.kth.se>
+2005-07-01 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Setting automatic
beam behavior): Correct the documentation of
* scm/midi.scm: compile fix.
-2005-06-28 Mats Bengtsson <mabe@s3.kth.se>
+2005-06-28 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/lilypond-book.py : Fix embarrassing bug in my previous
patch. Now, the tempfile module is loaded too, not only used.
* buildscripts/gen-emmentaler-scripts.py (notice): add GPL notice
to fonts.
-2005-06-23 Mats Bengtsson <mabe@s3.kth.se>
+2005-06-23 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/lilypond-book.py (LATEX_DOCUMENT): More or less ugly
workaround since /dev/stdin doesn't work on Cygwin. Using a
* scm/backend-library.scm (postprocess-output): remove debugging gobs.
-2005-06-14 Mats Bengtsson <mabe@s3.kth.se>
+2005-06-14 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/topdocs/NEWS.tely (Top): Corrected name of
\musicDisplay
* lily/main.cc (prepend_env_path, set_env_file): Use them.
-2005-06-02 Mats Bengtsson <mabe@s3.kth.se>
+2005-06-02 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/easy-notation.cc: Added include cctype to correct
compilation error.
* lily/main.cc (setup_paths)[ARGV0_RELOCATION]: Remove GS_*.
-2005-05-16 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-16 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/horizontal-bracket.cc (print): Take care of the direction
property so brackets above the stave point downwards.
Documentation/user/tutorial.itely: begin pruning
unused (duplicated) cindex entries and misc cleanup.
-2005-05-12 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-12 Mats Bengtsson <mabe@drongo.s3.kth.se>
* input/test/volta-chord-names.ly: Bring the explanation up to
date.
* configure.in (gui_b): Add mbrtowc checking.
Resurrect [utf8/]wchar.h checking.
-2005-05-09 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-09 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/advanced-notation.itely (Metronome marks):
Add link to the program reference for MetronomeMark
* lily/general-scheme.cc (LY_DEFINE): hand-convert utf8 to 32
bits. Patch by Matthias Neeracher. <neeracher@mac.com>
-2005-05-09 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-09 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/convert-ly.py: In the conversion to version 1.9.0,
keep Scheme expressions and strings unmodified when doing the
* Documentation/user/programming-interface.itely (How markups work
internally ): remove \encoding reference.
-2005-05-04 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-04 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/convert-ly.py: Attempt to do a smarter update of
text markups from versions < 1.9.0 with arbitrary nesting.
* configure.in: Search for mingw wcrtomb library.
-2005-05-02 Mats Bengtsson <mabe@s3.kth.se>
+2005-05-02 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scripts/convert-ly.py: Bug fix
* Documentation/user/advanced-notation.itely: corrected docs
concerning remove-first.
-2005-04-29 Mats Bengtsson <mabe@s3.kth.se>
+2005-04-29 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/part-combine-engraver.cc: make sure that the relevant
properties are included in the documentation.
lilypond-book filter example and warned about not doing
--filter and --process at the same time.
-2005-03-23 Mats Bengtsson <mabe@s3.kth.se>
+2005-03-23 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/parser.yy (bass_number),
Documentation/user/instrument-notation.itely (Figured bass):
* mf/feta-test-generic.mf: Include all files as in feta-generic.mf.
-2005-01-13 Mats Bengtsson <mabe@s3.kth.se>
+2005-01-13 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/notation.itely (Ancient rests): Fix typo
(thanks Anthony)
dump systems as separate .eps files (without fonts) and write a
single collecting .tex file.
-2005-01-05 Mats Bengtsson <mabe@s3.kth.se>
+2005-01-05 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/user/notation.itely (Setting simple songs):
Correct several errors in the equivalent formulation of
* scm/output-svg.scm (svg-font): Add weight to font selection.
-2004-12-14 Mats Bengtsson <mabe@s3.kth.se>
+2004-12-14 Mats Bengtsson <mabe@drongo.s3.kth.se>
* Documentation/topdocs/INSTALL.texi (Top): Point to
buildscripts/out/clean-fonts instead of
* lily/vaticana-ligature.cc: Fix for MacOS X: use <math.h> instead of
<cmath> beacause isinf/isnan is undefined in <cmath>
-2004-12-03 Mats Bengtsson <mabe@s3.kth.se>
+2004-12-03 Mats Bengtsson <mabe@drongo.s3.kth.se>
* cygwin/lily-wins.py (stat): remove old flag -p when calling lilypond.
* buildscripts/guile-gnome.sh: Update.
-2004-11-10 Mats Bengtsson <mabe@s3.kth.se>
+2004-11-10 Mats Bengtsson <mabe@drongo.s3.kth.se>
* scm/define-grobs.scm (all-grob-descriptions): Added
line-interface to the LigatureBracket object.
* tex/texinfo.tex: Updated from texinfo CVS -- this version provides
better output for multicolumn tables.
-2004-11-01 Mats Bengtsson <mabe@s3.kth.se>
+2004-11-01 Mats Bengtsson <mabe@drongo.s3.kth.se>
* lily/main.cc (dir_info): Fixed typo in the printouts.
Those deserving special mentioning (in no particular order):
Esther, Marijke, Heike, Inge, Judith, Hannah, Auke, Ilse, Evelyn,
Maartje, Suzanne, Ilse (gee, again?), Marieke, Irene, Martine, Idwine,
-Hanna, Lonneke, Elisha, Anna, Janneke and last (but certainly not
-least) Janneke!
+Hanna, Lonneke, Elisha, Anna and last (but certainly not least)
+Janneke!
HWN
depth = ..
NAME = documentation
-SUBDIRS=user bibliography pictures topdocs misc
+SUBDIRS=user bibliography pictures topdocs misc
STEPMAKE_TEMPLATES=documentation texinfo tex
LOCALSTEPMAKE_TEMPLATES=lilypond ly
LILYPOND_BOOK_FLAGS=--extra-options '-e "(ly:set-option (quote internal-type-checking) \#t)"'
STEPMAKE_TEMPLATES=documentation texinfo
-TEXTS = $(call src-wildcard,ANNOUNCE-*[0-9]) $(call src-wildcard,CHANGES-*[0-9]) $(call src-wildcard,ChangeLog*[0-9]) $(call src-wildcard,NEWS-*[0-9])
+TEXTS = $(wildcard ANNOUNCE-*[0-9]) $(wildcard CHANGES-*[0-9]) $(wildcard ChangeLog*[0-9]) $(wildcard NEWS-*[0-9])
EXTRA_DIST_FILES = $(TEXTS)
include $(depth)/make/stepmake.make
depth = ../..
STEPMAKE_TEMPLATES=documentation
-XPM_FILES=$(call src-wildcard,*.xpm)
+XPM_FILES=$(wildcard *.xpm)
EXTRA_DIST_FILES= $(XPM_FILES)
lilypond-icon = $(outdir)/lilypond.ico
$(outdir)/NEWS.nexi: NEWS.tely
-
@end ignore
-@item Calculation of note head durations is now softcoded.
-
-@lilypond[relative=1,fragment,ragged-right]
- %% use half heads for whole notes.
- \override NoteHead #'duration-log = 1
- c1 c2 c4 c8[ c16 c]
-@end lilypond
-
-
-@c Please insert any new material above this line. -gp
-
-@item Chords can now be partially tied,
-
-@lilypond[ragged-right,relative,fragment]
-<c~ e g~ b> <c e g b>
-@end lilypond
-
-This feature was sponsored by Steve Doonan.
-
-@item Lyric extenders now have tunable padding.
-
-This feature was sponsored by David Griffel.
-
-@item
-Instrument changes are better supported: names in the margin can be
-changed half-way during a staff, and cues are printed automatically.
-
-This feature was sponsored by Kieren MacMillan.
-
-@item
-Barlines can be dashed now,
-
-@lilypond[relative,ragged-right,fragment]
-c4 \bar "dashed" c4
-@end lilypond
-
-This feature was sponsored by Kieren MacMillan.
-
-@item
-Grace notes may be forced to use floating spacing,
-
-@lilypond[relative=2,ragged-right]
-<<
- \override Score.SpacingSpanner #'strict-grace-spacing = ##t
- \new Staff {
- c'4
- \afterGrace
- c'4
- { c'16[ c'8 c'16] }
- c'4
- }
- \new Staff {
- c'16[ c'16 c'16 c'16]
- c'16[ c'16 c'16 c'16]
- c'4
- }
->>
-@end lilypond
-
-This feature was sponsored by Trevor Bača.
-
-
-@item
-Durations of grace notes are taken into account for spacing,
-
-@lilypond[relative=2,ragged-right,fragment]
- c
- \grace { c8[ c16 d c8] }
- c
-@end lilypond
-
-This feature was sponsored by Trevor Bača.
-
-@item
-Tuplet brackets can be made to run to prefatory matter or
-the next note
-
-@lilypond[ragged-right]
-\new RhythmicStaff {
- \set tupletFullLength = ##t
- \time 4/4
- \times 4/5 {
- c4 c1
- }
- \set tupletFullLengthNote = ##t
- \time 2/4
- \times 2/3 {
- c4 c c
- }
- \time 3/4
- c4
-}
-@end lilypond
-
-
-This feature was sponsored by Trevor Bača.
-
-@item
-Falls and doits can be added to notes
-
-@lilypond[fragment,ragged-right,relative=2]
-\override Score.SpacingSpanner #'shortest-duration-space = #3.0
-c4-\bendAfter #+5
-c4-\bendAfter #-3
-@end lilypond
-
-This feature was sponsored by Anthony Youngman and Paul Scott.
-
-@item
-@code{lilypond-book} now includes support for PDF@TeX{}.
-
-This feature was sponsored by David Roundy.
-
-@item
-Nested tuplets can have different formatting for each nesting level,
-
-@lilypond[ragged-right]
-\new Staff {
- \time 5/4
- \tweak #'text #tuplet-number::calc-fraction-text
- \times 5/3 {
- \tweak #'text #tuplet-number::calc-denominator-text
- \times 2/3 {
- c'8[ c'8 c'8]
- }
- \times 2/3 {
- c'8[ c'8 c'8]
- }
- \times 2/3 {
- c'8[ c'8 c'8]
- }
- }
-}
-@end lilypond
-
-This feature was sponsored by Trevor Bača.
-
-
-@item
-New sections with different spacing parameters can be started with
-@code{newSpacingSection}. This is useful when there are
-sections with a different notions of long and short notes.
-
-In the following example, the time signature change introduces a new
-section, and hence the 16ths notes are spaced wider.
-
-@lilypond[relative,fragment]
- \time 2/4
- c4 c8 c
- c8 c c4 c16[ c c8] c4
-
- \newSpacingSection
- \time 4/16
- c16[ c c8]
-@end lilypond
-
-This feature was sponsored by Trevor Bača, Michael Meixner and Vivian
-Barty-Taylor.
-
@item
A new, automated testing technique has been added. It will detect
changes in the formatting automatically, which will make it easier to
@item
Figured bass can also be added to @code{Staff} contexts directly. In
-this case, their vertical position is adjusted automatically.
+this case, their vertical position is adjusted automatically.
@lilypond[ragged-right,fragment]
<<
\override Beam #'grow-direction = #LEFT
c16[
c c c
- c c c ]
+ c c c c ]
}
@end lilypond
-Known bug: the \featherDuration command only works with very short music
-snippets.
-
This feature was sponsored by Jamie Bullock.
@item
LATEX_FILES =$(call src-wildcard,*.latex)
+# todo: add latex.
+DVI_FILES = $(TELY_FILES:%.tely=$(outdir)/%.dvi)
-EXTRA_DIST_FILES= $(LATEX_FILES) $(IMAGES) README.txt convert-ly.txt $(EPS_ILLUSTRATIONS)
+EXTRA_DIST_FILES= $(LATEX_FILES) $(IMAGES) README.txt $(EPS_ILLUSTRATIONS)
IMAGES=$(call src-wildcard,*.png)
EPS_ILLUSTRATIONS=context-example.eps
-PDF_ILLUSTRATIONS=context-example.pdf
-
-OUT_PDF_IMAGES=$(IMAGES:%.png=$(outdir)/%.pdf) $(addprefix $(outdir)/,$(PDF_ILLUSTRATIONS))
-OUT_PNG_IMAGES=$(OUT_PDF_IMAGES:%.pdf=%.png)
+OUT_EPS_IMAGES=$(IMAGES:%.png=$(outdir)/%.eps) $(addprefix $(outdir)/,$(EPS_ILLUSTRATIONS))
+OUT_PNG_IMAGES=$(OUT_EPS_IMAGES:%.eps=%.png)
OUT_TEXI_FILES=$(ITEXI_FILES:%.itexi=$(outdir)/%.texi)\
$(ITELY_FILES:%.itely=$(outdir)/%.texi)
HTML_FILES = $(TELY_FILES:%.tely=$(outdir)/%.html)\
$(outdir)/lilypond-internals.html
-# todo: add latex.
-PDF_FILES = $(TELY_FILES:%.tely=$(outdir)/%.pdf)
+PS_FILES = $(DVI_FILES:.dvi=.ps)
+PDF_FILES = $(DVI_FILES:.dvi=.pdf)
+
+PS_GZ_FILES= $(addsuffix .gz, $(PS_FILES))
INFO_DOCS = lilypond lilypond-internals music-glossary
INFO_FILES = $(INFO_DOCS:%=$(outdir)/%.info)
include $(depth)/make/stepmake.make
+dvi: $(DVI_FILES)
+
+ps: $(PS_FILES)
+
info: $(INFO_FILES)
pathsettings:
mkdir -p $(dir $@)
$(MAKEINFO) --output=$(outdir)/lilypond-internals --docbook $<
-$(outdir)/lilypond.pdf: $(OUT_PDF_IMAGES) $(OUT_PNG_IMAGES)
+$(outdir)/lilypond.dvi: $(OUT_EPS_IMAGES) $(OUT_PNG_IMAGES)
$(outdir)/%.png: %.png
convert -geometry 50x50% $< $@
$(outdir)/%.eps: %.eps
cp $< $@
-$(outdir)/%.pdf: %.png
- convert $< $@
-
-$(outdir)/%.pdf: %.eps
- gs -dAutoRotatePages=/None -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@ -dEPSCrop -c .setpdfwrite -f $<
-
-
DEEP_HTML_FILES =\
$(outdir)/lilypond/index.html\
$(outdir)/lilypond-internals/index.html\
Info for Documentation
----------------------
-Current version of the manual: 2.9.13
+Current version of the manual: 2.8.0
*** Please update this whenever you run convert-ly on the docs.
convert-ly --from=... --to=... --no-version *.itely
GENERAL GUIDELINES
* Do not forget to create @cindex entries for new sections of text.
- Enter commands with @funindex, i.e.
- @funindex \relative
- do not bother with the @code{} (they are added automatically). These
- items are added to both the command index and the unified index.
+Enter commands with @funindex, i.e.
+@funindex \relative
+do not bother with the @code{} (they are added automatically). These
+items are added to both the command index and the unified index.
* The use of the word `illegal' is inappropriate in most cases. Say
`invalid' instead.
import os
import string
-Import ('env', 'base_glob', 'src_glob')
+Import ('env', 'base_glob')
tely = base_glob ('*.tely')
-png = src_glob ('*.png') + map (env.EPS2PNG, base_glob ('*.eps'))
+png = base_glob ('*.png')
# We need lily and mf to build these.
env.Depends ('lilypond.texi', ['#/lily', '#/mf', '#/python'])
env.Depends ('lilypond.texi', 'lilypond-internals.texi')
-eps = src_glob ('*.eps') + map (env.PNG2EPS, base_glob ('*.png'))
-env.Depends ('lilypond.texi', eps + png)
+eps = map (env.PNG2EPS, png)
+env.Depends ('lilypond.texi', eps)
-lilypond_book_flags = '''--format=$LILYPOND_BOOK_FORMAT --process="lilypond -I$srcdir/input/manual/ $__verbose --backend=eps --formats=ps,png --header=texidoc -dcheck-internal-types -ddump-signatures -danti-alias-factor=2 -dgs-load-fonts" '''
e = env.Copy (
-# LILYPOND_BOOK_FLAGS = '''--process="lilypond --backend=eps --formats=ps,png --header=texidoc -I#/input/manual -e '(ly:set-option (quote internal-type-checking) \#t)'"''',
- LILYPOND_BOOK_FLAGS = lilypond_book_flags,
+ LILYPOND_BOOK_FLAGS = '''--process="lilypond --backend=eps --formats=ps,png --header=texidoc -I#/input/test -e '(ly:set-option (quote internal-type-checking) \#t)'"''',
__verbose = ' --verbose',
GENERATE_DOCUMENTATION = '$srcdir/ly/generate-documentation',
- ## TEXI2DVI_FLAGS = ['-I#Documentation/user'],
)
e.Command ('lilypond-internals.texi', ['#/lily', '#/mf', '#/python'],
@refcommands
-@funindex \fatText
+@findex \fatText
@code{\fatText},
-@funindex \emptyText
+@findex \emptyText
@code{\emptyText}.
@cindex segno on bar line
@cindex fermata on bar line
@cindex bar lines, symbols on
-@funindex \mark
+@findex \mark
The @code{\mark} command is primarily used for
@ref{Rehearsal marks},
but it can also be used to put signs like coda,
segno, and fermata on a bar line. Use @code{\markup} to
-access the appropriate symbol (symbols are listed in
-@ref{The Feta font})
+access the appropriate symbol
@lilypond[fragment,quote,ragged-right,verbatim,relative=2]
c1 \mark \markup { \musicglyph #"scripts.ufermata" }
#'break-visibility = #begin-of-line-invisible
\override Score.RehearsalMark #'self-alignment-X = #right
- \set Staff.instrumentName = \markup{ \column{ Alto solo } }
+ \set Staff.instrument = \markup{ \column{ Alto solo } }
c2^\markup{ don't be \flat }
\override TextSpanner #'edge-text = #(cons (markup #:italic "rit" ) "")
b2\startTextSpan
Text can also be placed on its own, away from any @code{\score}
block. This is primarily used in a @code{\book} (see
-@ref{Multiple scores in a book}).
+@ref{Multiple movements}).
@lilypond[quote,ragged-right,verbatim]
\markup{ Here is some text. }
@cindex font selection
@cindex font magnification
-@funindex font-interface
+@findex font-interface
By setting the object properties described below, you can select a
font from the preconfigured font families. LilyPond has default
@noindent
Any font can be used, as long as it is available to Pango/FontConfig.
-To get a full list of all available fonts, run the command
-@example
-lilypond -dshow-available-fonts blabla
-@end example
-(the last argument of the command can be anything, but has to be present).
-
The size of the font may be set with the @code{font-size}
property. The resulting size is taken relative to the
@cindex Rests, multi measure
@cindex Rests, full measure
@cindex whole rests for a full measure
-@funindex R
+@findex R
Rests for one full measure (or many bars) are entered using `@code{R}'. It
is specifically meant for full bar rests and for entering parts: the rest
In the MIDI output, they are interpreted as a tempo change. In the
layout output, a metronome marking is printed
-@funindex \tempo
+@findex \tempo
@lilypond[quote,ragged-right,verbatim,fragment]
\tempo 8.=120 c''1
@end lilypond
@subsection Rehearsal marks
@cindex Rehearsal marks
-@funindex \mark
+@findex \mark
To print a rehearsal mark, use the @code{\mark} command
and @code{format-mark-circle-barnumbers} to get bar numbers instead of
incremented numbers or letters.
-@cindex segno
-@cindex coda
-@cindex D.S al Fine
-
-Music glyphs (such as the segno sign) may be printed inside
-a @code{\mark}
-
-@lilypond[fragment,quote,ragged-right,verbatim,relative]
-c1 \mark \markup { \musicglyph #"scripts.segno" }
-c1 \mark \markup { \musicglyph #"scripts.coda" }
-c1 \mark \markup { \musicglyph #"scripts.ufermata" }
-c1
-@end lilypond
-
-@noindent
-See @ref{The Feta font} for a list of symbols which may be
-printed with @code{\musicglyph}.
-
The horizontal location of rehearsal marks can be adjusted by
setting @code{break-align-symbol}
@cindex Bar numbers
@cindex measure numbers
-@funindex currentBarNumber
+@findex currentBarNumber
Bar numbers are printed by default at the start of the line. The
number itself is stored in the @code{currentBarNumber} property, which
of the staves.
This can be achieved by setting @internalsref{Staff}.@code{instrument}
-and @internalsref{Staff}.@code{instr}, or
-@internalsref{PianoStaff}.@code{instrument} and
-@internalsref{PianoStaff}.@code{instr}. This will print text before
+and @internalsref{Staff}.@code{instr}. This will print a string before
the start of the staff. For the first staff, @code{instrument} is
used, for the following ones, @code{instr} is used.
@lilypond[quote,verbatim,ragged-right,relative=1,fragment]
-\set Staff.instrumentName = "Ploink "
-\set Staff.shortInstrumentName = "Plk "
+\set Staff.instrument = "Ploink "
+\set Staff.instr = "Plk "
c1
\break
c''
names, for example
@lilypond[quote,fragment,verbatim,ragged-right]
-\set Staff.instrumentName = \markup {
+\set Staff.instrument = \markup {
\column { "Clarinetti"
\line { "in B" \smaller \flat } } }
c''1
@lilypond[quote,verbatim,ragged-right]
{ <<
\new Staff {
- \set Staff.instrumentName = \markup {
+ \set Staff.instrument = \markup {
\center-align { "Clarinetti"
\line { "in B" \smaller \flat } } }
c''1
}
\new Staff {
- \set Staff.instrumentName = \markup{ \center-align { Vibraphone }}
+ \set Staff.instrument = \markup{ \center-align { Vibraphone }}
c''1
}
>>
\new StaffGroup \relative
<<
\new Staff {
- \set Staff.instrumentName = \markup { \hcenter-in #10 "blabla" }
+ \set Staff.instrument
+ = \markup { \hcenter-in #10 "blabla" }
c1 c1
}
\new Staff {
- \set Staff.instrumentName = \markup { \hcenter-in #10 "blo" }
+ \set Staff.instrument
+ = \markup { \hcenter-in #10 "blo" }
c1 c1
}
>>
@end lilypond
-To add instrument names to other contexts (such as @code{GrandStaff},
-@code{ChoirStaff}, or @code{StaffGroup}), the engraver must
-be added to that context.
-
-@example
-\layout@{
- \context @{\GrandStaff \consists "Instrument_name_engraver"@}
-@}
-@end example
-
-@noindent
-More information about adding and removing engravers can
-be found in @ref{Modifying context plug-ins}.
-
@seealso
@node Different editions from one source
@subsection Different editions from one source
-@funindex \tag
+@findex \tag
@cindex tag
The @code{\tag} command marks music expressions with a name. These
microtones, nested tuplet beams, and unusual fermatas, please
see those sections of the documentation.
+
+@c I don't think we should discourage modern composers who might
+@c want to sponsor new features. :)
+@c In general, the use of new, innovative notation makes a piece
+@c harder to understand and perform and its use should therefore be
+@c avoided. For this reason, support for contemporary notation in
+@c LilyPond is limited.
+
+
@menu
* Polymetric notation::
* Time administration::
* Special noteheads::
* Feathered beams::
* Improvisation::
-* Selecting notation font size::
@end menu
@node Special noteheads
@subsection Special noteheads
-@cindex note heads, special
-
Different noteheads are used by various instruments for various
meanings -- crosses are used for ``parlato'' with vocalists, stopped
notes on guitar; diamonds are used for harmonics on string instruments,
@node Feathered beams
@subsection Feathered beams
-Feathered beams are printed by setting the @code{grow-direction}
-property of a @code{Beam}. The @code{\featherDurations} function
-can be used to adjust note durations.
+Feathered beams are not supported natively, but they can be faked by
+forcing two beams to overlap. Here is an example,
+@c don't change relative setting witout changing positions!
@lilypond[ragged-right,relative=1,fragment,verbatim,quote]
-\featherDurations #(ly:make-moment 5 4)
-{
- \override Beam #'grow-direction = #LEFT
- c16[ c c c c c c]
-}
+\new Staff <<
+ \new Voice
+ {
+ \stemUp
+ \once \override Voice.Beam #'positions = #'(0 . 0.5)
+ c8[ c c c c ]
+ }
+ \new Voice {
+ \stemUp
+ \once \override Voice.Beam #'positions = #'(0 . -0.5)
+ c[ c c c c]
+ }
+>>
@end lilypond
-@refbugs
-
-The @code{\featherDuration} command only works with very short
-music snippets.
@node Improvisation
@subsection Improvisation
@end lilypond
-@node Selecting notation font size
-@subsection Selecting notation font size
-
-The easiest method of setting the font size of any context is by
-setting the @code{fontSize} property.
-
-@lilypond[quote,fragment,relative=1,verbatim]
-c8
-\set fontSize = #-4
-c f
-\set fontSize = #3
-g
-@end lilypond
-
-@noindent
-It does not change the size of variable symbols, such as beams or
-slurs.
-
-Internally, the @code{fontSize} context property will cause the
-@code{font-size} property to be set in all layout objects. The value
-of @code{font-size} is a number indicating the size relative to the
-standard size for the current staff height. Each step up is an
-increase of approximately 12% of the font size. Six steps is exactly a
-factor two. The Scheme function @code{magstep} converts a
-@code{font-size} number to a scaling factor.
-
-@lilypond[quote,fragment,relative=1,verbatim]
-c8
-\override NoteHead #'font-size = #-4
-c f
-\override NoteHead #'font-size = #3
-g
-@end lilypond
-
-Font size changes are achieved by scaling the design size that is
-closest to the desired size. The standard font size (for
-@code{font-size} equals 0), depends on the standard staff height. For
-a 20pt staff, a 10pt font is selected.
-
-The @code{font-size} property can only be set on layout objects that
-use fonts. These are the ones supporting the
-@internalsref{font-interface} layout interface.
-
-@refcommands
-
-The following commands set @code{fontSize} for the current voice:
-
-@funindex \tiny
-@code{\tiny},
-@funindex \small
-@code{\small},
-@funindex \normalsize
-@code{\normalsize}.
-
-
-
@node Educational use
@section Educational use
@cindex Invisible notes
@cindex Transparent notes
-@funindex \hideNotes
-@funindex \unHideNotes
+@findex \hideNotes
+@findex \unHideNotes
Hidden (or invisible or transparent) notes can be useful in preparing theory
or composition exercises.
@node Shape note heads
@subsection Shape note heads
-@cindex note heads, shape
-
In shape note head notation, the shape of the note head corresponds
to the harmonic function of a note in the scale. This notation was
popular in the 19th century American song books.
Shapes are determined on the step in the scale, where the base of the
scale is determined by the @code{\key} command
-@funindex \key
-@funindex shapeNoteStyles
-@funindex \aikenHeads
-@funindex \sacredHarpHeads
+@findex \key
+@findex shapeNoteStyles
+@findex \aikenHeads
+@findex \sacredHarpHeads
Shape note heads are implemented through the @code{shapeNoteStyles}
property. Its value is a vector of symbols. The k-th element indicates
@node Easy Notation note heads
@subsection Easy Notation note heads
-@cindex note heads, practice
-@cindex note heads, easy notation
@cindex easy notation
@cindex Hal Leonard
@refcommands
-@funindex \setEasyHeads
+@findex \setEasyHeads
@code{\setEasyHeads}
@end lilypond
The full range of colors defined for X11 can be accessed by using the
-Scheme function x11-color. The function takes one argument that can be a
+scheme function x11-color. The function takes one argument that can be a
symbol
@example
@lilypond[quote,ragged-right,verbatim]
{
\override Staff.StaffSymbol #'color = #(x11-color 'SlateBlue2)
- \set Staff.instrumentName = \markup {
+ \set Staff.instrument = \markup {
\with-color #(x11-color 'navy) "Clarinet"
}
\time 2/4
c1
@end lilypond
-@funindex '
-@funindex ,
+@findex '
+@findex ,
The optional octave specification takes the form of a series of
single quote (`@code{'}') characters or a series of comma
@cindex note names, default
A sharp is formed by adding @code{-is} to the end of a pitch name and
-a flat is formed by adding @code{-es}. Double sharps and double flats
-are obtained by adding @code{-isis} or @code{-eses} to a note name.
+a flat is formed by adding @code{-es}
@lilypond[quote,ragged-right,fragment,verbatim,relative=2]
a2 ais a aes
-a2 aisis a aeses
@end lilypond
-@noindent
-These are the Dutch note names. In Dutch, @code{aes} is contracted to
+Double sharps and double flats
+are obtained by adding @code{-isis} or @code{-eses} to a note name. These
+are the Dutch note names. In Dutch, @code{aes} is contracted to
@code{as}, but both forms are accepted. Similarly, both
@code{es} and @code{ees} are accepted
@lilypond[fragment,quote,ragged-right,verbatim,relative=2]
-a2 as e es
+a2 aisis a aeses
@end lilypond
A natural will cancel the effect of an accidental or key signature.
a4 aes a2
@end lilypond
-The input @code{d e f} is interpreted as ``print a D-natural,
-E-natural, and an F-natural,'' regardless of the key
-signature. For more information about the distinction between
-musical content and the presentation of that content, see
-@ref{More about pitches}.
-
-@lilypond[fragment,quote,ragged-right,verbatim,relative]
-\key d \major
-d e f g
-d e fis g
-@end lilypond
-
@commonprop
@cindex accidental, cautionary
@cindex accidental, parenthesized
@cindex reminder accidental
-@funindex ?
+@findex ?
@cindex cautionary accidental
@cindex parenthesized accidental
-@funindex !
+@findex !
Normally accidentals are printed automatically, but you may also
print them manually. A reminder accidental
and the note names they define are
@c what about micro-tunes, double-sharps, and double-flats? add
-@c more columns to the table?
+@c more clumns to the table?
@c Oh, and should this be made into a multitable?
@cindex note names, other languages
@example
@cindex Relative
@cindex Relative octave specification
-@funindex \relative
+@findex \relative
Octaves are specified by adding @code{'} and @code{,} to pitch names.
When you copy existing music, it is easy to accidentally put a pitch
@end lilypond
Octave changing marks are used for intervals greater than a fourth
-
@lilypond[quote,ragged-right,fragment,verbatim]
\relative c'' {
c g c f, c' a, e''
}
@end lilypond
-The pitch after @code{\relative} contains a note name.
+The pitch after the @code{\relative} contains a note name.
The relative conversion will not affect @code{\transpose},
@code{\chordmode} or @code{\relative} sections in its argument. To use
@end example
This checks that @var{pitch} (without quotes) yields @var{pitch} (with
-quotes) in @code{\relative} mode compared to the note given in the
-@code{\relative} command. If not, a warning is printed, and the
+quotes) in @code{\relative} mode. If not, a warning is printed, and the
octave is corrected. The @var{pitch} is not printed as a note.
In the example below, the first check passes without incident, since
-the @code{e} (in @code{relative} mode) is within a fifth of
-@code{a'}. However,
+the @code{e} (in relative mode) is within a fifth of @code{a'}. However,
the second check produces a warning, since the @code{e} is not within
a fifth of @code{b'}. The warning message is printed, and the octave
is adjusted so that the following notes are in the correct octave
@cindex Transpose
@cindex Transposition of pitches
-@funindex \transpose
+@findex \transpose
A music expression can be transposed with @code{\transpose}. The
syntax is
\transpose c bes @{ e4 @dots{} @}
@end example
-To print this music in B-flat again (i.e., producing a trumpet part,
+To print this music in B-flat again (i.e. producing a trumpet part,
instead of a concert pitch conductor's score) you would wrap the
existing music with another @code{transpose}
Program reference: @internalsref{TransposedMusic}.
-Example: @inputfileref{input/@/test,smart@/-transpose@/.ly}.
-
@refbugs
If you want to use both @code{\transpose} and @code{\relative},
you must put @code{\transpose} outside of @code{\relative}, since
-@code{\relative} will have no effect on music that appears inside a
+@code{\relative} will have no effect music that appears inside a
@code{\transpose}.
@subsection Rests
@cindex Rests
-@funindex \rest
-@funindex r
+@findex \rest
+@findex r
Rests are entered like notes with the note name @code{r}
@cindex Skip
@cindex Invisible rest
@cindex Space note
-@funindex \skip
-@funindex s
+@findex \skip
+@findex s
An invisible rest (also called a `skip') can be entered like a note
with note name `@code{s}' or with @code{\skip @var{duration}}
@subsection Durations
@cindex duration
-@funindex \longa
-@funindex \breve
-@funindex \maxima
+@findex \longa
+@findex \breve
+@findex \maxima
In Note, Chord, and Lyrics mode, durations are designated by numbers and
dots: durations are entered as their reciprocal values. For example, a
quarter note is entered using a @code{4} (since it is a 1/4 note), while
a half note is entered using a @code{2} (since it is a 1/2 note). For
-notes longer than a whole you must use the @code{\longa} and
-@code{\breve} commands
+notes longer than a whole you must use the variables @code{\longa} and
+@code{\breve}
@example
c'\breve
}
\layout {
ragged-right = ##t
- indent=0\mm
- \context {
- \Score
- \remove "Bar_number_engraver"
- }
\context {
\Staff
\remove "Clef_engraver"
@node Augmentation dots
@subsection Augmentation dots
-@funindex .
+@findex .
To obtain dotted note lengths, simply add a dot (`@code{.}') to
the number. Double-dotted notes are produced in a similar way.
situations. The following commands may be used to force a particular
direction manually
-@funindex \dotsUp
+@findex \dotsUp
@code{\dotsUp},
-@funindex \dotsDown
+@findex \dotsDown
@code{\dotsDown},
-@funindex \dotsNeutral
+@findex \dotsNeutral
@code{\dotsNeutral}.
@seealso
@cindex tuplets
@cindex triplets
-@funindex \times
+@findex \times
Tuplets are made out of a music expression by multiplying all durations
with a fraction
Tuplets may be nested, for example,
@lilypond[fragment,ragged-right,verbatim,relative=2]
-\override TupletNumber #'text = #tuplet-number::calc-fraction-text
+\set tupletNumberFormatFunction = #fraction-tuplet-formatter
\times 4/6 {
a4 a
\times 3/5 { a a a a a }
@refcommands
-@funindex \tupletUp
+@findex \tupletUp
@code{\tupletUp},
-@funindex \tupletDown
+@findex \tupletDown
@code{\tupletDown},
-@funindex \tupletNeutral
+@findex \tupletNeutral
@code{\tupletNeutral}.
@commonprop
-@funindex tupletNumberFormatFunction
+@findex tupletNumberFormatFunction
@cindex tuplet formatting
The property @code{tupletSpannerDuration} specifies how long each
For more information about @code{make-moment}, see
@ref{Time administration}.
-The format of the number is determined by the property @code{text} in
-@code{TupletNumber}. The default prints only the denominator, but if
-it is set to the function @code{tuplet-number::calc-fraction-text},
-@var{num}:@var{den} will be printed instead.
+The format of the number is determined by the property
+@code{tupletNumberFormatFunction}. The default prints only the
+denominator, but if it is set to the Scheme function
+@code{fraction-tuplet-formatter}, @var{num}:@var{den} will be printed
+instead.
To avoid printing tuplet numbers, use
\times 2/3 { c8 c c } \times 2/3 { c8 c c }
@end lilypond
-Tuplet brackets can be made to run to prefatory matter or
-the next note
-
-@lilypond[ragged-right]
-\new RhythmicStaff {
- \set tupletFullLength = ##t
- \time 4/4
- \times 4/5 {
- c4 c1
- }
- \set tupletFullLengthNote = ##t
- \time 2/4
- \times 2/3 {
- c4 c c
- }
- \time 3/4
- c4
-}
-@end lilypond
-
@seealso
@subsection Bar check
@cindex Bar check
-@funindex barCheckSynchronize
-@funindex |
+@findex barCheckSynchronize
+@findex |
Bar checks help detect errors in the durations. A bar check is
entered using the bar symbol, `@code{|}'. Whenever it is encountered
especially if the score is polyphonic, so a good place to start correcting
input is by scanning for failed bar checks and incorrect durations.
-@funindex |
-@funindex pipeSymbol
+@findex |
+@findex pipeSymbol
It is also possible to redefine the meaning of @code{|}. This is done
by assigning a music expression to @code{pipeSymbol},
@cindex Chords
-A chord is formed by a enclosing a set of pitches between @code{<}
-and @code{>}. A chord may be followed by a duration, and a set of
+A chord is formed by a enclosing a set of pitches in @code{<} and
+@code{>}. A chord may be followed by a duration, and a set of
articulations, just like simple notes
@lilypond[verbatim,ragged-right,fragment,quote,relative=1]
@refcommands
-@funindex \stemUp
+@findex \stemUp
@code{\stemUp},
-@funindex \stemDown
+@findex \stemDown
@code{\stemDown},
-@funindex \stemNeutral
+@findex \stemNeutral
@code{\stemNeutral}.
is to enter each voice as a sequence (with @code{@{...@}}), and combine
them simultaneously, separating the voices with @code{\\}
-@funindex \\
+@findex \\
@lilypond[quote,verbatim,fragment]
\new Staff \relative c' {
voice in the first @code{<< \\ >>} construct is effective in the second
@code{<< \\ >>}, and the voice is tied across the two constructs.
-@cindex note heads, styles
-
@lilypond[quote,verbatim,fragment]
\new Staff \relative c' {
\override NoteHead #'style = #'cross
@refcommands
-@funindex \oneVoice
+@findex \oneVoice
@code{\oneVoice},
-@funindex \voiceOne
+@findex \voiceOne
@code{\voiceOne},
-@funindex \voiceTwo
+@findex \voiceTwo
@code{\voiceTwo},
-@funindex \voiceThree
+@findex \voiceThree
@code{\voiceThree},
-@funindex \voiceFour
+@findex \voiceFour
@code{\voiceFour}.
-@funindex \shiftOn
+@findex \shiftOn
@code{\shiftOn},
-@funindex \shiftOnn
+@findex \shiftOnn
@code{\shiftOnn},
-@funindex \shiftOnnn
+@findex \shiftOnnn
@code{\shiftOnnn},
-@funindex \shiftOff
+@findex \shiftOff
@code{\shiftOff}: these commands specify in what chords of the current
voice should be shifted. The outer voices (normally: voice one and
two) have @code{\shiftOff}, while the inner voices (three and four)
* Unmetered music::
* System start delimiters::
* Staff symbol::
-* Writing music in parallel::
@end menu
@node Clef
@subsection Clef
-@funindex \clef
+@findex \clef
The clef indicates which lines of the staff correspond to which
pitches. The clef is set with the @code{\clef} command
@seealso
-Manual: @ref{Grace notes}.
-
Program reference: @internalsref{Clef}.
@subsection Key signature
@cindex Key signature
-@funindex \key
+@findex \key
The key signature indicates the tonality in which a piece is played. It
is denoted by a set of alterations (flats or sharps) at the start of the
@code{\key} @var{pitch} @var{type}
@end example
-@funindex \minor
-@funindex \major
-@funindex \minor
-@funindex \ionian
-@funindex \locrian
-@funindex \aeolian
-@funindex \mixolydian
-@funindex \lydian
-@funindex \phrygian
-@funindex \dorian
+@findex \minor
+@findex \major
+@findex \minor
+@findex \ionian
+@findex \locrian
+@findex \aeolian
+@findex \mixolydian
+@findex \lydian
+@findex \phrygian
+@findex \dorian
@cindex church modes
Here, @var{type} should be @code{\major} or @code{\minor} to get
Accidentals and key signatures often confuse new users, because
unaltered notes get natural signs depending on the key signature. For
-more information, see @ref{Accidentals} or @ref{More about pitches}.
-
-@lilypond[quote,ragged-right,verbatim,relative=2,fragment]
-\key g \major
-f1
-fis
-@end lilypond
+more information, see @ref{More about pitches}.
@commonprop
@cindex Time signature
@cindex meter
-@funindex \time
+@findex \time
Time signature indicates the metrum of a piece: a regular pattern of
strong and weak beats. It is denoted by a fraction at the start of the
@cindex partial measure
@cindex measure, partial
@cindex shorten measures
-@funindex \partial
+@findex \partial
Partial measures, such as an anacrusis or upbeat, are entered using the
\partial @var{duration}
@end example
-where @code{duration} is the rhythmic length to be added before
-the next bar.
-
This is internally translated into
@example
@end example
The property @code{measurePosition} contains a rational number
-indicating how much of the measure has passed at this point. Note
-that this is a negative number; @code{\partial 4} is internally
-translated to mean ``there is a quarter note left in the bar''.
+indicating how much of the measure has passed at this point.
@refbugs
@subsection Bar lines
@cindex Bar lines
-@funindex \bar
+@findex \bar
@cindex measure lines
@cindex repeat bars
@noindent
This will insert an invisible bar line and allow line breaks at this
-point. This also increases the bar number counter.
+point.
In scores with many staves, a @code{\bar} command in one staff is
automatically applied to all staves. The resulting bar lines are
-connected between different staves of a @code{StaffGroup},
-@code{PianoStaff}, or @code{ChoirStaff}.
+connected between different staves of a StaffGroup
@lilypond[quote,ragged-right,fragment,verbatim]
<<
@commonprop
-@funindex whichBar
-@funindex repeatCommands
-@funindex defaultBarType
+@findex whichBar
+@findex repeatCommands
+@findex defaultBarType
The command @code{\bar }@var{bartype} is a short cut for doing
@code{\set Timing.whichBar = }@var{bartype}. Whenever @code{whichBar}
@subsection Unmetered music
@cindex cadenza
-@funindex \cadenzaOn
-@funindex \cadenzaOff
+@findex \cadenzaOn
+@findex \cadenzaOff
Bar lines and bar numbers are calculated automatically. For unmetered
music (cadenzas, for example), this is not desirable. To turn off
@refbugs
-LilyPond will only insert line breaks and page breaks at a
-barline. Unless the unmetered music ends before the end of
-the staff line, you will need to insert
+LilyPond will only insert page breaks at a barline. Unless the unmetered
+music ends before the end of the staff line, you will need to insert
invisible bar lines
@example
@end example
@noindent
-to indicate where breaks can occur.
+to indicate where line breaks can occur.
@node System start delimiters
@internalsref{SystemStartBar}, @internalsref{SystemStartBrace}, and
@internalsref{SystemStartBracket}. Only one of these types is created
in every context, and that type is determined by the property
-@internalsref{systemStartDelimiter}.
+@code{systemStartDelimiter}.
@node Staff symbol
Notes, dynamic signs, etc., are grouped
with a set of horizontal lines, called a staff (plural `staves'). In
LilyPond, these lines are drawn using a separate layout object called
-@code{staff symbol}.
+staff symbol.
The staff symbol may be tuned in the number, thickness and distance
of lines, using properties. This is demonstrated in the example files
@inputfileref{input/@/regression,staff@/-line@/-positions@/.ly}.
-@node Writing music in parallel
-@subsection Writing music in parallel
-
-@cindex Writing music in parallel
-@cindex Interleaved music
-
-Music for multiple parts can be interleaved
-
-@lilypond[quote,fragment,verbatim]
-\parallelMusic #'(voiceA voiceB) {
- r8 g'16[ c''] e''[ g' c'' e''] r8 g'16[ c''] e''[ g' c'' e''] |
- c'2 c'2 |
- r8 a'16[ d''] f''[ a' d'' f''] r8 a'16[ d''] f''[ a' d'' f''] |
- c'2 c'2 |
-}
-\new StaffGroup <<
- \new Staff \new Voice \voiceA
- \new Staff \new Voice \voiceB
->>
-@end lilypond
-
-
@node Connecting notes
@section Connecting notes
@subsection Ties
@cindex tie
-@funindex ~
+@findex ~
A tie connects two adjacent note heads of the same pitch. The tie in
effect extends the length of a note. Ties should not be confused with
@end lilypond
When a tie is applied to a chord, all note heads whose pitches match
-are connected. When no note heads match, no ties will be created. Chords
-may be partially tied by placing the tie inside the chord,
-
-@lilypond[quote,ragged-right,fragment,verbatim,relative=1]
-<c~ e g~ b> <c e g b>
-@end lilypond
+are connected. When no note heads match, no ties will be created.
A tie is just a way of extending a note duration, similar to the
augmentation dot. The following example shows two ways of notating
mechanism automatically splits long notes, and ties them across bar
lines.
-@funindex \repeatTie
-
When a second alternative of a repeat starts with a tied note, you
have to repeat the tie. This can be achieved with @code{\repeatTie},
\set tieWaitForNote = ##t
\grace { c16[~ e~ g]~ } <c, e g>2
\repeat "tremolo" 8 { c32~ c'~ } <c c,>1
-e8~ c~ a~ f~ <e' c a f>2
@end lilypond
@refcommands
-@funindex \tieUp
+@findex \tieUp
@code{\tieUp},
-@funindex \tieDown
+@findex \tieDown
@code{\tieDown},
-@funindex \tieNeutral
+@findex \tieNeutral
@code{\tieNeutral},
-@funindex \tieDotted
+@findex \tieDotted
@code{\tieDotted},
-@funindex \tieDashed
+@findex \tieDashed
@code{\tieDashed},
-@funindex \tieSolid
+@findex \tieSolid
@code{\tieSolid}.
Switching staves when a tie is active will not produce a slanted tie.
-Changing clefs or octavations during a tie is not really
-well-defined. In these cases, a slur may be preferable.
-
@node Slurs
@subsection Slurs
@refcommands
-@funindex \slurUp
+@findex \slurUp
@code{\slurUp},
-@funindex \slurDown
+@findex \slurDown
@code{\slurDown},
-@funindex \slurNeutral
+@findex \slurNeutral
@code{\slurNeutral},
-@funindex \slurDashed
+@findex \slurDashed
@code{\slurDashed},
-@funindex \slurDotted
+@findex \slurDotted
@code{\slurDotted},
-@funindex \slurSolid
+@findex \slurSolid
@code{\slurSolid}.
@seealso
@refcommands
-@funindex \phrasingSlurUp
+@findex \phrasingSlurUp
@code{\phrasingSlurUp},
-@funindex \phrasingSlurDown
+@findex \phrasingSlurDown
@code{\phrasingSlurDown},
-@funindex \phrasingSlurNeutral
+@findex \phrasingSlurNeutral
@code{\phrasingSlurNeutral}.
@subsection Manual beams
@cindex beams, manual
-@funindex ]
-@funindex [
+@findex ]
+@findex [
In some cases it may be necessary to override the automatic beaming
algorithm. For example, the autobeamer will not put beams over rests
@commonprop
-@funindex stemLeftBeamCount
-@funindex stemRightBeamCount
+@findex stemLeftBeamCount
+@findex stemRightBeamCount
Normally, beaming patterns within a beam are determined automatically.
If necessary, the properties @code{stemLeftBeamCount} and
\set Score.beatLength = #(ly:make-moment 1 8)
c16[ c c c c c c c]
@end lilypond
-@funindex subdivideBeams
+@findex subdivideBeams
@noindent
For more information about @code{make-moment}, see
Line breaks are normally forbidden when beams cross bar lines. This
behavior can be changed by setting @code{allowBeamBreak}.
-@funindex allowBeamBreak
+@findex allowBeamBreak
@cindex beams and line breaks
@cindex beams, kneed
@cindex kneed beams
@node Grace notes
@subsection Grace notes
-@funindex \grace
+@findex \grace
@cindex ornaments
@cindex grace notes
@cindex appoggiatura
\new Staff { c4 \grace { g8[ b] } c4 } >>
@end lilypond
-@funindex \afterGrace
+@findex \afterGrace
If you want to end a note with a grace, use the @code{\afterGrace}
command. It takes two arguments: the main note, and the grace notes
for example, to produce smaller type, and set directions. Hence, when
introducing layout tweaks, they should be inside the grace section,
for example,
-
@lilypond[quote,ragged-right,fragment,verbatim,relative=2]
\new Voice {
\acciaccatura {
The layout of grace sections can be changed throughout the music using
the function @code{add-grace-property}. The following example
-undefines the @code{Stem} direction for this grace, so
-that stems do not always point up.
+undefines the Stem direction for this grace, so stems do not always
+point up.
@example
\new Staff @{
The slash through the stem in acciaccaturas can be obtained
in other situations by @code{\override Stem #'stroke-style = #"grace"}.
-
-@commonprop
-
-Grace notes may be forced to use floating spacing,
-
-@lilypond[relative=2,ragged-right]
-<<
- \override Score.SpacingSpanner #'strict-grace-spacing = ##t
- \new Staff {
- c'4
- \afterGrace
- c'4
- { c'16[ c'8 c'16] }
- c'4
- }
- \new Staff {
- c'16[ c'16 c'16 c'16]
- c'16[ c'16 c'16 c'16]
- c'4
- }
->>
-@end lilypond
-
-
@seealso
Program reference: @internalsref{GraceMusic}.
* Trills::
* Glissando::
* Arpeggio::
-* Falls and doits::
@end menu
@subsection Dynamics
@cindex Dynamics
-@funindex \pppp
-@funindex \ppp
-@funindex \pp
-@funindex \p
-@funindex \mp
-@funindex \mf
-@funindex \f
-@funindex \ff
-@funindex \fff
-@funindex \ffff
-@funindex \fp
-@funindex \sf
-@funindex \sff
-@funindex \sp
-@funindex \spp
-@funindex \sfz
-@funindex \rfz
+@findex \pppp
+@findex \ppp
+@findex \pp
+@findex \p
+@findex \mp
+@findex \mf
+@findex \f
+@findex \ff
+@findex \fff
+@findex \ffff
+@findex \fp
+@findex \sf
+@findex \sff
+@findex \sp
+@findex \spp
+@findex \sfz
+@findex \rfz
Absolute dynamic marks are specified using a command after a note
@code{c4\ff}. The available dynamic marks are @code{\ppppp},
c2\fp c\sf c\sff c\sp c\spp c\sfz c\rfz
@end lilypond
-@funindex \<
-@funindex \>
-@funindex \!
+@findex \<
+@findex \>
+@findex \!
A crescendo mark is started with @code{\<} and terminated with
@code{\!} or an absolute dynamic. A decrescendo is started with
@noindent
A hairpin starts at the left edge of the beginning note and ends on the
-right edge of the ending note. This may be modified by setting
-the @code{hairpinToBarline} property,
-
-@lilypond[quote,ragged-right,fragment,verbatim,relative=2]
-\set hairpinToBarline = ##t
-c4\< c2. c4\!
-@end lilypond
+right edge of the ending note.
In some situations the @code{\espressivo} articulation mark may
be suitable to indicate a crescendo and decrescendo on the one note,
example
@example
-\override Voice.Hairpin #'minimum-length = #5
+\override Staff.Hairpin #'minimum-length = #5
@end example
-@cindex al niente
-@cindex niente, al
-
-Hairpins may be printed with a circled tip (al niente notation) by
-setting the @code{circled-tip} property,
-
-@lilypond[quote,ragged-right,fragment,relative=2,verbatim]
-\override Hairpin #'circled-tip = ##t
-c2\< c\!
-c4\> c\< c2\!
-@end lilypond
-
-
@cindex crescendo
@cindex decrescendo
@cindex diminuendo
-You can also use text saying @emph{cresc.} instead of hairpins
+You can also use a text saying @emph{cresc.} instead of hairpins
@lilypond[quote,ragged-right,fragment,relative=2,verbatim]
\setTextCresc
\override Score.Hairpin #'after-line-breaking = ##t
@end example
-Text style dynamic changes (such as @emph{cresc.} and @emph{dim.})
-are printed with a
+Text style dynamic changes (such as cresc. and dim.) are printed with a
dashed line showing their extent. To surpress printing this line, use
@example
@refcommands
-@funindex \dynamicUp
+@findex \dynamicUp
@code{\dynamicUp},
-@funindex \dynamicDown
+@findex \dynamicDown
@code{\dynamicDown},
-@funindex \dynamicNeutral
+@findex \dynamicNeutral
@code{\dynamicNeutral}.
Trills that should be executed on an explicitly specified pitch can be
typeset with the command @code{pitchedTrill},
-@lilypond[ragged-right,verbatim,fragment,relative=1,quote]
+@lilypond[ragged-right,verbatim,fragment,relative=1]
\pitchedTrill c4\startTrillSpan fis
f\stopTrillSpan
@end lilypond
@refcommands
@code{\startTrillSpan},
-@funindex \startTrillSpan
+@findex \startTrillSpan
@code{\stopTrillSpan}.
-@funindex \stopTrillSpan
+@findex \stopTrillSpan
@seealso
@subsection Glissando
@cindex Glissando
-@funindex \glissando
+@findex \glissando
A glissando is a smooth change in pitch. It is denoted by a line or a
wavy line between two notes. It is requested by attaching
@cindex Arpeggio
@cindex broken chord
-@funindex \arpeggio
+@findex \arpeggio
You can specify an arpeggio sign (also known as broken chord) on a
chord by attaching an @code{\arpeggio} to a chord
@refcommands
@code{\arpeggio},
-@funindex \arpeggioUp
+@findex \arpeggioUp
@code{\arpeggioUp},
-@funindex \arpeggioDown
+@findex \arpeggioDown
@code{\arpeggioDown},
-@funindex \arpeggioNeutral
+@findex \arpeggioNeutral
@code{\arpeggioNeutral},
-@funindex \arpeggioBracket
+@findex \arpeggioBracket
@code{\arpeggioBracket}.
arpeggios in one @internalsref{PianoStaff} at the same point in time.
-@node Falls and doits
-@subsection Falls and doits
-Falls and doits can be added to notes using the @code{\bendAfter}
-command,
-
-@lilypond[fragment,ragged-right,relative=2]
-\override Score.SpacingSpanner #'shortest-duration-space = #3.0
-c4-\bendAfter #+5
-c4-\bendAfter #-3
-@end lilypond
@node Repeats
@subsection Repeat types
@cindex repeats
-@funindex \repeat
+@findex \repeat
The following types of repetition are supported
@item percent
Make beat or measure repeats. These look like percent signs. These
are not played in MIDI output by default. Percent repeats must be
-declared within a @code{Voice} context.
+declared within a Voice context.
@end table
@end example
If you have alternative endings, you may add
-@funindex \alternative
+@findex \alternative
@example
\alternative @{
@var{alternative1}
\alternative { {d2 d} {f f,} }
@end lilypond
-In the following example, the first ending is not a complete
-bar (it only had 3 beats). The beginning of the second ending
+In this example, the first ending is not a complete bar (it
+only had 3 beats). The beginning of the second ending
contains the 4th beat from the first ending. This ``extra''
beat in the second ending is due to the first time ending,
and has nothing to do with the @code{\partial} at the
}
@end lilypond
-@funindex \repeatTie
-
-Ties may be added to a second ending,
-
-@lilypond[quote,ragged-right,fragment,verbatim,relative=2]
-c1
-\repeat volta 2 {c4 d e f ~ }
-\alternative { {f2 d} {f\repeatTie f,} }
-@end lilypond
-
It is possible to shorten volta brackets
by setting @code{voltaSpannerDuration}. In the next example, the
bracket only lasts one measure, which is a duration of 3/4.
For clarity, it is advisable to use braces in such situations.
Timing information is not remembered at the start of an alternative,
-so after a repeat timing information must be reset by hand; for
-example, by setting @code{Score.measurePosition} or entering
+so after a repeat timing information must be reset by hand, for
+example by setting @code{Score.measurePosition} or entering
@code{\partial}. Similarly, slurs or ties are also not repeated.
@subsection Repeats and MIDI
@cindex expanding repeats
-@funindex \unfoldRepeats
+@findex \unfoldRepeats
With a little bit of tweaking, all types of repeats can be present
in the MIDI output. This is achieved by applying the
-@code{\unfoldRepeats} music function. This function changes all
+@code{\unfoldRepeats} music function. This functions changes all
repeats to unfold repeats.
@lilypond[quote,verbatim,fragment,line-width=8.0\cm]
\bar "|."
@end lilypond
-When creating a score file using @code{\unfoldRepeats} for MIDI,
-it is necessary to make two @code{\score} blocks: one for MIDI (with
+When creating a score file using @code{\unfoldRepeats} for midi, then
+it is necessary to make two @code{\score} blocks. One for MIDI (with
unfolded repeats) and one for notation (with volta, tremolo, and
percent repeats). For example,
@node Manual repeat commands
@subsection Manual repeat commands
-@funindex repeatCommands
+@findex repeatCommands
The property @code{repeatCommands} can be used to control the layout of
repeats. Its value is a Scheme list of repeat commands.
@subsection Tremolo subdivisions
@cindex tremolo marks
-@funindex tremoloFlags
+@findex tremoloFlags
Tremolo marks can be printed on a single note by adding
`@code{:}[@var{number}]' after the note. The number indicates the
-Isolated percents can also be printed. This is done by putting a
-multi-measure rest with a different print function,
+Isolated percents can also be printed. This is done by putting a multi
+measure rest with a different print function,
-@lilypond[fragment,verbatim,quote]
+@lilypond[fragment,verbatim]
\override MultiMeasureRest #'stencil
= #ly:multi-measure-rest::percent
R1
notation. For example, giving each staff a separate time signature.
@item
-Page layout: changing the appearance of the spacing, line
+Global layout: changing the appearance of the spacing, line
breaks, and page dimensions. These modifications are discussed
-in @ref{Non-musical notation} and @ref{Spacing issues}.
+in @ref{Global issues}.
@end itemize
Internally, LilyPond uses Scheme (a LISP dialect) to provide
Common rules for typesetting accidentals have been placed in a
function. This function is called as follows
-@funindex set-accidental-style
+@findex set-accidental-style
@example
#(set-accidental-style 'STYLE #('CONTEXT#))
@end example
should be used instead.
@item modern
-@funindex modern style accidentals
+@findex modern style accidentals
This rule corresponds to the common practice in the 20th century. This rule
prints the same accidentals as @code{default}, but temporary
accidentals also are canceled in other octaves. Furthermore,
@end lilypond
@item @code{modern-cautionary}
-@funindex modern-cautionary
+@findex modern-cautionary
This rule is similar to @code{modern}, but the ``extra'' accidentals
(the ones not typeset by @code{default}) are typeset as cautionary
accidentals. They are printed in reduced size or with parentheses
cis' c'' cis'2 | c'' c'
@end lilypond
-@funindex modern-voice
+@findex modern-voice
@item modern-voice
This rule is used for multivoice accidentals to be read both by musicians
playing one voice and musicians playing all voices. Accidentals are
typeset for each voice, but they @emph{are} canceled across voices in
the same @internalsref{Staff}.
-@funindex modern-voice-cautionary
+@findex modern-voice-cautionary
@item modern-voice-cautionary
This rule is the same as @code{modern-voice}, but with the extra
accidentals (the ones not typeset by @code{voice}) typeset
some of them are typeset as cautionaries.
@item piano
-@funindex piano accidentals
+@findex piano accidentals
This rule reflects 20th century practice for piano notation. Very similar to
@code{modern} but accidentals also get canceled
across the staves in the same @internalsref{GrandStaff} or
@internalsref{PianoStaff}.
@item piano-cautionary
-@funindex #(set-accidental-style 'piano-cautionary)
+@findex #(set-accidental-style 'piano-cautionary)
Same as @code{#(set-accidental-style 'piano)} but with the extra
accidentals typeset as cautionaries.
@item no-reset
-@funindex no-reset accidental style
+@findex no-reset accidental style
This is the same as @code{default} but with accidentals lasting
``forever'' and not only until the next measure
@lilypond[quote,ragged-right,fragment,verbatim,relative=1]
@node Setting automatic beam behavior
@subsection Setting automatic beam behavior
-@funindex autoBeamSettings
-@funindex (end * * * *)
-@funindex (begin * * * *)
+@findex autoBeamSettings
+@findex (end * * * *)
+@findex (begin * * * *)
@cindex automatic beams, tuning
@cindex tuning automatic beaming
3/8 and on the fourth beat of the measure (after 3/4, that is 2 times
3/8, has passed within the measure).
-If any unexpected beam behaviour occurs, check the default automatic beam
-settings in @file{scm/@/auto@/-beam@/.scm}
-for possible interference, because the beam
-endings defined there will still apply on top of your own overrides. Any
-unwanted endings in the default vales must be reverted for your time
-signature(s).
-
-For example, to typeset @code{(3 4 3 2)}-beam endings in 12/8, begin
-with
-
-@example
-%%% revert default values in scm/auto-beam.scm regarding 12/8 time
-#(revert-auto-beam-setting '(end * * 12 8) 3 8)
-#(revert-auto-beam-setting '(end * * 12 8) 3 4)
-#(revert-auto-beam-setting '(end * * 12 8) 9 8)
-
-%%% your new values
-#(override-auto-beam-setting '(end 1 8 12 8) 3 8)
-#(override-auto-beam-setting '(end 1 8 12 8) 7 8)
-#(override-auto-beam-setting '(end 1 8 12 8) 10 8)
-@end example
-
@cindex automatic beam generation
@cindex autobeam
-@funindex autoBeaming
+@findex autoBeaming
@cindex lyrics
If beams are used to indicate melismata in songs, then automatic
@refcommands
-@funindex \autoBeamOff
+@findex \autoBeamOff
@code{\autoBeamOff},
-@funindex \autoBeamOn
+@findex \autoBeamOn
@code{\autoBeamOn}.
-@commonprop
-
-Beaming patterns may be altered with the @code{beatGrouping} property,
-
-@lilypond[quote,verbatim,relative=2,fragment,ragged-right]
-\time 5/16
-\set beatGrouping = #'(2 3)
-c8[^"(2+3)" c16 c8]
-\set beatGrouping = #'(3 2)
-c8[^"(3+2)" c16 c8]
-@end lilypond
-
@refbugs
The easiest command is @code{\new}, and it also the quickest to type.
It is prepended to a music expression, for example
-@funindex \new
+@findex \new
@cindex new contexts
@cindex Context, creating
context already earlier with the same name.
-@funindex \context
+@findex \context
@item
Like @code{\new}, the @code{\context} command also directs a music
@subsection Changing context properties on the fly
@cindex properties
-@funindex \set
+@findex \set
@cindex changing properties
Each context can have different @emph{properties}, variables contained
`on-the-fly', during the music, so that the setting only affects the
second group of eighth notes.
-@funindex \unset
+@findex \unset
There is also an @code{\unset} command,
@example
starting a new context with @code{\new} or @code{\context}, and
modifying it,
-@funindex \with
+@findex \with
@example
\new @var{context} \with @{
@}
@end example
-@funindex \accepts
+@findex \accepts
Contexts form hierarchies. We want to hang the @context{ImproVoice}
under @context{Staff}, just like normal @code{Voice}s. Therefore, we
modify the @code{Staff} definition with the @code{\accepts}
@}
@end example
-@funindex \denies
+@findex \denies
The opposite of @code{\accepts} is @code{\denies},
which is sometimes needed when reusing existing context definitions.
@cindex finding graphical objects
@cindex graphical object descriptions
@cindex tweaking
-@funindex \override
+@findex \override
@cindex internal documentation
We demonstrate how to glean this information from the notation manual
@node Objects connected to the input
@subsection Objects connected to the input
-@funindex \tweak
+@findex \tweak
In some cases, it is possible to take a short-cut for tuning graphical
objects. For objects that result directly from a piece of the input,
The value of @code{context} (the alist) is used to initalize
the properties of individual grobs. Grobs also have
-properties, named in Scheme style, with
+properties, named in scheme style, with
@code{dashed-words}. The values of grob properties change
during the formatting process: formatting basically amounts
to computing properties using callback functions.
+++ /dev/null
-%future
-%
-
-There are a few things that the convert-ly cannot handle. Here's a list of limitations
-that the community has complained about.
-
-This bug report structure has been chosen because convert-ly has a structure that doesn't
-allow to smoothly implement all needed changes. Thus this is just a wishlist, placed
-here for reference.
-
-1.6->2.0:
- Doesn't always convert figured bass correctly, specifically things like {< >}. Mats' comment on working around this:
- To be able to run convert-ly
- on it, I first replaced all occurencies of '{<' to some dummy like '{#'
- and similarly I replaced '>}' with '&}'. After the conversion, I could
- then change back from '{ #' to '{ <' and from '& }' to '> }'.
- Doesn't convert all text markup correctly. In the old markup syntax,
- it was possible to group a number of markup commands together within parentheses, e.g.
- -#'((bold italic) "string")
- This will incorrectly be converted into
- -\markup{{\bold italic} "string"}
- instead of the correct
- -\markup{\bold \italic "string"}
-2.0->2.2:
- Doesn't handle \partcombine
- Doesn't do \addlyrics => \lyricsto, this breaks some scores with multiple stanzas.
-2.0->2.4:
- \magnify isn't changed to \fontsize.
- - \magnify #m => \fontsize #f, where f = 6ln(m)/ln(2)
- remove-tag isn't changed.
- - \applymusic #(remove-tag '. . .) => \keepWithTag #'. . .
- firstpagenumber isn't changed.
- - firstpagenumber no => printfirstpagenumber = ##f
- Line breaks in header strings aren't converted.
- - \\\\ as line break in \header strings => \markup \center-align <
- "First Line" "Second Line" >
- Crescendo and decrescendo terminators aren't converted.
- - \rced => \!
- - \rc => \!
-2.2->2.4:
- \turnOff (used in \set Staff.VoltaBracket = \turnOff) is not properly converted.
-2.4.2->2.5.9
- \markup{ \center-align <{ ... }> } should be converted to:
- \markup{ \center-align {\line { ... }} }
- but now, \line is missing.
-2.4->2.6
- Special LaTeX characters such as $~$ in text are not converted to UTF8.
line in the operating system. Windows users
might be more familiar with the terms ``DOS shell'' or
``command shell''; OSX users might be more familiar with the
-terms ``terminal'' or ``console''. OSX users should also
-consult @ref{Notes for the MacOS X app}.
-
-Describing how to use
+terms ``terminal'' or ``console''. Describing how to use
this part of an operating system is outside the scope of this
manual; please consult other documentation on this topic if
you are unfamiliar with the command-line.
add notes, and you're finished!
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' {
\clef treble
\key c \major
\score {
\new Staff \melody
\layout { }
- \midi {}
+ \midi { \tempo 4=60 }
}
@end lilypond
line.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' {
\clef treble
\key c \major
\new Lyrics \lyricsto "one" \text
>>
\layout { }
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
Want to prepare a lead sheet with a melody and chords? Look no further!
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' {
\clef treble
\key c \major
>>
\layout{ }
- \midi { }
+ \midi { \tempo 4=60}
}
@end lilypond
This template allows you to prepare a song with melody, words, and chords.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' {
\clef treble
\key c \major
\new Lyrics \lyricsto "one" \text
>>
\layout { }
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
Here is a simple piano staff.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
upper = \relative c'' {
\clef treble
\key c \major
\score {
\new PianoStaff <<
- \set PianoStaff.instrumentName = "Piano "
+ \set PianoStaff.instrument = "Piano "
\new Staff = "upper" \upper
\new Staff = "lower" \lower
>>
\layout { }
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
piano accompaniment underneath.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c'' {
\clef treble
\key c \major
\layout {
\context { \RemoveEmptyStaffContext }
}
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
the lyrics between the piano staff (and omit the separate melody staff).
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
upper = \relative c'' {
\clef treble
\key c \major
\context { \GrandStaff \accepts "Lyrics" }
\context { \Lyrics \consists "Bar_engraver" }
}
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
tweaking yourself.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
upper = \relative c'' {
\clef treble
\key c \major
section for time and key signatures.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
global= {
\time 4/4
}
violinOne = \new Voice { \relative c''{
- \set Staff.instrumentName = "Violin 1 "
+ \set Staff.instrument = "Violin 1 "
c2 d e1
\bar "|." }}
violinTwo = \new Voice { \relative c''{
- \set Staff.instrumentName = "Violin 2 "
+ \set Staff.instrument = "Violin 2 "
g2 f e1
\bar "|." }}
viola = \new Voice { \relative c' {
- \set Staff.instrumentName = "Viola "
+ \set Staff.instrument = "Viola "
\clef alto
e2 d c1
\bar "|." }}
cello = \new Voice { \relative c' {
- \set Staff.instrumentName = "Cello "
+ \set Staff.instrument = "Cello "
\clef bass
c2 b a1
\new Staff << \global \cello >>
>>
\layout { }
- \midi { }
+ \midi { \tempo 4=60}
}
@end lilypond
@verbatim
%%%%% piece.ly
-\version "2.9.13"
+\version "2.7.39"
global= {
\time 4/4
}
Violinone = \new Voice { \relative c''{
- \set Staff.instrumentName = "Violin 1 "
+ \set Staff.instrument = "Violin 1 "
c2 d e1
\bar "|." }} %*********************************
Violintwo = \new Voice { \relative c''{
- \set Staff.instrumentName = "Violin 2 "
+ \set Staff.instrument = "Violin 2 "
g2 f e1
\bar "|." }} %*********************************
Viola = \new Voice { \relative c' {
- \set Staff.instrumentName = "Viola "
+ \set Staff.instrument = "Viola "
\clef alto
e2 d c1
\bar "|." }} %*********************************
Cello = \new Voice { \relative c' {
- \set Staff.instrumentName = "Cello "
+ \set Staff.instrument = "Cello "
\clef bass
c2 b a1
%%%%% score.ly
-\version "2.9.13"
+\version "2.7.39"
\include "piece.ly"
#(set-global-staff-size 14)
\score {
\new StaffGroup \keepWithTag #'score \music
\layout { }
- \midi { }
+ \midi { \tempo 4 = 60 }
}
%%%%% vn1.ly
-\version "2.9.13"
+\version "2.7.39"
\include "piece.ly"
\score {
\keepWithTag #'vn1 \music
%%%%% vn2.ly
-\version "2.9.13"
+\version "2.7.39"
\include "piece.ly"
\score {
\keepWithTag #'vn2 \music
%%%%% vla.ly
-\version "2.9.13"
+\version "2.7.39"
\include "piece.ly"
\score {
\keepWithTag #'vla \music
%%%%% vlc.ly
-\version "2.9.13"
+\version "2.7.39"
\include "piece.ly"
\score {
\keepWithTag #'vlc \music
always the same for all parts.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
global = {
\key c \major
\time 4/4
apply to the piano reduction.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
global = {
\key c \major
\time 4/4
staves rather than on the staves.
@lilypond[quote,verbatim,line-width=11.0\cm]
-\version "2.9.13"
+\version "2.7.39"
global = {
\set Score.skipBars = ##t
discantusNotes = {
\transpose c' c'' {
- \set Staff.instrumentName = "Discantus "
+ \set Staff.instrument = "Discantus "
% incipit
\clef "neomensural-c1"
altusNotes = {
\transpose c' c'' {
- \set Staff.instrumentName = "Altus "
+ \set Staff.instrument = "Altus "
% incipit
\clef "neomensural-c3"
tenorNotes = {
\transpose c' c' {
- \set Staff.instrumentName = "Tenor "
+ \set Staff.instrument = "Tenor "
% incipit
\clef "neomensural-c4"
bassusNotes = {
\transpose c' c' {
- \set Staff.instrumentName = "Bassus "
+ \set Staff.instrument = "Bassus "
% incipit
\clef "bass"
@lilypond[quote,verbatim,ragged-right]
\include "gregorian-init.ly"
-\version "2.9.13"
+\version "2.8.0"
chant = \relative c' {
\set Score.timing = ##f
@c The `line-width' argument is for the \header.
@lilypond[quote,verbatim,ragged-right,line-width]
-\version "2.9.13"
+\version "2.7.39"
\header {
title = "Song"
subtitle = "(tune)"
}
trumpet = {
\global
- \set Staff.instrumentName = #"Trumpet"
+ \set Staff.instrument = #"Trumpet"
\clef treble
<<
\trpt
}
altosax = {
\global
- \set Staff.instrumentName = #"Alto Sax"
+ \set Staff.instrument = #"Alto Sax"
\clef treble
<<
\alto
}
barisax = {
\global
- \set Staff.instrumentName = #"Bari Sax"
+ \set Staff.instrument = #"Bari Sax"
\clef treble
<<
\bari
}
trombone = {
\global
- \set Staff.instrumentName = #"Trombone"
+ \set Staff.instrument = #"Trombone"
\clef bass
<<
\tbone
}
guitar = {
\global
- \set Staff.instrumentName = #"Guitar"
+ \set Staff.instrument = #"Guitar"
\clef treble
<<
\gtr
piano = {
<<
- \set PianoStaff.instrumentName = #"Piano"
+ \set PianoStaff.instrument = #"Piano"
\new Staff = "upper" \PianoRH
\new Staff = "lower" \PianoLH
>>
}
bass = {
\global
- \set Staff.instrumentName = #"Bass"
+ \set Staff.instrument = #"Bass"
\clef bass
<<
\Bass
drumContents = {
\global
<<
- \set DrumStaff.instrumentName = #"Drums"
+ \set DrumStaff.instrument = #"Drums"
\new DrumVoice { \voiceOne \up }
\new DrumVoice { \voiceTwo \down }
>>
}
}
- \midi { }
+ \midi { \tempo 4 = 75 }
}
@end lilypond
@ The `line-width' is for \header.
@li lypond[quote,verbatim,ragged-right,line-width]
-\version "2.9.13"
+\version "2.7.39"
\header {
dedication = "dedication"
title = "Title"
@c M-x texinfo-all-menus-update
@c to automatically fill in these menus before saving changes
-@node Non-musical notation
-@chapter Non-musical notation
+@node Global issues
+@chapter Global issues
This section deals with general lilypond issues, rather than
specific notation.
@menu
* Input files::
+* A single music expression::
* Titles and headers::
+* Paper and pages::
+* Music layout::
+* Multiple movements::
* MIDI output::
* Displaying LilyPond notation::
-* Skipping corrected music::
+* Other::
@end menu
@menu
* File structure (introduction)::
-* Multiple scores in a book::
* File structure::
-* A single music expression::
* Including LilyPond files::
* Text encoding::
@end menu
A basic example of a lilypond input file is
@example
-\version "2.9.13"
+\version "2.8.0"
\score @{
@{ @} % this is a single music expression;
% all the music goes in here.
them all.
-@node Multiple scores in a book
-@subsection Multiple scores in a book
-
-@funindex \book
-@cindex movements, multiple
-
-A document may contain multiple pieces of music and texts. Examples
-of these are an etude book, or an orchestral part with multiple
-movements. Each movement is entered with a @code{\score} block,
-
-@example
-\score @{
- @var{..music..}
-@}
-@end example
-
-and texts are entered with a @code{\markup} block,
-
-@example
-\markup @{
- @var{..text..}
-@}
-@end example
-
-@funindex \book
-
-The movements and texts are combined together in a @code{\book} block,
-like
-
-@example
-\book @{
- \score @{
- @var{..}
- @}
- \markup @{
- @var{..}
- @}
- \score @{
- @var{..}
- @}
-@}
-@end example
-
-
-The header for each piece of music can be put inside the @code{\score}
-block. The @code{piece} name from the header will be printed before
-each movement. The title for the entire book can be put inside the
-@code{\book}, but if it is not present, the @code{\header} which is at
-the top of the file is inserted.
-
-@example
-\book @{
- \header @{
- title = "Eight miniatures"
- composer = "Igor Stravinsky"
- @}
- \score @{
- @dots{}
- \header @{ piece = "Romanze" @}
- @}
- \markup @{
- ..text of second verse..
- @}
- \markup @{
- ..text of third verse..
- @}
- \score @{
- @dots{}
- \header @{ piece = "Menuetto" @}
- @}
-@}
-@end example
-
-
-
@node File structure
@subsection File structure
@end itemize
-@node A single music expression
-@subsection A single music expression
-
-A @code{\score} must contain a single music expression. However,
-this music expression may be of any size. Recall that music
-expressions may be included inside other expressions to form
-larger expressions. All of these examples are single music
-expressions; note the curly braces @{ @} or angle brackets <<
->> at the beginning and ending of the music.
-
-@example
-@{ c'4 c' c' c' @}
-@end example
-
-@lilypond[ragged-right,verbatim,quote]
-{
- { c'4 c' c' c'}
- { d'4 d' d' d'}
-}
-@end lilypond
-
-@lilypond[ragged-right,verbatim,quote]
-<<
- \new Staff { c'4 c' c' c' }
- \new Staff { d'4 d' d' d' }
->>
-@end lilypond
-
-@example
-@{
- \new GrandStaff <<
- \new StaffGroup <<
- \new Staff @{ \flute @}
- \new Staff @{ \oboe @}
- >>
- \new StaffGroup <<
- \new Staff @{ \violinI @}
- \new Staff @{ \violinII @}
- >>
- >>
-@}
-@end example
-
-
@node Including LilyPond files
@subsection Including LilyPond files
-@funindex \include
+@findex \include
@cindex including files
A large project may be split up into separate files. To refer to another
+@node A single music expression
+@section A single music expression
+
+A @code{\score} must contain a single music expression. However,
+this music expression may be of any size. Recall that music
+expressions may be included inside other expressions to form
+larger expressions. All of these examples are single music
+expressions; note the curly braces @{ @} or angle brackets <<
+>> at the beginning and ending of the music.
+
+@example
+@{ c'4 c' c' c' @}
+@end example
+
+@lilypond[ragged-right,verbatim,quote]
+{
+ { c'4 c' c' c'}
+ { d'4 d' d' d'}
+}
+@end lilypond
+
+@lilypond[ragged-right,verbatim,quote]
+<<
+ \new Staff { c'4 c' c' c' }
+ \new Staff { d'4 d' d' d' }
+>>
+@end lilypond
+
+@example
+@{
+ \new GrandStaff <<
+ \new StaffGroup <<
+ \new Staff @{ \flute @}
+ \new Staff @{ \oboe @}
+ >>
+ \new StaffGroup <<
+ \new Staff @{ \violinI @}
+ \new Staff @{ \violinII @}
+ >>
+ >>
+@}
+@end example
+
+
@node Titles and headers
@section Titles and headers
The contents of the titles are taken from the @code{\header} blocks.
The header block for a book supports the following
-
-
@table @code
-@funindex dedication
@item dedication
The dedicatee of the music, centered at the top of the first page.
-@funindex title
@item title
The title of the music, centered just below the dedication.
-@funindex subtitle
@item subtitle
Subtitle, centered below the title.
-@funindex subsubtitle
@item subsubtitle
Subsubtitle, centered below the subtitle.
-@funindex poet
@item poet
Name of the poet, flush-left below the subtitle.
-@funindex composer
@item composer
Name of the composer, flush-right below the subtitle.
-@funindex meter
@item meter
Meter string, flush-left below the poet.
-@funindex opus
@item opus
Name of the opus, flush-right below the composer.
-@funindex arranger
@item arranger
Name of the arranger, flush-right below the opus.
-@funindex instrument
@item instrument
Name of the instrument, centered below the arranger. Also
centered at the top of pages (other than the first page).
-@funindex piece
@item piece
Name of the piece, flush-left below the instrument.
@cindex page breaks, forcing
-@funindex breakbefore
@item breakbefore
This forces the title to start on a new page (set to ##t or ##f).
-@funindex copyright
@item copyright
Copyright notice, centered at the bottom of the first page. To
insert the copyright symbol, see @ref{Text encoding}.
-@funindex tagline
@item tagline
Centered at the bottom of the last page.
}
@end lilypond
-@funindex printallheaders
+@findex printallheaders
@noindent
You may change this behavior (and print all the headers when defining
@code{\header} inside @code{\score}) by using
@}
@end example
-@cindex copyright
-@cindex tagline
-
-The default footer is empty, except for the first page, where the
-@code{copyright} field from @code{\header} is inserted, and the last
-page, where @code{tagline} from @code{\header} is added. The default
-tagline is ``Music engraving by LilyPond (@var{version})''.@footnote{Nicely
-printed parts are good PR for us, so please leave the tagline if you
-can.}
-
-Headers may be completely removed by setting them to false.
-
-@example
-\header @{
- tagline = ##f
- composer = ##f
-@}
-@end example
-
@node Custom titles
@subsection Custom titles
@file{ly/titling-init.ly} lists the default layout.
@table @code
-@funindex bookTitleMarkup
+@findex bookTitleMarkup
@item bookTitleMarkup
This is the title put over an entire @code{\book} block. Typically,
it has the composer and the title of the piece
-@funindex scoreTitleMarkup
+@findex scoreTitleMarkup
@item scoreTitleMarkup
This is the title put over a @code{\score} block within a
@code{\book}. Typically, it has the name of the movement (@code{piece}
field).
-@funindex oddHeaderMarkup
+@findex oddHeaderMarkup
@item oddHeaderMarkup
This is the page header for odd-numbered pages.
-@funindex evenHeaderMarkup
+@findex evenHeaderMarkup
@item evenHeaderMarkup
This is the page header for even-numbered pages. If unspecified,
the odd header is used instead.
By default, headers are defined such that the page number is on the
outside edge, and the instrument is centered.
-@funindex oddFooterMarkup
+@findex oddFooterMarkup
@item oddFooterMarkup
This is the page footer for odd-numbered pages.
-@funindex evenFotterMarkup
+@findex evenFotterMarkup
@item evenFooterMarkup
This is the page footer for even-numbered pages. If unspecified,
the odd header is used instead.
-@node MIDI output
-@section MIDI output
-
-@cindex Sound
-@cindex MIDI
-
-MIDI (Musical Instrument Digital Interface) is a standard for
-connecting and controlling digital instruments. A MIDI file is a
-series of notes in a number of tracks. It is not an actual
-sound file; you need special software to translate between the
-series of notes and actual sounds.
-
-Pieces of music can be converted to MIDI files, so you can listen to
-what was entered. This is convenient for checking the music; octaves
-that are off or accidentals that were mistyped stand out very much
-when listening to the MIDI output.
-
-@refbugs
-
-Many musically interesting effects, such as swing, articulation,
-slurring, etc., are not translated to midi.
-
-The midi output allocates a channel for each staff, and one for global
-settings. Therefore the midi file should not have more than 15 staves
-(or 14 if you do not use drums). Other staves will remain silent.
+@node Paper and pages
+@section Paper and pages
-Not all midi players correctly handle tempo changes in the midi
-output. Players that are known to work include
-@uref{http://@/timidity@/.sourceforge@/.net/,timidity}.
+This section deals with the display of music on physical paper.
@menu
-* Creating MIDI files::
-* MIDI block::
-* MIDI instrument names::
+* Paper size::
+* Page formatting::
@end menu
-@node Creating MIDI files
-@subsection Creating MIDI files
-To create a MIDI from a music piece of music, add a @code{\midi} block
-to a score, for example,
+@node Paper size
+@subsection Paper size
+@cindex paper size
+@cindex page size
+@findex papersize
+
+To change the paper size, there are two commands,
@example
-\score @{
- @var{...music...}
- \midi @{ @}
+#(set-default-paper-size "a4")
+\paper @{
+ #(set-paper-size "a4")
@}
@end example
-FIXME
+The first command sets the size of all pages. The second command sets the
+size
+of the pages that the @code{\paper} block applies to -- if the @code{\paper}
+block is at the top of the file, then it will apply to all pages. If the
+@code{\paper} block is inside a @code{\book}, then the paper size will only
+apply to that book.
-The tempo is specified using the @code{\tempo} command. In this
-example the tempo of quarter notes is set to 72 beats per minute.
+Support for the following paper sizes are included by default,
+@code{a6}, @code{a5}, @code{a4}, @code{a3}, @code{legal}, @code{letter},
+@code{11x17} (also known as tabloid).
+Extra sizes may be added by editing the definition for
+@code{paper-alist} in the initialization file @file{scm/paper.scm}.
-If there is a @code{\midi} command in a @code{\score}, only MIDI will
-be produced. When notation is needed too, a @code{\layout} block must
-be added
+@cindex orientation
+@cindex landscape
+
+If the symbol @code{landscape} is supplied as an argument to
+@code{set-default-paper-size}, the pages will be rotated by 90 degrees,
+and wider line widths will be set correspondingly.
@example
-\score @{
- @var{...music...}
- \midi @{ @}
- \layout @{ @}
-@}
+#(set-default-paper-size "a6" 'landscape)
@end example
-@cindex layout block
+Setting the paper size will adjust a number of @code{\paper} variables
+(such as margins). To use a particular paper size with altered
+@code{\paper} variables, set the paper size before setting the variables.
-Ties, dynamics, and tempo changes are interpreted. 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 volume vary linearly between
-their two extremes. The fractions can be adjusted by
-@code{dynamicAbsoluteVolumeFunction} in @internalsref{Voice} context.
-For each type of MIDI instrument, a volume range can be defined. This
-gives a basic equalizer control, which can enhance the quality of
-the MIDI output remarkably. The equalizer can be controlled by
-setting @code{instrumentEqualizer}, or by setting
+@node Page formatting
+@subsection Page formatting
-@example
-\set Staff.midiMinimumVolume = #0.2
-\set Staff.midiMaximumVolume = #0.8
-@end example
+@cindex page formatting
+@cindex margins
+@cindex header, page
+@cindex footer, page
-To remove dynamics from the MIDI output, insert the following lines
-in the @code{\midi@{@}} section.
+LilyPond will do page layout, set margins, and add headers and
+footers to each page.
+
+@findex annotate-spacing
+@cindex Spacing, display of properties
+
+To graphically display the dimensions of properties that may
+be altered for page formatting, use
@example
-\midi @{
- ...
- \context @{
- \Voice
- \remove "Dynamic_performer"
- \remove "Span_dynamic_performer"
- @}
+\paper @{
+ annotate-spacing = ##t
@}
@end example
+@noindent
+All units dimensions are measured in staff spaces. The pairs
+(@var{a},@var{b}) are intervals, where @var{a} is the lower edge and
+@var{b} the upper edge of the interval.
-@refbugs
+The default layout responds to the following settings in the
+@code{\paper} block.
-Unterminated (de)crescendos will not render properly in the midi file,
-resulting in silent passages of music. The workaround is to explicitly
+@findex \paper
+
+@quotation
+@table @code
+@findex first-page-number
+@item first-page-number
+The value of the page number of the first page. Default is@tie{}1.
+
+@findex printfirst-page-number
+@item printfirst-page-number
+If set to true, will print the page number in the first page. Default is
+false.
+
+@findex print-page-number
+@item print-page-number
+If set to false, page numbers will not be printed.
+
+@findex paper-width
+@item paper-width
+The width of the page.
+
+@findex paper-height
+@item paper-height
+The height of the page.
+
+@findex top-margin
+@item top-margin
+Margin between header and top of the page.
+
+@findex bottom-margin
+@item bottom-margin
+Margin between footer and bottom of the page.
+
+@findex left-margin
+@item left-margin
+Margin between the left side of the page and the beginning of the music.
+
+@findex line-width
+@item line-width
+The length of the systems.
+
+@findex head-separation
+@item head-separation
+Distance between the top-most music system and the page header.
+
+@findex foot-separation
+@item foot-separation
+Distance between the bottom-most music system and the page footer.
+
+@findex page-top-space
+Distance from the top of the printable area to the center of the first
+staff. This only works for staves which are vertically small. Big staves
+are set with the top of their bounding box aligned to the top of the
+printable area.
+
+@findex ragged-bottom
+@item ragged-bottom
+If set to true, systems will not be spread vertically across the page. This
+does not affect the last page.
+
+This should be set to true for pieces that have only two or three
+systems per page, for example orchestral scores.
+
+@findex ragged-last-bottom
+@item ragged-last-bottom
+If set to false, systems will be spread vertically to fill the last page.
+
+Pieces that amply fill two pages or more should have this set to
+true.
+
+@findex system-count
+@item system-count
+This variable, if set, specifies into how many lines a score should be
+broken.
+
+@findex between-system-space
+@item between-system-space
+This dimensions determines the distance between systems. It is the
+ideal distance between the center of the bottom staff of one system
+and the center of the top staff of the next system.
+
+Increasing this will provide a more even appearance of the page at the
+cost of using more vertical space.
+
+@findex between-system-padding
+@item between-system-padding
+This dimension is the minimum amount of white space that will always
+be present between the bottom-most symbol of one system, and the
+top-most of the next system.
+
+Increasing this will put systems whose bounding boxes almost touch
+farther apart.
+
+
+@findex horizontal-shift
+@item horizontal-shift
+All systems (including titles and system separators) are shifted by
+this amount to the right. Page markup, such as headers and footers are
+not affected by this. The purpose of this variable is to make space
+for instrument names at the left.
+
+@findex after-title-space
+@item after-title-space
+Amount of space between the title and the first system.
+
+@findex after-title-space
+@item before-title-space
+Amount of space between the last system of the previous piece and the
+title of the next.
+
+@findex between-title-space
+@item between-title-space
+Amount of space between consecutive titles (e.g., the title of the
+book and the title of a piece).
+
+@findex printallheaders
+@item printallheaders
+Setting this to #t will print all headers for each \score in a
+\book. Normally only the piece and opus \headers are printed.
+
+@findex systemSeparatorMarkup
+@item systemSeparatorMarkup
+This contains a markup object, which will be inserted between
+systems. This is often used for orchestral scores.
+
+The markup command @code{\slashSeparator} is provided as a sensible
+default, for example
+
+@lilypond[ragged-right]
+\book {
+ \score {
+ \relative { c1 \break c1 }
+ }
+ \paper {
+ systemSeparatorMarkup = \slashSeparator
+ }
+}
+@end lilypond
+
+
+@end table
+@end quotation
+
+Example:
+
+@example
+\paper@{
+ paper-width = 2\cm
+ top-margin = 3\cm
+ bottom-margin = 3\cm
+ ragged-last-bottom = ##t
+@}
+@end example
+
+You can also define these values in Scheme. In that case @code{mm},
+@code{in}, @code{pt}, and @code{cm} are variables defined in
+@file{paper-defaults.ly} with values in millimeters. That's why the
+value has to be multiplied in the example
+
+@example
+\paper @{
+ #(define bottom-margin (* 2 cm))
+@}
+@end example
+
+@cindex copyright
+@cindex tagline
+
+The default footer is empty, except for the first page, where the
+@code{copyright} field from @code{\header} is inserted, and the last
+page, where @code{tagline} from @code{\header} is added. The default
+tagline is ``Music engraving by LilyPond (@var{version})''.@footnote{Nicely
+printed parts are good PR for us, so please leave the tagline if you
+can.}
+
+The header and footer are created by the functions @code{make-footer}
+and @code{make-header}, defined in @code{\paper}. The default
+implementations are in @file{ly/@/paper@/-defaults@/.ly} and
+@file{ly/@/titling@/-init@/.ly}.
+
+The page layout itself is done by two functions in the
+@code{\paper} block, @code{page-music-height} and
+@code{page-make-stencil}. The former tells the line-breaking algorithm
+how much space can be spent on a page, the latter creates the actual
+page given the system to put on it.
+
+
+@refbugs
+
+The option right-margin is defined but doesn't set the right margin
+yet. The value for the right margin has to be defined adjusting the
+values of @code{left-margin} and @code{line-width}.
+
+The default page header puts the page number and the @code{instrument}
+field from the @code{\header} block on a line.
+
+The titles (from the @code{\header@{@}} section) are treated as a
+system, so @code{ragged-bottom} and @code{ragged-last-bottom} will
+add space between the titles and the first system of the score.
+
+
+@node Music layout
+@section Music layout
+
+This section deals with the manner in which the music is printed
+within the boundaries defined by the @code{\paper} block.
+
+The global paper layout is determined by three factors: the page layout, the
+line breaks, and the spacing. These all influence each other. The
+choice of spacing determines how densely each system of music is set.
+This influences where line breaks are chosen, and thus ultimately, how
+many pages a piece of music takes.
+
+Globally spoken, this procedure happens in three steps: first,
+flexible distances (``springs'') are chosen, based on durations. All
+possible line breaking combinations are tried, and the one with the
+best results -- a layout that has uniform density and requires as
+little stretching or cramping as possible -- is chosen.
+
+After spacing and linebreaking, the systems are distributed across
+pages, taking into account the size of the page, and the size of the
+titles.
+
+@menu
+* Setting global staff size::
+* Selecting notation font size::
+* Score layout::
+* Vertical spacing::
+* Vertical spacing of piano staves::
+* Horizontal spacing::
+* Line length::
+* Line breaking::
+* Page breaking::
+@end menu
+
+
+@node Setting global staff size
+@subsection Setting global staff size
+
+@cindex font size, setting
+@cindex staff size, setting
+@findex layout file
+
+To set the global staff size, use @code{set-global-staff-size}.
+
+@example
+#(set-global-staff-size 14)
+@end example
+
+@noindent
+This sets the global default size to 14pt staff height and scales all
+fonts accordingly.
+
+The Feta font provides musical symbols at eight different
+sizes. Each font is tuned for a different staff size: at a smaller size
+the font becomes heavier, to match the relatively heavier staff lines.
+The recommended font sizes are listed in the following table:
+
+@quotation
+@multitable @columnfractions .15 .2 .22 .2
+
+@item @b{font name}
+@tab @b{staff height (pt)}
+@tab @b{staff height (mm)}
+@tab @b{use}
+
+@item feta11
+@tab 11.22
+@tab 3.9
+@tab pocket scores
+
+@item feta13
+@tab 12.60
+@tab 4.4
+@tab
+
+@item feta14
+@tab 14.14
+@tab 5.0
+@tab
+
+@item feta16
+@tab 15.87
+@tab 5.6
+@tab
+
+@item feta18
+@tab 17.82
+@tab 6.3
+@tab song books
+
+@item feta20
+@tab 20
+@tab 7.0
+@tab standard parts
+
+@item feta23
+@tab 22.45
+@tab 7.9
+@tab
+
+@item feta26
+@tab 25.2
+@tab 8.9
+@tab
+@c modern rental material?
+
+@end multitable
+@end quotation
+
+These fonts are available in any sizes. The context property
+@code{fontSize} and the layout property @code{staff-space} (in
+@internalsref{StaffSymbol}) can be used to tune the size for individual
+staves. The sizes of individual staves are relative to the global size.
+
+@example
+
+@end example
+
+@seealso
+
+This manual: @ref{Selecting notation font size}.
+
+
+@node Selecting notation font size
+@subsection Selecting notation font size
+
+The easiest method of setting the font size of any context, is by
+setting the @code{fontSize} property.
+
+@lilypond[quote,fragment,relative=1,verbatim]
+c8
+\set fontSize = #-4
+c f
+\set fontSize = #3
+g
+@end lilypond
+
+@noindent
+It does not change the size of variable symbols, such as beams or
+slurs.
+
+Internally, the @code{fontSize} context property will cause the
+@code{font-size} property to be set in all layout objects. The value
+of @code{font-size} is a number indicating the size relative to the
+standard size for the current staff height. Each step up is an
+increase of approximately 12% of the font size. Six steps is exactly a
+factor two. The Scheme function @code{magstep} converts a
+@code{font-size} number to a scaling factor.
+
+@lilypond[quote,fragment,relative=1,verbatim]
+c8
+\override NoteHead #'font-size = #-4
+c f
+\override NoteHead #'font-size = #3
+g
+@end lilypond
+
+LilyPond has fonts in different design sizes. The music fonts for
+smaller sizes are chubbier, while the text fonts are relatively wider.
+Font size changes are achieved by scaling the design size that is
+closest to the desired size. The standard font size (for
+@code{font-size} equals 0), depends on the standard staff height. For
+a 20pt staff, a 10pt font is selected.
+
+The @code{font-size} property can only be set on layout objects that
+use fonts. These are the ones supporting the
+@internalsref{font-interface} layout interface.
+
+@refcommands
+
+The following commands set @code{fontSize} for the current voice:
+
+@findex \tiny
+@code{\tiny},
+@findex \small
+@code{\small},
+@findex \normalsize
+@code{\normalsize}.
+
+
+@node Score layout
+@subsection Score layout
+
+@findex \layout
+
+While @code{\paper} contains settings that relate to the page formatting
+of the whole document, @code{\layout} contains settings for score-specific
+layout.
+
+@example
+\layout @{
+ indent = 2.0\cm
+ \context @{ \Staff
+ \override VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 6)
+ @}
+ \context @{ \Voice
+ \override TextScript #'padding = #1.0
+ \override Glissando #'thickness = #3
+ @}
+@}
+@end example
+
+
+@seealso
+
+This manual: @ref{Changing context default settings}
+
+
+@node Vertical spacing
+@subsection Vertical spacing
+
+@cindex vertical spacing
+@cindex distance between staves
+@cindex staff distance
+@cindex between staves, distance
+@cindex staves per page
+@cindex space between staves
+
+The height of each system is determined automatically. To prevent
+systems from bumping into each other, some minimum distances are set.
+By changing these, you can put staves closer together, and thus put
+more systems onto one page.
+
+Normally staves are stacked vertically. To make staves maintain a
+distance, their vertical size is padded. This is done with the
+property @code{minimum-Y-extent}. When applied to a
+@internalsref{VerticalAxisGroup}, it controls the size of a horizontal
+line, such as a staff or a line of lyrics. @code{minimum-Y-extent}
+takes a pair of numbers, so
+if you want to make it smaller than its default @code{#'(-4 . 4)}
+then you could set
+
+@example
+\override Staff.VerticalAxisGroup #'minimum-Y-extent = #'(-3 . 3)
+@end example
+
+@noindent
+This sets the vertical size of the current staff to 3 staff spaces on
+either side of the center staff line. The value @code{(-3 . 3)} is
+interpreted as an interval, where the center line is the 0, so the
+first number is generally negative. The staff can be made larger at
+the bottom by setting it to @code{(-6 . 4)}.
+
+The spacing of staves in a system may also be tuned per system. This is
+done with the command
+
+@example
+\overrideProperty
+#"Score.NonMusicalPaperColumn"
+#'line-break-system-details
+#'((alignment-extra-space . 15))
+@end example
+
+@noindent
+at the line break before the system to be changed. The distance
+@code{15} is distributed over all staves that have a fixed distance
+alignment. For example,
+
+@lilypond[ragged-right, fragment, relative=2, staffsize=13]
+\new StaffGroup <<
+ \new Staff {
+ c1\break
+
+ \overrideProperty
+ #"Score.NonMusicalPaperColumn"
+ #'line-break-system-details
+ #'((fixed-alignment-extra-space . 15))
+
+ c\break
+ }
+ \new Staff { c c }
+>>
+@end lilypond
+
+The distance for @code{alignment-extra-space} may also be negative.
+
+
+To change the amount of space between systems, use
+@code{between-system-space}. A score with only one staff is still
+considered to have systems, so setting @code{between-system-space} will
+be much more useful than changing @code{minimum-Y-extent} of a Staff
+context.
+
+@example
+\paper @{
+ between-system-space = 10\mm
+@}
+@end example
+
+If you simply want to tell LilyPond ``fit as much as possible onto
+these pages, then expand to fill any available space on the pages,''
+then use the following
+
+@example
+\paper @{
+ between-system-padding = #1
+ ragged-bottom=##f
+ ragged-last-bottom=##f
+@}
+@end example
+
+
+@c let's wait for a some comments before writing more.
+
+The vertical spacing on a page can also be changed for each system
+individually.
+Some examples are found in the example file
+@inputfileref{input/regression/,page-spacing.ly}.
+
+When setting @code{annotate-spacing} in the @code{\paper} block LilyPond
+will graphically indicate the dimensions of properties that may be set
+for page spacing,
+
+@lilypond[verbatim]
+#(set-default-paper-size "a7" 'landscape)
+\paper { annotate-spacing = ##t }
+{ c4 }
+@end lilypond
+
+@noindent
+All units dimensions are measured in staff spaces. The pairs
+(@var{a},@var{b}) are intervals, where @var{a} is the lower edge and
+@var{b} the upper edge of the interval.
+
+@seealso
+
+Internals: Vertical alignment of staves is handled by the
+@internalsref{VerticalAlignment} object. The context parameters
+specifying the vertical extent are described in connection with
+the @internalsref{Axis_group_engraver}.
+
+Example files: @inputfileref{input/regression/,page-spacing.ly},
+@inputfileref{input/regression/,alignment-vertical-spacing.ly}.
+
+
+
+
+@node Vertical spacing of piano staves
+@subsection Vertical spacing of piano staves
+
+The distance between staves of a @internalsref{PianoStaff} cannot be
+computed during formatting. Rather, to make cross-staff beaming work
+correctly, that distance has to be fixed beforehand.
+
+The distance of staves in a @code{PianoStaff} is set with the
+@code{forced-distance} property of the
+@internalsref{VerticalAlignment} object, created in
+@internalsref{PianoStaff}.
+
+It can be adjusted as follows
+@example
+\new PianoStaff \with @{
+ \override VerticalAlignment #'forced-distance = #7
+@} @{
+ ...
+@}
+@end example
+
+@noindent
+This would bring the staves together at a distance of 7 staff spaces,
+measured from the center line of each staff.
+
+The difference is demonstrated in the following example,
+@lilypond[quote,verbatim]
+\relative c'' <<
+ \new PianoStaff \with {
+ \override VerticalAlignment #'forced-distance = #7
+ } <<
+ \new Staff { c1 }
+ \new Staff { c }
+ >>
+ \new PianoStaff <<
+ \new Staff { c }
+ \new Staff { c }
+ >>
+>>
+@end lilypond
+
+
+It is also possible to change the distance between for each system
+individually. This is done by including the command
+
+@example
+\overrideProperty
+#"Score.NonMusicalPaperColumn"
+#'line-break-system-details
+#'((fixed-alignment-extra-space . 15))
+@end example
+
+@noindent
+at the line break before the system to be changed. The distance
+@code{15} is distributed over all staves that have a fixed distance
+alignment. For example,
+
+@lilypond[ragged-right, fragment, relative=2, staffsize=13]
+\new PianoStaff <<
+ \new Staff {
+ c1\break
+
+ \overrideProperty
+ #"Score.NonMusicalPaperColumn"
+ #'line-break-system-details
+ #'((fixed-alignment-extra-space . 15))
+
+ c\break
+ }
+ \new Staff { c c }
+>>
+@end lilypond
+
+The distance for @code{fixed-alignment-extra-space} may also be
+negative.
+
+@seealso
+
+Example files: @inputfileref{input/regression/,alignment-vertical-spacing.ly}.
+
+@node Horizontal spacing
+@subsection Horizontal Spacing
+
+The spacing engine translates differences in durations into stretchable
+distances (``springs'') of differring lengths. Longer durations get
+more space, shorter durations get less. The shortest durations get a
+fixed amount of space (which is controlled by
+@code{shortest-duration-space} in the @internalsref{SpacingSpanner}
+object). The longer the duration, the more space it gets: doubling a
+duration adds a fixed amount (this amount is controlled by
+@code{spacing-increment}) of space to the note.
+
+For example, the following piece contains lots of half, quarter, and
+8th notes; the eighth note is followed by 1 note head width (NHW).
+The quarter note is followed by 2 NHW, the half by 3 NHW, etc.
+
+@lilypond[quote,fragment,verbatim,relative=1]
+c2 c4. c8 c4. c8 c4. c8 c8
+c8 c4 c4 c4
+@end lilypond
+
+Normally, @code{spacing-increment} is set to 1.2 staff space, which is
+approximately the width of a note head, and
+@code{shortest-duration-space} is set to 2.0, meaning that the
+shortest note gets 2.4 staff space (2.0 times the
+@code{spacing-increment}) of horizontal space. This space is counted
+from the left edge of the symbol, so the shortest notes are generally
+followed by one NHW of space.
+
+If one would follow the above procedure exactly, then adding a single
+32nd note to a score that uses 8th and 16th notes, would widen up the
+entire score a lot. The shortest note is no longer a 16th, but a 32nd,
+thus adding 1 NHW to every note. To prevent this, the shortest
+duration for spacing is not the shortest note in the score, but rather
+the one which occurs most frequently.
+
+
+The most common shortest duration is determined as follows: in every
+measure, the shortest duration is determined. The most common shortest
+duration is taken as the basis for the spacing, with the stipulation
+that this shortest duration should always be equal to or shorter than
+an 8th note. The shortest duration is printed when you run
+@code{lilypond} with the @code{--verbose} option.
+
+These durations may also be customized. If you set the
+@code{common-shortest-duration} in @internalsref{SpacingSpanner}, then
+this sets the base duration for spacing. The maximum duration for this
+base (normally an 8th), is set through @code{base-shortest-duration}.
+
+@findex common-shortest-duration
+@findex base-shortest-duration
+@findex stem-spacing-correction
+@findex spacing
+
+Notes that are even shorter than the common shortest note are
+followed by a space that is proportional to their duration relative to
+the common shortest note. So if we were to add only a few 16th notes
+to the example above, they would be followed by half a NHW:
+
+@lilypond[quote,fragment,verbatim,relative=2]
+c2 c4. c8 c4. c16[ c] c4. c8 c8 c8 c4 c4 c4
+@end lilypond
+
+
+In the introduction (see @ref{Engraving}), it was explained that stem
+directions influence spacing. This is controlled with the
+@code{stem-spacing-correction} property in the
+@internalsref{NoteSpacing}, object. These are generated for every
+@internalsref{Voice} context. The @code{StaffSpacing} object
+(generated in @internalsref{Staff} context) contains the same property
+for controlling the stem/bar line spacing. The following example shows
+these corrections, once with default settings, and once with
+exaggerated corrections:
+
+@lilypond[quote,ragged-right]
+{
+ c'4 e''4 e'4 b'4 |
+ b'4 e''4 b'4 e''4|
+ \override Staff.NoteSpacing #'stem-spacing-correction = #1.5
+ \override Staff.StaffSpacing #'stem-spacing-correction = #1.5
+ c'4 e''4 e'4 b'4 |
+ b'4 e''4 b'4 e''4|
+}
+@end lilypond
+
+Proportional notation is supported; see @ref{Proportional notation}.
+
+By default, spacing in tuplets depends on various non-duration
+factors (such as accidentals, clef changes, etc). To disregard
+such symbols and force uniform equal-duration spacing, use
+@code{Score.SpacingSpanner #'uniform-stretching}. This
+property can only be changed at the beginning of a score,
+
+@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
+\new Score \with {
+ \override SpacingSpanner #'uniform-stretching = ##t
+} <<
+ \new Staff{
+ \times 4/5 {
+ c8 c8 c8 c8 c8
+ }
+ c8 c8 c8 c8
+ }
+ \new Staff{
+ c8 c8 c8 c8
+ \times 4/5 {
+ c8 c8 c8 c8 c8
+ }
+ }
+>>
+@end lilypond
+
+
+When @code{strict-note-spacing} is set, notes are spaced without
+regard for clefs, bar lines, and grace notes,
+
+@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
+\override Score.SpacingSpanner #'strict-note-spacing = ##t
+\new Staff { c8[ c \clef alto c \grace { c16[ c] } c8 c c] c32[ c32] }
+@end lilypond
+
+
+@seealso
+
+Internals: @internalsref{SpacingSpanner}, @internalsref{NoteSpacing},
+@internalsref{StaffSpacing}, @internalsref{SeparationItem}, and
+@internalsref{SeparatingGroupSpanner}.
+
+@refbugs
+
+Spacing is determined on a score wide basis. If you have a score that
+changes its character (measured in durations) halfway during the
+score, the part containing the longer durations will be spaced too
+widely.
+
+There is no convenient mechanism to manually override spacing. The
+following work-around may be used to insert extra space into a score.
+@example
+ \once \override Score.SeparationItem #'padding = #1
+@end example
+
+No work-around exists for decreasing the amount of space.
+
+
+@node Line length
+@subsection Line length
+
+@cindex page breaks
+@cindex breaking pages
+
+@findex indent
+@findex line-width
+@findex ragged-right
+@findex ragged-last
+
+@c Although line-width can be set in \layout, it should be set in paper
+@c block, to get page layout right.
+@c Setting indent in \paper block makes not much sense, but it works.
+
+@c Bit verbose and vague, use examples?
+The most basic settings influencing the spacing are @code{indent} and
+@code{line-width}. They are set in the @code{\layout} block. They
+control the indentation of the first line of music, and the lengths of
+the lines.
+
+If @code{ragged-right} is set to true in the @code{\layout} block, then
+systems ends at their natural horizontal length, instead of being spread
+horizontally to fill the whole line. This is useful for
+short fragments, and for checking how tight the natural spacing is.
+
+@cindex page layout
+@cindex vertical spacing
+
+The option @code{ragged-last} is similar to @code{ragged-right}, but
+only affects the last line of the piece. No restrictions are put on
+that line. The result is similar to formatting text paragraphs. In a
+paragraph, the last line simply takes its natural horizontal length.
+@c Note that for text there are several options for the last line.
+@c While Knuth TeX uses natural length, lead typesetters use the same
+@c stretch as the previous line. eTeX uses \lastlinefit to
+@c interpolate between both these solutions.
+
+@example
+\layout @{
+ indent = #0
+ line-width = #150
+ ragged-last = ##t
+@}
+@end example
+
+
+@node Line breaking
+@subsection Line breaking
+
+@cindex line breaks
+@cindex breaking lines
+
+Line breaks are normally computed automatically. They are chosen so
+that lines look neither cramped nor loose, and that consecutive lines
+have similar density.
+
+Occasionally you might want to override the automatic breaks; you can
+do this by specifying @code{\break}. This will force a line break at
+this point. Line breaks can only occur at places where there are bar
+lines. If you want to have a line break where there is no bar line,
+you can force an invisible bar line by entering @code{\bar
+""}. Similarly, @code{\noBreak} forbids a line break at a
+point.
+
+
+@cindex regular line breaks
+@cindex four bar music.
+
+For line breaks at regular intervals use @code{\break} separated by
+skips and repeated with @code{\repeat}:
+@example
+<< \repeat unfold 7 @{
+ s1 \noBreak s1 \noBreak
+ s1 \noBreak s1 \break @}
+ @emph{the real music}
+>>
+@end example
+
+@noindent
+This makes the following 28 measures (assuming 4/4 time) be broken every
+4 measures, and only there.
+
+@refcommands
+
+@code{\break}, and @code{\noBreak}.
+@findex \break
+@findex \noBreak
+
+@seealso
+
+Internals: @internalsref{BreakEvent}.
+
+A linebreaking configuration can now be saved as a @code{.ly} file
+automatically. This allows vertical alignments to be stretched to
+fit pages in a second formatting run. This is fairly new and
+complicated; see @inputfileref{input/regression/,page-layout-twopass.ly}
+for details.
+
+@refbugs
+
+Line breaks can only occur if there is a ``proper'' bar line. A note
+which is hanging over a bar line is not proper, such as
+
+@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
+c4 c2 c2 \break % this does nothing
+c2 c4 | % a break here would work
+c4 c2 c4 ~ \break % as does this break
+c4 c2 c4
+@end lilypond
+
+
+@node Page breaking
+@subsection Page breaking
+
+The default page breaking may be overriden by inserting
+@code{\pageBreak} or @code{\noPageBreak} commands. These commands are
+analogous to @code{\break} and @code{\noBreak}. They should be
+inserted at a bar line. These commands force and forbid a page-break
+from happening. Of course, the @code{\pageBreak} command also forces
+a line break.
+
+Page breaks are computed by the @code{page-breaking} function in the
+@code{\paper} block.
+
+To force a new page for a new piece (in a collection of pieces or a
+piece in several movements), use @code{breakbefore} in the header.
+
+@example
+\header@{
+ breakbefore = ##t
+ piece = ""
+@}
+@end example
+
+@refcommands
+
+@findex \pageBreak
+@code{\pageBreak}
+@findex \noPageBreak
+@code{\noPageBreak}
+
+
+@refbugs
+
+The @code{breakbefore=##t} header requires that there is a @code{piece}
+header as well. It may be used as a normal header, or left blank
+(@code{=""}) as in the example above, but it must be present.
+
+
+
+@node Multiple movements
+@section Multiple movements
+
+@cindex bibliographic information
+@cindex titles
+@cindex composer
+@cindex Music engraving by LilyPond
+
+A document may contain multiple pieces of music and texts. Examples
+of these are an etude book, or an orchestral part with multiple
+movements. Each movement is entered with a @code{\score} block,
+
+@example
+\score @{
+ @var{..music..}
+@}
+@end example
+
+and texts are entered with a @code{\markup} block,
+
+@example
+\markup @{
+ @var{..text..}
+@}
+@end example
+
+@findex \book
+
+The movements and texts are combined together in a @code{\book} block,
+like
+
+@example
+\book @{
+ \score @{
+ @var{..}
+ @}
+ \markup @{
+ @var{..}
+ @}
+ \score @{
+ @var{..}
+ @}
+@}
+@end example
+
+
+The header for each piece of music can be put inside the @code{\score}
+block. The @code{piece} name from the header will be printed before
+each movement. The title for the entire book can be put inside the
+@code{\book}, but if it is not present, the @code{\header} which is at
+the top of the file is inserted.
+
+@cindex Engraved by LilyPond
+@cindex signature line
+
+@example
+\book @{
+ \header @{
+ title = "Eight miniatures"
+ composer = "Igor Stravinsky"
+ @}
+ \score @{
+ @dots{}
+ \header @{ piece = "Romanze" @}
+ @}
+ \markup @{
+ ..text of second verse..
+ @}
+ \markup @{
+ ..text of third verse..
+ @}
+ \score @{
+ @dots{}
+ \header @{ piece = "Menuetto" @}
+ @}
+@}
+@end example
+
+
+
+@node MIDI output
+@section MIDI output
+
+@cindex Sound
+@cindex MIDI
+
+MIDI (Musical Instrument Digital Interface) is a standard for
+connecting and controlling digital instruments. A MIDI file is a
+series of notes in a number of tracks. It is not an actual
+sound file; you need special software to translate between the
+series of notes and actual sounds.
+
+Pieces of music can be converted to MIDI files, so you can listen to
+what was entered. This is convenient for checking the music; octaves
+that are off or accidentals that were mistyped stand out very much
+when listening to the MIDI output.
+
+@refbugs
+
+Many musically interesting effects, such as swing, articulation,
+slurring, etc., are not translated to midi.
+
+The midi output allocates a channel for each staff, and one for global
+settings. Therefore the midi file should not have more than 15 staves
+(or 14 if you do not use drums). Other staves will remain silent.
+
+Not all midi players correctly handle tempo changes in the midi
+output. Players that are known to work include
+@uref{http://@/timidity@/.sourceforge@/.net/,timidity}.
+
+@menu
+* Creating MIDI files::
+* MIDI block::
+* MIDI instrument names::
+@end menu
+
+@node Creating MIDI files
+@subsection Creating MIDI files
+
+To create a MIDI from a music piece of music, add a @code{\midi} block
+to a score, for example,
+
+@example
+\score @{
+ @var{...music...}
+ \midi @{ \tempo 4=72 @}
+@}
+@end example
+
+The tempo is specified using the @code{\tempo} command. In this
+example the tempo of quarter notes is set to 72 beats per minute.
+
+
+If there is a @code{\midi} command in a @code{\score}, only MIDI will
+be produced. When notation is needed too, a @code{\layout} block must
+be added
+
+@example
+\score @{
+ @var{...music...}
+ \midi @{ \tempo 4=72 @}
+ \layout @{ @}
+@}
+@end example
+@cindex layout block
+
+
+
+Ties, dynamics, and tempo changes are interpreted. 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 volume vary linearly between
+their two extremes. The fractions can be adjusted by
+@code{dynamicAbsoluteVolumeFunction} in @internalsref{Voice} context.
+For each type of MIDI instrument, a volume range can be defined. This
+gives a basic equalizer control, which can enhance the quality of
+the MIDI output remarkably. The equalizer can be controlled by
+setting @code{instrumentEqualizer}, or by setting
+
+@example
+\set Staff.midiMinimumVolume = #0.2
+\set Staff.midiMaximumVolume = #0.8
+@end example
+
+To remove dynamics from the MIDI output, insert the following lines
+in the @code{\midi@{@}} section.
+
+@example
+\midi @{
+ ...
+ \context @{
+ \Voice
+ \remove "Dynamic_performer"
+ \remove "Span_dynamic_performer"
+ @}
+@}
+@end example
+
+
+@refbugs
+
+Unterminated (de)crescendos will not render properly in the midi file,
+resulting in silent passages of music. The workaround is to explicitly
terminate the (de)crescendo. For example,
@example
The MIDI block is analogous to the layout block, but it is somewhat
-simpler. The @code{\midi} block is similar to @code{\layout}. It can contain
-context definitions.
+simpler. The @code{\midi} block can contain
+@cindex MIDI block
+
+@itemize @bullet
+ @item a @code{\tempo} definition, and
+ @item context definitions.
+@end itemize
+
+A number followed by a period is interpreted as a real number, so
+for setting the tempo for dotted notes, an extra space should be
+inserted, for example
+
+@example
+\midi @{ \tempo 4 . = 120 @}
+@end example
@cindex context definition
@subsection MIDI instrument names
@cindex instrument names
-@funindex Staff.midiInstrument
+@findex Staff.midiInstrument
The MIDI instrument name is set by the @code{Staff.midiInstrument}
property. The instrument name should be chosen from the list in
@node Displaying LilyPond notation
@section Displaying LilyPond notation
-@funindex \displayLilyMusc
+@findex \displayLilyMusc
Displaying a music expression in LilyPond notation can be
done using the music function @code{\displayLilyMusic}. For example,
@end example
+@node Other
+@section Other
+
+@c FIXME: yeah, it really needs to be moved soon. -gp
+@menu
+* Skipping corrected music::
+* Writing music in parallel::
+@end menu
+
@node Skipping corrected music
-@section Skipping corrected music
+@subsection Skipping corrected music
-@funindex skipTypesetting
-@funindex showLastLength
+@findex skipTypesetting
+@findex showLastLength
When entering or copying music, usually only the music near the end (where
you
voices and staves, saving even more time.
+@node Writing music in parallel
+@subsection Writing music in parallel
+@cindex Writing music in parallel
+@cindex Interleaved music
+
+Music for multiple parts can be interleaved
+
+@lilypond[quote,fragment,verbatim]
+\parallelMusic #'(voiceA voiceB) {
+ r8 g'16[ c''] e''[ g' c'' e''] r8 g'16[ c''] e''[ g' c'' e''] |
+ c'2 c'2 |
+ r8 a'16[ d''] f''[ a' d'' f''] r8 a'16[ d''] f''[ a' d'' f''] |
+ c'2 c'2 |
+}
+\new StaffGroup <<
+ \new Staff \new Voice \voiceA
+ \new Staff \new Voice \voiceB
+>>
+@end lilypond
+
@cindex staff switching
@cindex cross staff
-@funindex followVoice
+@findex followVoice
Whenever a voice switches to another staff, a line connecting the notes
can be printed automatically. This is switched on by setting
@refcommands
-@funindex \showStaffSwitch
+@findex \showStaffSwitch
@code{\showStaffSwitch},
-@funindex \hideStaffSwitch
+@findex \hideStaffSwitch
@code{\hideStaffSwitch}.
@end lilypond
@cindex modifiers, in chords.
-@funindex aug
-@funindex dim
-@funindex maj
-@funindex sus
-@funindex m
+@findex aug
+@findex dim
+@findex maj
+@findex sus
+@findex m
Since an unaltered 11 does not sound good when combined with an
unaltered 3, the 11 is removed in this case (unless it is added
\chordmode { c:13 c:13.11 c:m13 }
@end lilypond
-@funindex /
+@findex /
An inversion (putting one pitch of the chord on the bottom), as well
as bass notes, can be specified by appending
@lilypond[quote,ragged-right,fragment,verbatim]
\chordmode { c1 c/g c/f }
@end lilypond
-@funindex /+
+@findex /+
A bass note can be added instead transposed out of the chord,
by using @code{/+}@var{pitch}.
\consists "Volta_engraver"
}
\chordmode { \repeat volta 2 {
- f1:maj7 f:7 bes:7
- c:maj7
+ f1:maj f:7 bes:7
+ c:maj
} \alternative {
es e
}
following properties
@table @code
-@funindex chordNameExceptions
+@findex chordNameExceptions
@item chordNameExceptions
This is a list that contains the chords that have special formatting.
@cindex exceptions, chord names.
-@funindex majorSevenSymbol
+@findex majorSevenSymbol
@item majorSevenSymbol
This property contains the markup object used for the 7th step, when
it is major. Predefined options are @code{whiteTriangleMarkup} and
@code{blackTriangleMarkup}. See
@inputfileref{input/@/regression,chord@/-name@/-major7@/.ly} for an example.
-@funindex chordNameSeparator
+@findex chordNameSeparator
@item chordNameSeparator
Different parts of a chord name are normally separated by a
slash. By setting @code{chordNameSeparator}, you can specify other
}
@end lilypond
-@funindex chordRootNamer
+@findex chordRootNamer
@item chordRootNamer
The root of a chord is usually printed as a letter with an optional
alteration. The transformation from pitch to letter is done by this
function. Special note names (for example, the German ``H'' for a
B-chord) can be produced by storing a new function in this property.
-@funindex chordNoteNamer
+@findex chordNoteNamer
@item chordNoteNamer
The default is to print single pitch, e.g., the bass note, using the
@code{chordRootNamer}. The @code{chordNoteNamer} property can be set
to a specialized function to change this behavior. For example, the
base can be printed in lower case.
-@funindex chordPrefixSpacer
+@findex chordPrefixSpacer
@item chordPrefixSpacer
The ``m'' for minor chords is usually printed right after the root of
the chord. By setting @code{chordPrefixSpacer}, you can fix a spacer
@refcommands
-@funindex \germanChords
+@findex \germanChords
@code{\germanChords},
-@funindex \semiGermanChords
+@findex \semiGermanChords
@code{\semiGermanChords}.
-@funindex \italianChords
+@findex \italianChords
@code{\italianChords}.
-@funindex \frenchChords
+@findex \frenchChords
@code{\frenchChords}.
@subsection Entering lyrics
@cindex lyrics
-@funindex \lyricmode
+@findex \lyricmode
@cindex punctuation
Lyrics are entered in a special input mode. This mode is introduced
\lyricmode @{ twinkle@}
@end example
-@funindex \property in \lyricmode
+@findex \property in \lyricmode
@noindent
Similarly, a period which follows an alphabetic sequence is included in
\override Score . LyricText #'font-shape = #'italic
@end example
-@funindex _
+@findex _
@cindex spaces, in lyrics
@cindex quotes, in lyrics
@node The Lyrics context
@subsection The Lyrics context
-Lyrics are printed by interpreting them in the context called
+Lyrics are printed by interpreting them in the context caleld
@internalsref{Lyrics}.
@example
@end example
@cindex automatic syllable durations
-@funindex \lyricsto
+@findex \lyricsto
@cindex lyrics and melodies
This will place the lyrics according to the durations that were
@refcommands
@code{\melisma}, @code{\melismaEnd}
-@funindex \melismaEnd
-@funindex \melisma
+@findex \melismaEnd
+@findex \melisma
@seealso
Names of singers can also be added. They are printed at the start of
the line, just like instrument names. They are created by setting
-@code{vocalName}. A short version may be entered as @code{shortVocalName}.
+@code{vocalName}. A short version may be entered as @code{vocNam}.
@lilypond[fragment,ragged-right,quote,verbatim,relative=2]
}
@end lilypond
-@funindex minimumFret
+@findex minimumFret
@cindex fret
When no string is specified, the first string that does not give a
@node Ancient note heads
@subsection Ancient note heads
-@cindex note heads, ancient
+@cindex note heads
+
For ancient notation, a note head style other than the @code{default}
style may be chosen. This is accomplished by setting the @code{style}
\include "gregorian-init.ly"
\score {
\new VaticanaVoice {
+ \override Staff.StaffSymbol #'color = #red
+ \override Staff.LedgerLineSpanner #'color = #red
\override TextScript #'font-family = #'typewriter
\override TextScript #'font-shape = #'upright
\override Script #'padding = #-0.1
@refcommands
-@funindex \virgula
+@findex \virgula
@code{\virgula},
-@funindex \caesura
+@findex \caesura
@code{\caesura},
-@funindex \divisioMinima
+@findex \divisioMinima
@code{\divisioMinima},
-@funindex \divisioMaior
+@findex \divisioMaior
@code{\divisioMaior},
-@funindex \divisioMaxima
+@findex \divisioMaxima
@code{\divisioMaxima},
-@funindex \finalis
+@findex \finalis
@code{\finalis}.
@seealso
The following head prefixes are supported
-@funindex \virga
+@findex \virga
@code{\virga},
-@funindex \stropha
+@findex \stropha
@code{\stropha},
-@funindex \inclinatum
+@findex \inclinatum
@code{\inclinatum},
-@funindex \auctum
+@findex \auctum
@code{\auctum},
-@funindex \descendens
+@findex \descendens
@code{\descendens},
-@funindex \ascendens
+@findex \ascendens
@code{\ascendens},
-@funindex \oriscus
+@findex \oriscus
@code{\oriscus},
-@funindex \quilisma
+@findex \quilisma
@code{\quilisma},
-@funindex \deminutum
+@findex \deminutum
@code{\deminutum},
-@funindex \cavum
+@findex \cavum
@code{\cavum},
-@funindex \linea
+@findex \linea
@code{\linea}.
Head prefixes can be accumulated, though restrictions apply. For
example, either @code{\descendens} or @code{\ascendens} can be applied
to a head, but not both to the same head.
-@funindex \pes
-@funindex \flexa
+@findex \pes
+@findex \flexa
Two adjacent heads can be tied together with the @code{\pes} and
@code{\flexa} infix commands for a rising and falling line of melody,
respectively.
\score {
<<
\new VaticanaVoice = "cantus" {
- \[ c'\melisma c' \flexa a \]
- \[ a \flexa \deminutum g\melismaEnd \]
- f \divisioMinima
- \[ f\melisma \pes a c' c' \pes d'\melismaEnd \]
- c' \divisioMinima \break
- \[ c'\melisma c' \flexa a \]
- \[ a \flexa \deminutum g\melismaEnd \] f \divisioMinima
+ \override Staff.StaffSymbol #'color = #red
+ \override Staff.LedgerLineSpanner #'color = #red
+ \override Score.BarNumber #'transparent = ##t {
+ \[ c'\melisma c' \flexa a \]
+ \[ a \flexa \deminutum g\melismaEnd \]
+ f \divisioMinima
+ \[ f\melisma \pes a c' c' \pes d'\melismaEnd \]
+ c' \divisioMinima \break
+ \[ c'\melisma c' \flexa a \]
+ \[ a \flexa \deminutum g\melismaEnd \] f \divisioMinima
+ }
}
\new Lyrics \lyricsto "cantus" {
San- ctus, San- ctus, San- ctus
Support for such suggested accidentals is included, and can be
switched on by setting @code{suggestAccidentals} to true.
-@funindex suggestAccidentals
+@findex suggestAccidentals
@lilypond[verbatim,fragment,relative=1]
fis gis
markup text properties to override formatting. For example, the
vertical spacing of the figures may be set with @code{baseline-skip}.
-
-Figured bass can also be added to @code{Staff} contexts
-directly. In this case, their vertical position is adjusted
-automatically.
-
-@lilypond[ragged-right,fragment,quote]
-<<
- \new Staff = someUniqueName
- \relative c'' {
- c4 c'8 r8 c,4 c'
- }
-
- %% send to existing Staff.
- \context Staff = someUniqueName
- \figuremode {
- <4>4 <6 10>8 s8
-
- \set Staff.useBassFigureExtenders = ##t
- <4 6>4 <4 6>
- }
->>
-@end lilypond
-
-
@seealso
Program reference: @internalsref{NewBassFigure},
explains how to fine tune layout.
@item
-@emph{@ref{Non-musical notation}}
-discusses non-musical output such as titles, multiple movements,
-and how to select which MIDI instruments to use.
-
-@item
-@emph{@ref{Spacing issues}}
+@emph{@ref{Global issues}}
discusses issues which affect the global output, such as selecting
-paper size or specifying page breaks.
+paper size or which MIDI instruments to use.
@item
@emph{@ref{LilyPond-book}} explains the details behind creating
This chapter details the technicalities of running LilyPond.
-Some of these commands are run from the command-line. By
-``command-line'', we mean the command
-line in the operating system. Windows users
-might be more familiar with the terms ``DOS shell'' or
-``command shell''; OSX users might be more familiar with the
-terms ``terminal'' or ``console''. OSX users should also
-consult @ref{Notes for the MacOS X app}.
-
-Describing how to use
-this part of an operating system is outside the scope of this
-manual; please consult other documentation on this topic if
-you are unfamiliar with the command-line.
@menu
* Invoking lilypond::
@code{--safe} option will prevent inline Scheme code from wreaking
havoc, for example
+When LilyPond formatting is available through a web server, the
+@code{--safe} @b{MUST} be passed. This will prevent inline Scheme
+code from wreaking havoc, for example
+
@quotation
@verbatim
#(system "rm -rf /")
@node Notes for the MacOS X app
@section Notes for the MacOS X app
-The scripts (such as lilypond-book, convert-ly, abc2ly, and even
-lilypond itself) are also
+The scripts (such as lilypond-book, convert-ly, abc2ly, etc.) are also
included inside MacOS X .app. They can be run from the command line by
invoking them directly, e.g.
@example
-@var{path/to}/LilyPond.app/Contents/Resources/bin/lilypond
+@var{path/to}/LilyPond.app/Contents/Resources/bin/convert-ly
@end example
-@noindent
-The same is true of the other scripts in that directory, including
-lilypond-book, convert-ly, abc2ly, etc.
-
Alternatively, you may add this directory to your path. Modify (or create)
a file called @code{.profile} in your home directory such that it contains
@section Updating with @command{convert-ly}
@cindex Updating a LilyPond file
-@funindex convert-ly
+@findex convert-ly
The LilyPond input syntax is routinely changed to simplify it or improve
it in different ways. As a side effect of this, the LilyPond interpreter
@refbugs
Not all language changes are handled. Only one output option can be
-specified. Automatically updating scheme and lilypond scheme
-interfaces is quite unlikely; be prepared to tweak scheme code
-manually.
+specified.
@c We might want to make this a completely new section, along with more
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/lilypond/lily-bugs/bugs/
convert-ly.txt?rev=HEAD&content-type=text/plain
-
-NEW: not exactly copied; this list has been modified. Since we're
-changing the bug system, it doesn't make sense to copy from
-the bug CVS any more. I'll figure out something else. -gp
@end ignore
@verbatim
remove-tag isn't changed.
- \applyMusic #(remove-tag '. . .) => \keepWithTag #'. . .
first-page-number isn't changed.
- - first-page-number no => print-first-page-number = ##f
+ - first-page-number no => printfirst-page-number = ##f
Line breaks in header strings aren't converted.
- \\\\ as line break in \header strings => \markup \center-align <
"First Line" "Second Line" >
but now, \line is missing.
2.4->2.6
Special LaTeX characters such as $~$ in text are not converted to UTF8.
-2.8
- \score{} must now begin with a music expression. Anything else
- (particularly \header{}) must come after the music.
+
@end verbatim
Using Mac OSX 10.3.7, lilypond 2.7.32
-\version "2.9.13"
+\version "2.7.32"
\layout { ragged-right = ##t }
\relative c'' {
a4 b cis d
* Music fragment options::
* Invoking lilypond-book::
* Filename extensions::
-* Inserting LilyPond output into other programs::
@end menu
@cindex texinfo
@cindex latex
@cindex texinfo
-@funindex texi
+@findex texi
@cindex html
@cindex documents, adding music to
use the @code{line-width} music fragment option.
@cindex titling and lilypond-book
-@funindex \header in La@TeX{} documents
+@findex \header in La@TeX{} documents
Each snippet will call the following macros if they have been defined by
the user:
@cindex international characters
@cindex latin1
-Sometimes it is useful to display music elements (such as ties and slurs)
-as if they continued after the end of the fragment. This can be done by
-breaking the staff and suppressing inclusion of the rest of the lilypond
-output.
-
-In La@TeX{}, define @code{\betweenLilyPondSystem} in such a way that
-inclusion of other systems is terminated once the required number of
-systems are included. Since @code{\betweenLilypondSystem} is first
-called @b{after} the first system, including only the first system
-is trivial.
-
-@example
-\def\betweenLilyPondSystem#1@{\endinput@}
-
-\begin[fragment]@{lilypond@}
- c'1\( e'( c'~ \break c' d) e f\)
-\end@{lilypond@}
-@end example
-
-If a greater number of systems is requested, a TeX conditional must be
-used before the @code{\endinput}. In this example, replace "2" by
-the numer of systems you want in the output,
-
-@example
-\def\betweenLilyPondSystem#1@{
- \ifnum##1<2\else\endinput\fi
-@}
-@end example
-
-Remember that the definition of @code{\betweenLilyPondSystem} is
-effective until @TeX{} quits the current group (such as the La@TeX{}
-environment) or is overridden by another definition (which is, in
-most cases, for the rest of the document). To reset your
-definition, write
-
-@example
-\let\betweenLilyPondSystem\undefined
-@end example
-
-@noindent
-in your LaTeX source.
-
-This may be simplified by defining a @TeX{} macro
-
-@example
-\def\onlyFirstNSystems#1@{
- \def\betweenLilyPondSystem##1@{\ifnum##1<#1\else\endinput\fi@}
-@}
-@end example
-
-@noindent
-and then saying only how many systems you want before each fragment,
-
-@example
-\onlyFirstNSystems@{3@}
-\begin@{lilypond@}...\end@{lilypond@}
-\onlyFirstNSystems@{1@}
-\begin@{lilypond@}...\end@{lilypond@}
-@end example
-
@node Integrating Texinfo and music
@section Integrating Texinfo and music
processing.
@command{lilypond-book} can also create a PSFONTS file, which is required
-by @command{dvips} to produce Postscript and PDF files.
+by @command{dvips} to produce Postscript and PDF files. You can call
+this file whatever you want as long as you refer to the same file when
+you call @command{dvips}.
To produce PDF output from the lilypond-book file (here called
-@code{yourfile.lytex}) via LaTeX, you should do
+@code{yourfile.lytex}), you should do
@example
lilypond-book --psfonts yourfile.lytex
noteheads. This is normal; if you follow the instructions, they
will be included in the @file{.ps} and @file{.pdf} files.
-To produce a PDF file through PDF(La)TeX, use
-
-@example
-lilypond-book --pdf yourfile.pdftex
-pdflatex yourfile.tex
-@end example
-
-
To produce a Texinfo document (in any output format), follow the normal
procedures for Texinfo (this is, either call @command{texi2dvi} or
@command{makeinfo}, depending on the output format you want to
@item @file{.xml} @tab HTML
@end multitable
@end quotation
-
-
-@node Inserting LilyPond output into other programs
-@section Inserting LilyPond output into other programs
-
-To insert LilyPond output in other programs, use @code{lilypond}
-instead of @code{lilypond-book}. Each example must be created
-individually and added to the document; consult the
-documentation for that program. Most programs will be able
-to insert lilypond output in @file{PNG}, @file{EPS}, or @file{PDF}
-formats.
-
-To reduce the white space around your lilypond score, use
-the following options
-
-@example
-\paper@{
- indent=0\mm
- line-width=120\mm
- oddFooterMarkup=##f
- oddHeaderMarkup=##f
- bookTitleMarkup = ##f
- scoreTitleMarkup = ##f
-@}
-
-@{ c1 @}
-@end example
-
-To produce a useful @file{eps} file, use
-
-@example
-lilypond -b eps -dno-gs-load-fonts -dinclude-eps-fonts myfile.ly
-@end example
-
@c LilyPond program.
@end ignore
-
-@c
-@c Info files are installed in subdirectories to allow images to be present.
-@c
-@dircategory LilyPond
+@dircategory GNU music project
@direntry
* LilyPond: (lilypond/lilypond). The GNU music typesetter.
* abc2ly: (lilypond/lilypond)Invoking abc2ly. Importing ABC.
* mup2ly: (lilypond/lilypond)Invoking mup2ly. Importing Mup.
@end direntry
+
@c don't remove this comment.
@ignore
@omfcreator Han-Wen Nienhuys, Jan Nieuwenhuizen and Graham Percival
@c This produces the unified index
-@syncodeindex fn cp
+@syncodeindex ky cp
@syncodeindex vr cp
@documentlanguage en
Copyright @copyright{} 1999--2006 by the authors
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1
-or any later version published by the Free Software Foundation;
-with no Invariant Sections.
-A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
-@end quotation
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
@vskip 20pt
@end titlepage
-@copying
-Copyright @copyright{} 1999--2006 by the authors
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1
-or any later version published by the Free Software Foundation;
-with no Invariant Sections.
-A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
-@end quotation
-@end copying
@ifnottex
This file documents GNU LilyPond.
Copyright 1999--2006 by the authors
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1
-or any later version published by the Free Software Foundation;
-with no Invariant Sections.
-A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
-@end quotation
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections.
+ A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
@end ifnottex
+
@ifnottex
@node Top
@top GNU LilyPond --- The music typesetter
* Instrument-specific notation:: Specialized notation.
* Advanced notation:: Less frequently used notation.
* Changing defaults:: Tuning output.
-* Non-musical notation:: Output that is not musical notation.
-* Spacing issues:: Display of output on paper.
+* Global issues:: What LilyPond produces.
* Interfaces for programmers:: Expert usage.
Program usage
@include advanced-notation.itely
@include changing-defaults.itely
@include global.itely
-@include page.itely
@include programming-interface.itely
@include invoking.itely
@node LilyPond command index
@appendix LilyPond command index
-@printindex ky
+@printindex fn
@node LilyPond index
@appendix LilyPond index
@end macro
-@macro funindex {WORD}
-@findex \WORD\
-@kindex \WORD\
-@end macro
+@c @macro funindex {WORD}
+@c @end macro
+@c @findex \WORD\
+@c @kindex \WORD\
@documentencoding utf-8
@documentlanguage en
-@c see lilypond.tely for info installation note
-@dircategory LilyPond
+@dircategory GNU music project
@direntry
* Glossary: (lilypond/music-glossary). Glossary of music terms.
@end direntry
@c French glossary
@author Han-Wen Nienhuys @c Dutch glossary
@author Jan Nieuwenhuizen @c Dutch glossary
-@author David González @c Spanish glossary
+@author Dadiv Gonzalez @c Spanish glossary
@author Bjoern Jacke @c German glossary
@author Neil Jerram @c English glossary translations
@author Mats Bengtsson @c Swedish glossary
@top Music glossary
@end ifnottex
-
-@ifnottex
-
This glossary was brought you by
+@ifnottex
@table @code
@item Adrian Mariano
Italian glossary,
German glossary,
@item Christian Mondrup
Original author of LilyPond glossary, Danish glossary,
-@item David González
+@item Dadiv Gonzalez
Spanish glossary,
@item Fran@,{c}ois Pinard
Original glossary of GNU music project, French glossary,
@node accidental
@section accidental
-ES: alteración accidental,
+ES: alteración accidentelle,
I: accidento,
F: altération accidentelle,
D: Vorzeichen, Versetzungszeichen, Akzidenz,
@node ambit
@section ambit
-ES: ámbito,
+ES: Ã\83¡mbito,
I: ambitus,
F: ambitus,
D: ambitus,
@node ancient minor scale
@section ancient minor scale
-ES: escala menor antigua,
+ES: escala menor antigua
I: scala minore naturale,
F: forme du mode mineur ancien, troisème mode, mode hellénique
D: reines Moll,
@node bar
@section bar
-@aref{measure}.
+ES: compás, @aref{measure}.
@node bar line
@section bar line
-ES: barra, línea divisoria,
+ES: barra, lÃ\83Ânea divisoria,
I: stanghetta, barra (di divisione),
F: barre (de mesure),
D: Taktstrich,
@node beat
@section beat
-ES: tiempo, parte (de compás)
+ES: tiempo, parte (de compÃ\83¡s)
I: tempi,
F: temps,
D: Takt, Taktschlag, Zeit (im Takt),
@node breath mark
@section breath mark
-ES: respiración,
+ES: respiraciÃ\83³n,
I: respiro,
F: respiration,
D: Atemzeichen, Trennungszeichen,
@node cluster
@section cluster
-ES: racimo.
-
A @emph{cluster} is a range of simultaneously sounding pitches that
may change over time. The set of available pitches to apply usually
depends on the acoustic source. Thus, in piano music, a cluster
@node comma
@section comma
-ES: coma, comma,
+ES: coma, comma
I: comma,
F: comma,
D: Komma,
@node complement
@section complement
-ES: intervalo invertido,
+ES: intervalo invertido
I: rivolto,
F: intervalle complémentaire,
D: Komplementärintervall,
@node cue-notes
@section cue-notes
-ES: notas guía,
+ES: notas guÃ\83Âa,
I: notine,
F: petites notes précédent l'entrée d'in instrument, réplique,
D: Stichnoten,
@node diminished interval
@section diminished interval
-ES: intervalo disminuido,
+ES: intervalo disminuído,
I: intervallo diminuito,
F: intervalle diminué,
D: vermindertes Intervall,
@node disjunct movement
@section disjunct movement
-ES: movimiento disjunto,
+ES: movimiendo disjunto,
I: moto disgiunto,
F: mouvement disjoint,
D: sprunghafte Bewegung,
@node enharmonic
@section enharmonic
-ES: enarmónico,
+ES: enharmónico,
I: enarmonico,
F: enharmonique,
D: enharmonisch,
@node expression mark
@section expression mark
-ES: expresión,
+ES: expresiÃ\83³n,
I: segno d'espressione,
F: signe d'expression, indication de nuance,
D: Vortragszeichen,
@node fermata
@section fermata
-ES: calderón,
+ES: Calderón,
I: corona,
F: point d'orgue, point d'arr@^et,
D: Fermate,
@node figured bass
@section figured bass
-@aref{thorough bass}.
+ES: bajo cifrado, @aref{thorough bass}.
@node fingering
@section fingering
@node grace notes
@section grace notes
-ES: notas de adorno,
+ES: mordente,
I: abbellimenti,
F: fioriture,
D: Verzierungen, Vorschläge, Vor@-schlags@-noten,
\bar "|."
}
\lyrics {
- T4 S D T
+ T S D T
}
>>
>>
<g d'>_"fifth " s
<g e'>_"sixth " s
<g g'>_"octave " s
- <g b'>_"tenth" s s
+ <g b'>_"decime" s s
}
@end lilypond
}
\context Lyrics \lyrics {
"seventh " "seventh " "seventh " "octave "
- "ninth " "ninth " "tenth " "tenth"
+ "none " "none " "decime " "decime"
}
>>
@end lilypond
@node just intonation
@section just intonation
-ES: entonación justa,
+ES: entonaciÃ\83³n justa,
I: intonazione giusta,
F: intonation juste,
D: reine Stimmung,
@node ledger line
@section ledger line
-ES: línea adicional,
+ES: líneas adicionales,
I: tagli addizionali,
F: ligne supplémentaire,
D: Hilfslinie,
c4-. d-. e-. \bar "||"
}
\lyrics {
- a2.
+ a1
b
c
d
@node lilypond
@section lilypond
-ES: estanque de nenúfares,
+ES: estanque de nenÃ\83ºfares,
I: stagno del giglio,
F: étang de lis,
UK: lily pond,
@node lyrics
@section lyrics
-ES: letra (de la canción),
+ES: letra (de la canciÃ\83³n),
I: .,
F: .,
D: Liedtext,
@node meantone temperament
@section meantone temperament
-ES: afinación mesotónica,
+ES: afinaciÃ\83³n mesotÃ\83³nica,
I: accordatura mesotonica,
F: tempérament mésotonique,
D: mitteltönige Stimmung,
@node mezzo-soprano
@section mezzo-soprano
-ES: mezzosoprano,
+ES: mezzo soprano,
I: mezzo-soprano,
F: mezzo-soprano,
D: Mezzosopran,
@node minor interval
@section minor interval
-ES: intervalo menor,
+ES: intervalo mayor,
I: intervallo minore,
F: intervalle mineur,
D: kleines Intervall,
@node motive
@section motive
-ES: motivo,
+ES: tema,
I: inciso,
F: incise,
D: Motiv,
The briefest intelligible and self-contained fragment of a musical theme or
subject.
-@lilypond[line-width=13.0\cm]
-\score{
+@lilypond[fragment,line-width=13.0\cm]
+\override Score.TimeSignature #'break-visibility = #all-invisible
+%\override Score.TextScript #'font-style = #'large
\relative c'' {
- \override Score.TimeSignature #'break-visibility = #all-invisible
- %\override Score.TextScript #'font-style = #'large
\time 4/4
\key g \major
- \partial 8 g16\startGroup fis |
- g8\stopGroup d16\startGroup c d8\stopGroup g16 fis g8 b,16 a b8 g'16 fis |
+ \partial 8 g16_"------" fis |
+ g8 d16_"------" c d8 g16 fis g8 b,16 a b8 g'16 fis |
g8 g,16 a b8 cis d16 s
}
-\layout {
- \context {
- \Staff \consists "Horizontal_bracket_engraver"
-}}
-}
@end lilypond
@node movement
@node note value
@section note value
-ES: valor (duración),
+ES: valor (duraciÃ\83³n),
I: valore, durata,
F: durée, valeur (d'une note),
D: Notenwert,
@node Pythagorean comma
@section Pythagorean comma
-ES: coma pitagórica,
+ES: coma pitagórico,
I: comma pitagorico,
F: comma pythagoricien,
D: Pythagoräisches Komma,
@node relative key
@section relative key
-ES: relativo,
+ES: relativa,
I: tonalità relativa,
F: tonalité relative,
D: Paralleltonart,
@node repeat
@section repeat
-ES: repetición,
+ES: barra de repetición,
I: ritornello,
F: barre de reprise,
D: Wiederholung,
@node scale degree
@section scale degree
-ES: grado (de la escala),
+ES: grados de la escala,
I: grado della scala,
F: degré [de la gamme],
D: Tonleiterstufe,
@node slur
@section slur
-ES: ligadura (de expresión),
+ES: ligadura (de expresiÃ\83³n),
I: legatura (di portamento or espressiva),
F: liaison, coulé,
D: Bogen, Legatobogen, Phrasierungsbogen,
@node solmization
@section solmization
-ES: solmisación,
+ES: solmisaciÃ\83³n,
I: solmisazione,
F: solmisation,
D: Solmisation,
@node staccato
@section staccato
-ES: picado,
+ES: picado (staccato),
I: staccato,
F: staccato, piqué, détaché,
D: Staccato,
@node subtonic
@section subtonic
-ES: subtónica,
+ES: sensible,
I: sottotonica,
F: sous-tonique,
D: Subtonika,
@node syncopation
@section syncopation
-ES: síncopa,
+ES: sÃ\83Âncopa,
I: sincope,
F: syncope,
D: Synkope,
@node syntonic comma
@section syntonic comma
-ES: coma sintónica,
+ES: coma sintÃ\83³nica,
I: comma sintonico (o didimico),
F: comma syntonique,
D: syntonisches Komma,
@node tenuto
@section tenuto
-ES: subrayado (tenuto),
+ES: tenuto,
I: tenuto,
F: tenue, tenuto,
D: gehalten, tenuo,
@node time signature
@section time signature
-ES: indicación de compás,
+ES: cifra indicadora de compás,
I: segni di tempo,
F: chiffrage (chiffres indicateurs), signe de valeur,
D: Taktangabe, Angabe der Taktart,
@node tonic
@section tonic
-ES: tónica,
+ES: tÃ\83³nica,
I: tonica,
F: tonique,
D: Tonika,
@node transposition
@section transposition
-ES: transporte,
+ES: transposición,
I: trasposizione,
F: transposition,
D: Transposition,
@node tremolo
@section tremolo
-ES: trémolo,
+ES: trÃ\83©molo,
I: tremolo,
F: trémolo,
D: Tremolo,
@node triple meter
@section triple meter
-ES: compás ternario,
+ES: compás compuesto,
I: tempo ternario,
F: mesure ternaire,
D: in drei,
@node tritone
@section tritone
-ES: tritono,
+ES: trítono,
I: tritono,
F: triton,
D: Tritonus,
@node upbeat
@section upbeat
-ES: anacrusa,
+ES: entrada anacrúsica,
I: anacrusi,
F: anacrouse, levée,
D: Auftakt,
@node whole tone
@section whole tone
-ES: tono (entero),
+ES: tono,
I: tono intero,
F: ton entier,
D: Ganzton,
@item
-@item @strong{c-sharp} @tab do sostenido @tab do diesis @tab ut dièse @tab
+@item @strong{c-sharp} @tab do diesis @tab do diesis @tab ut dièse @tab
Cis @tab cis @tab
cis @tab cis @tab cis
@item
-@item @strong{d-flat} @tab re bemol @tab re bemolle @tab ré bémol @tab
+@item @strong{d-flat} @tab re bemolle @tab re bemolle @tab ré bémol @tab
Des @tab des @tab
des @tab des @tab des
+++ /dev/null
-@c -*- coding: utf-8; mode: texinfo; -*-
-@c This file is part of lilypond.tely
-
-@c A menu is needed before every deeper *section nesting of @node's; run
-@c M-x texinfo-all-menus-update
-@c to automatically fill in these menus before saving changes
-
-@node Spacing issues
-@chapter Spacing issues
-
-The global paper layout is determined by three factors: the page layout, the
-line breaks, and the spacing. These all influence each other. The
-choice of spacing determines how densely each system of music is set.
-This influences where line breaks are chosen, and thus ultimately, how
-many pages a piece of music takes.
-
-Globally speaking, this procedure happens in four steps: first,
-flexible distances (``springs'') are chosen, based on durations. All
-possible line breaking combinations are tried, and a ``badness'' score
-is calculated for each. Then the height of each possible system is
-estimated. Finally, a page breaking and line breaking combination is chosen
-so that neither the horizontal nor the vertical spacing is too cramped
-or stretched.
-
-@menu
-* Paper and pages::
-* Music layout::
-* Vertical spacing::
-* Horizontal spacing::
-* Breaks::
-* Displaying spacing::
-@end menu
-
-
-@node Paper and pages
-@section Paper and pages
-
-This section deals with the boundaries that define the area
-that music can be printed inside.
-
-@menu
-* Paper size::
-* Page formatting::
-@end menu
-
-
-@node Paper size
-@subsection Paper size
-
-@cindex paper size
-@cindex page size
-@funindex papersize
-
-To change the paper size, there are two commands,
-@example
-#(set-default-paper-size "a4")
-\paper @{
- #(set-paper-size "a4")
-@}
-@end example
-
-The first command sets the size of all pages. The second command sets the
-size
-of the pages that the @code{\paper} block applies to -- if the @code{\paper}
-block is at the top of the file, then it will apply to all pages. If the
-@code{\paper} block is inside a @code{\book}, then the paper size will only
-apply to that book.
-
-Support for the following paper sizes are included by default,
-@code{a6}, @code{a5}, @code{a4}, @code{a3}, @code{legal}, @code{letter},
-@code{11x17} (also known as tabloid).
-
-Extra sizes may be added by editing the definition for
-@code{paper-alist} in the initialization file @file{scm/paper.scm}.
-
-@cindex orientation
-@cindex landscape
-
-If the symbol @code{landscape} is supplied as an argument to
-@code{set-default-paper-size}, the pages will be rotated by 90 degrees,
-and wider line widths will be set correspondingly.
-
-@example
-#(set-default-paper-size "a6" 'landscape)
-@end example
-
-Setting the paper size will adjust a number of @code{\paper} variables
-(such as margins). To use a particular paper size with altered
-@code{\paper} variables, set the paper size before setting the variables.
-
-
-@node Page formatting
-@subsection Page formatting
-
-@cindex page formatting
-@cindex margins
-@cindex header, page
-@cindex footer, page
-
-LilyPond will do page layout, set margins, and add headers and
-footers to each page.
-
-The default layout responds to the following settings in the
-@code{\paper} block.
-
-@funindex \paper
-
-@quotation
-@table @code
-@funindex first-page-number
-@item first-page-number
-The value of the page number of the first page. Default is@tie{}1.
-
-@funindex printfirst-page-number
-@item print-first-page-number
-If set to true, will print the page number in the first page. Default is
-false.
-
-@funindex print-page-number
-@item print-page-number
-If set to false, page numbers will not be printed. Default is true.
-
-@funindex paper-width
-@item paper-width
-The width of the page. The default is taken from the current paper size,
-see @ref{Paper size}.
-
-@funindex paper-height
-@item paper-height
-The height of the page. The default is taken from the current paper size,
-see @ref{Paper size}.
-
-@funindex top-margin
-@item top-margin
-Margin between header and top of the page. Default is@tie{}5mm.
-
-@funindex bottom-margin
-@item bottom-margin
-Margin between footer and bottom of the page. Default is@tie{}6mm.
-
-@funindex left-margin
-@item left-margin
-Margin between the left side of the page and the beginning of the
-music. Unset by default, which means that the margins is determined
-based on the @code{paper-width} and @code{line-width} to center the
-score on the paper.
-
-@funindex line-width
-@item line-width
-The length of the systems. Default is @code{paper-width} minus @tie{}20mm.
-
-@funindex head-separation
-@item head-separation
-Distance between the top-most music system and the page header. Default
-is@tie{}4mm.
-
-@funindex foot-separation
-@item foot-separation
-Distance between the bottom-most music system and the page
-footer. Default is@tie{}4mm.
-
-@funindex page-top-space
-@item page-top-space
-Distance from the top of the printable area to the center of the first
-staff. This only works for staves which are vertically small. Big staves
-are set with the top of their bounding box aligned to the top of the
-printable area. Default is@tie{}12mm.
-
-@funindex ragged-bottom
-@item ragged-bottom
-If set to true, systems will not be spread vertically across the page. This
-does not affect the last page. Default is false.
-
-This should be set to true for pieces that have only two or three
-systems per page, for example orchestral scores.
-
-@funindex ragged-last-bottom
-@item ragged-last-bottom
-If set to false, systems will be spread vertically to fill the last
-page. Default is true.
-
-Pieces that amply fill two pages or more should have this set to
-true.
-
-@funindex system-count
-@item system-count
-This variable, if set, specifies into how many lines a score should be
-broken. Unset by default.
-
-@funindex between-system-space
-@item between-system-space
-This dimensions determines the distance between systems. It is the
-ideal distance between the center of the bottom staff of one system
-and the center of the top staff of the next system. Default is@tie{}20mm.
-
-Increasing this will provide a more even appearance of the page at the
-cost of using more vertical space.
-
-@funindex between-system-padding
-@item between-system-padding
-This dimension is the minimum amount of white space that will always
-be present between the bottom-most symbol of one system, and the
-top-most of the next system. Default is@tie{}4mm.
-
-Increasing this will put systems whose bounding boxes almost touch
-farther apart.
-
-
-@funindex horizontal-shift
-@item horizontal-shift
-All systems (including titles and system separators) are shifted by
-this amount to the right. Page markup, such as headers and footers are
-not affected by this. The purpose of this variable is to make space
-for instrument names at the left. Default is@tie{}0.
-
-@funindex after-title-space
-@item after-title-space
-Amount of space between the title and the first system. Default is@tie{}5mm.
-
-@funindex before-title-space
-@item before-title-space
-Amount of space between the last system of the previous piece and the
-title of the next. Default is@tie{}10mm.
-
-@funindex between-title-space
-@item between-title-space
-Amount of space between consecutive titles (e.g., the title of the
-book and the title of a piece). Default is@tie{}2mm.
-
-@funindex printallheaders
-@item printallheaders
-Setting this to #t will print all headers for each \score in a
-\book. Normally only the piece and opus \headers are printed.
-
-@funindex systemSeparatorMarkup
-@item systemSeparatorMarkup
-This contains a markup object, which will be inserted between
-systems. This is often used for orchestral scores. Unset by default.
-
-The markup command @code{\slashSeparator} is provided as a sensible
-default, for example
-
-@lilypond[ragged-right]
-\book {
- \score {
- \relative { c1 \break c1 }
- }
- \paper {
- systemSeparatorMarkup = \slashSeparator
- }
-}
-@end lilypond
-
-@funindex blank-page-force
-@item blank-page-force
-The penalty for having a blank page in the middle of a
-score. This is not used by @code{ly:optimal-breaking} since it will
-never consider blank pages in the middle of a score. Default value
-is 10.
-
-@funindex blank-last-page-force
-@item blank-last-page-force
-The penalty for ending the score on an odd-numbered page.
-Default value is 0.
-
-@funindex page-spacing-weight
-@item page-spacing-weight
-The relative importance of page (vertical) spacing and line (horizontal)
-spacing. High values will make page spacing more important. Default
-value is 1.
-
-@funindex auto-first-page-number
-@item auto-first-page-number
-The page breaking algorithm is affected by the first page number being
-odd or even. If this variable is set to #t, the page breaking algorithm
-will decide whether to start with an odd or even number. This will
-result in the first page number remaining as is or being increased by one.
-
-@end table
-@end quotation
-
-Example:
-
-@example
-\paper@{
- paper-width = 2\cm
- top-margin = 3\cm
- bottom-margin = 3\cm
- ragged-last-bottom = ##t
-@}
-@end example
-
-You can also define these values in Scheme. In that case @code{mm},
-@code{in}, @code{pt}, and @code{cm} are variables defined in
-@file{paper-defaults.ly} with values in millimeters. That is why the
-value must be multiplied in the example
-
-@example
-\paper @{
- #(define bottom-margin (* 2 cm))
-@}
-@end example
-
-The header and footer are created by the functions @code{make-footer}
-and @code{make-header}, defined in @code{\paper}. The default
-implementations are in @file{ly/@/paper@/-defaults@/.ly} and
-@file{ly/@/titling@/-init@/.ly}.
-
-The page layout itself is done by two functions in the
-@code{\paper} block, @code{page-music-height} and
-@code{page-make-stencil}. The former tells the line-breaking algorithm
-how much space can be spent on a page, the latter creates the actual
-page given the system to put on it.
-
-
-@refbugs
-
-The option right-margin is defined but doesn't set the right margin
-yet. The value for the right margin has to be defined adjusting the
-values of @code{left-margin} and @code{line-width}.
-
-The default page header puts the page number and the @code{instrument}
-field from the @code{\header} block on a line.
-
-The titles (from the @code{\header@{@}} section) are treated as a
-system, so @code{ragged-bottom} and @code{ragged-last-bottom} will
-add space between the titles and the first system of the score.
-
-
-@node Music layout
-@section Music layout
-
-@menu
-* Setting global staff size::
-* Score layout::
-@end menu
-
-
-@node Setting global staff size
-@subsection Setting global staff size
-
-@cindex font size, setting
-@cindex staff size, setting
-@funindex layout file
-
-To set the global staff size, use @code{set-global-staff-size}.
-
-@example
-#(set-global-staff-size 14)
-@end example
-
-@noindent
-This sets the global default size to 14pt staff height and scales all
-fonts accordingly.
-
-The Feta font provides musical symbols at eight different
-sizes. Each font is tuned for a different staff size: at a smaller size
-the font becomes heavier, to match the relatively heavier staff lines.
-The recommended font sizes are listed in the following table:
-
-@quotation
-@multitable @columnfractions .15 .2 .22 .2
-
-@item @b{font name}
-@tab @b{staff height (pt)}
-@tab @b{staff height (mm)}
-@tab @b{use}
-
-@item feta11
-@tab 11.22
-@tab 3.9
-@tab pocket scores
-
-@item feta13
-@tab 12.60
-@tab 4.4
-@tab
-
-@item feta14
-@tab 14.14
-@tab 5.0
-@tab
-
-@item feta16
-@tab 15.87
-@tab 5.6
-@tab
-
-@item feta18
-@tab 17.82
-@tab 6.3
-@tab song books
-
-@item feta20
-@tab 20
-@tab 7.0
-@tab standard parts
-
-@item feta23
-@tab 22.45
-@tab 7.9
-@tab
-
-@item feta26
-@tab 25.2
-@tab 8.9
-@tab
-@c modern rental material?
-
-@end multitable
-@end quotation
-
-These fonts are available in any sizes. The context property
-@code{fontSize} and the layout property @code{staff-space} (in
-@internalsref{StaffSymbol}) can be used to tune the size for individual
-staves. The sizes of individual staves are relative to the global size.
-
-@example
-
-@end example
-
-@seealso
-
-This manual: @ref{Selecting notation font size}.
-
-
-@node Score layout
-@subsection Score layout
-
-@funindex \layout
-
-While @code{\paper} contains settings that relate to the page formatting
-of the whole document, @code{\layout} contains settings for score-specific
-layout.
-
-@example
-\layout @{
- indent = 2.0\cm
- \context @{ \Staff
- \override VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 6)
- @}
- \context @{ \Voice
- \override TextScript #'padding = #1.0
- \override Glissando #'thickness = #3
- @}
-@}
-@end example
-
-
-@seealso
-
-This manual: @ref{Changing context default settings}
-
-
-@node Vertical spacing
-@section Vertical spacing
-
-@cindex vertical spacing
-@cindex spacing, vertical
-
-Vertical spacing is controlled by three things: the amount of
-space available (i.e., paper size and margins), the amount of
-space between systems, and the amount of space between
-staves inside a system.
-
-@menu
-* Vertical spacing inside a system::
-* Vertical spacing of piano staves::
-* Vertical spacing between systems::
-* Controlling spacing of individual systems::
-* Two-pass vertical spacing::
-@end menu
-
-
-@node Vertical spacing inside a system
-@subsection Vertical spacing inside a system
-
-@cindex distance between staves
-@cindex staff distance
-@cindex space between staves
-@cindex space inside systems
-
-The height of each system is determined automatically. To prevent
-staves from bumping into each other, some minimum distances are set.
-By changing these, you can put staves closer together. This
-reduces the amount of space each system requires, and may result
-in having more systems per page.
-
-Normally staves are stacked vertically. To make staves maintain a
-distance, their vertical size is padded. This is done with the
-property @code{minimum-Y-extent}. When applied to a
-@internalsref{VerticalAxisGroup}, it controls the size of a horizontal
-line, such as a staff or a line of lyrics. @code{minimum-Y-extent}
-takes a pair of numbers, so
-if you want to make it smaller than its default @code{#'(-4 . 4)}
-then you could set
-
-@example
-\override Staff.VerticalAxisGroup #'minimum-Y-extent = #'(-3 . 3)
-@end example
-
-@noindent
-This sets the vertical size of the current staff to 3 staff spaces on
-either side of the center staff line. The value @code{(-3 . 3)} is
-interpreted as an interval, where the center line is the 0, so the
-first number is generally negative. The numbers need not match;
-for example, the staff can be made larger at the bottom by setting
-it to @code{(-6 . 4)}.
-
-
-@seealso
-
-Internals: Vertical alignment of staves is handled by the
-@internalsref{VerticalAlignment} object. The context parameters
-specifying the vertical extent are described in connection with
-the @internalsref{Axis_group_engraver}.
-
-Example files: @inputfileref{input/regression/,page-spacing.ly},
-@inputfileref{input/regression/,alignment-vertical-spacing.ly}.
-
-
-@node Vertical spacing of piano staves
-@subsection Vertical spacing of piano staves
-
-The distance between staves of a @internalsref{PianoStaff} cannot be
-computed during formatting. Rather, to make cross-staff beaming work
-correctly, that distance has to be fixed beforehand.
-
-The distance of staves in a @code{PianoStaff} is set with the
-@code{forced-distance} property of the
-@internalsref{VerticalAlignment} object, created in
-@internalsref{PianoStaff}.
-
-It can be adjusted as follows
-@example
-\new PianoStaff \with @{
- \override VerticalAlignment #'forced-distance = #7
-@} @{
- ...
-@}
-@end example
-
-@noindent
-This would bring the staves together at a distance of 7 staff spaces,
-measured from the center line of each staff.
-
-The difference is demonstrated in the following example,
-@lilypond[quote,verbatim]
-\relative c'' <<
- \new PianoStaff \with {
- \override VerticalAlignment #'forced-distance = #7
- } <<
- \new Staff { c1 }
- \new Staff { c }
- >>
- \new PianoStaff <<
- \new Staff { c }
- \new Staff { c }
- >>
->>
-@end lilypond
-
-
-@seealso
-
-Example files: @inputfileref{input/regression/,alignment-vertical-spacing.ly}.
-
-
-@node Vertical spacing between systems
-@subsection Vertical spacing between systems
-
-Space between systems are controlled by four @code{\paper} variables,
-
-@example
-\paper @{
- between-system-space = 1.5\cm
- between-system-padding = #1
- ragged-bottom=##f
- ragged-last-bottom=##f
-@}
-@end example
-
-
-@node Controlling spacing of individual systems
-@subsection Controlling spacing of individual systems
-
-It is also possible to change the distance between for each system
-individually. This is done by including the command
-
-@example
-\overrideProperty
-#"Score.NonMusicalPaperColumn"
-#'line-break-system-details
-#'((fixed-alignment-extra-space . 15))
-@end example
-
-@noindent
-at the line break before the system to be changed. The distance
-@code{15} is distributed over all staves that have a fixed distance
-alignment. For example,
-
-@lilypond[ragged-right, fragment, relative=2, staffsize=13]
-\new PianoStaff <<
- \new Staff {
- c1\break
-
- \overrideProperty
- #"Score.NonMusicalPaperColumn"
- #'line-break-system-details
- #'((fixed-alignment-extra-space . 15))
-
- c\break
- }
- \new Staff { c c }
->>
-@end lilypond
-
-The distance for @code{fixed-alignment-extra-space} may also be
-negative.
-
-
-@node Two-pass vertical spacing
-@subsection Two-pass vertical spacing
-
-In order to automatically stretch systems so that they should fill the
-space left on a page, a two-pass technique can be used:
-
-@enumerate
-@item In the first pass, the amount of vertical space used to increase
-the height of each system is computed and dumped to a file.
-@item In the second pass, the systems are stretched according to the
-data in the page layout file.
-@end enumerate
-
-To allow this behaviour, a @code{tweak-key} variable has to be set in
-each score @code{\layout} block, and the tweaks included in each score
-music, using the @code{\scoreTweak} music function.
-
-@quotation
-@verbatim
-%% include the generated page layout file:
-\includePageLayoutFile
-
-\score {
- \new StaffGroup <<
- \new Staff <<
- %% Include this score tweaks:
- \scoreTweak "scoreA"
- { \clef french c''1 \break c''1 }
- >>
- \new Staff { \clef soprano g'1 g'1 }
- \new Staff { \clef mezzosoprano e'1 e'1 }
- \new Staff { \clef alto g1 g1 }
- \new Staff { \clef bass c1 c1 }
- >>
- \header {
- piece = "Score with tweaks"
- }
- %% Define how to name the tweaks for this score:
- \layout { #(define tweak-key "scoreA") }
-}
-@end verbatim
-@end quotation
-
-For the first pass, the @code{dump-tweaks} option should be set to
-generate the page layout file.
-
-@example
-lilypond -b null -d dump-tweaks <file>.ly
-lilypond <file>.ly
-@end example
-
-@node Horizontal spacing
-@section Horizontal Spacing
-
-@cindex horizontal spacing
-@cindex spacing, horizontal
-
-@menu
-* Horizontal spacing overview::
-* New spacing area::
-* Changing horizontal spacing::
-* Line length::
-@end menu
-
-
-@node Horizontal spacing overview
-@subsection Horizontal spacing overview
-
-The spacing engine translates differences in durations into stretchable
-distances (``springs'') of differring lengths. Longer durations get
-more space, shorter durations get less. The shortest durations get a
-fixed amount of space (which is controlled by
-@code{shortest-duration-space} in the @internalsref{SpacingSpanner}
-object). The longer the duration, the more space it gets: doubling a
-duration adds a fixed amount (this amount is controlled by
-@code{spacing-increment}) of space to the note.
-
-For example, the following piece contains lots of half, quarter, and
-8th notes; the eighth note is followed by 1 note head width (NHW).
-The quarter note is followed by 2 NHW, the half by 3 NHW, etc.
-
-@lilypond[quote,fragment,verbatim,relative=1]
-c2 c4. c8 c4. c8 c4. c8 c8
-c8 c4 c4 c4
-@end lilypond
-
-Normally, @code{spacing-increment} is set to 1.2 staff space, which is
-approximately the width of a note head, and
-@code{shortest-duration-space} is set to 2.0, meaning that the
-shortest note gets 2.4 staff space (2.0 times the
-@code{spacing-increment}) of horizontal space. This space is counted
-from the left edge of the symbol, so the shortest notes are generally
-followed by one NHW of space.
-
-If one would follow the above procedure exactly, then adding a single
-32nd note to a score that uses 8th and 16th notes, would widen up the
-entire score a lot. The shortest note is no longer a 16th, but a 32nd,
-thus adding 1 NHW to every note. To prevent this, the shortest
-duration for spacing is not the shortest note in the score, but rather
-the one which occurs most frequently.
-
-
-The most common shortest duration is determined as follows: in every
-measure, the shortest duration is determined. The most common shortest
-duration is taken as the basis for the spacing, with the stipulation
-that this shortest duration should always be equal to or shorter than
-an 8th note. The shortest duration is printed when you run
-@code{lilypond} with the @code{--verbose} option.
-
-These durations may also be customized. If you set the
-@code{common-shortest-duration} in @internalsref{SpacingSpanner}, then
-this sets the base duration for spacing. The maximum duration for this
-base (normally an 8th), is set through @code{base-shortest-duration}.
-
-@funindex common-shortest-duration
-@funindex base-shortest-duration
-@funindex stem-spacing-correction
-@funindex spacing
-
-Notes that are even shorter than the common shortest note are
-followed by a space that is proportional to their duration relative to
-the common shortest note. So if we were to add only a few 16th notes
-to the example above, they would be followed by half a NHW:
-
-@lilypond[quote,fragment,verbatim,relative=2]
-c2 c4. c8 c4. c16[ c] c4. c8 c8 c8 c4 c4 c4
-@end lilypond
-
-
-In the introduction (see @ref{Engraving}), it was explained that stem
-directions influence spacing. This is controlled with the
-@code{stem-spacing-correction} property in the
-@internalsref{NoteSpacing}, object. These are generated for every
-@internalsref{Voice} context. The @code{StaffSpacing} object
-(generated in @internalsref{Staff} context) contains the same property
-for controlling the stem/bar line spacing. The following example shows
-these corrections, once with default settings, and once with
-exaggerated corrections:
-
-@lilypond[quote,ragged-right]
-{
- c'4 e''4 e'4 b'4 |
- b'4 e''4 b'4 e''4|
- \override Staff.NoteSpacing #'stem-spacing-correction = #1.5
- \override Staff.StaffSpacing #'stem-spacing-correction = #1.5
- c'4 e''4 e'4 b'4 |
- b'4 e''4 b'4 e''4|
-}
-@end lilypond
-
-Proportional notation is supported; see @ref{Proportional notation}.
-
-
-@seealso
-
-Internals: @internalsref{SpacingSpanner}, @internalsref{NoteSpacing},
-@internalsref{StaffSpacing}, @internalsref{SeparationItem}, and
-@internalsref{SeparatingGroupSpanner}.
-
-
-@refbugs
-
-There is no convenient mechanism to manually override spacing. The
-following work-around may be used to insert extra space into a score.
-@example
- \once \override Score.SeparationItem #'padding = #1
-@end example
-
-No work-around exists for decreasing the amount of space.
-
-
-@node New spacing area
-@subsection New spacing area
-
-New sections with different spacing parameters can be started with
-@code{newSpacingSection}. This is useful when there are
-sections with a different notions of long and short notes.
-
-In the following example, the time signature change introduces a new
-section, and hence the 16ths notes are spaced wider.
-
-@lilypond[relative,fragment,verbatim,quote]
-\time 2/4
-c4 c8 c
-c8 c c4 c16[ c c8] c4
-\newSpacingSection
-\time 4/16
-c16[ c c8]
-@end lilypond
-
-
-@node Changing horizontal spacing
-@subsection Changing horizontal spacing
-
-Horizontal spacing may be altered with the
-@code{base-shortest-duration} property. Here
-we compare the same music; once without altering
-the property, and then altered. Larger values
-of @code{ly:make-moment} will produce smaller
-music.
-
-@lilypond[relative,verbatim,line-width=12\cm]
-\score {
- \relative c'' {
- g4 e e2 | f4 d d2 | c4 d e f | g4 g g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- d4 d d d | d4 e f2 | e4 e e e | e4 f g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- }
-}
-@end lilypond
-
-@lilypond[relative,verbatim,line-width=12\cm]
-\score {
- \relative c'' {
- g4 e e2 | f4 d d2 | c4 d e f | g4 g g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- d4 d d d | d4 e f2 | e4 e e e | e4 f g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- }
- \layout {
- \context {
- \Score
- \override SpacingSpanner
- #'base-shortest-duration = #(ly:make-moment 1 4)
- }
- }
-}
-@end lilypond
-
-
-@commonprop
-
-By default, spacing in tuplets depends on various non-duration
-factors (such as accidentals, clef changes, etc). To disregard
-such symbols and force uniform equal-duration spacing, use
-@code{Score.SpacingSpanner #'uniform-stretching}. This
-property can only be changed at the beginning of a score,
-
-@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
-\new Score \with {
- \override SpacingSpanner #'uniform-stretching = ##t
-} <<
- \new Staff{
- \times 4/5 {
- c8 c8 c8 c8 c8
- }
- c8 c8 c8 c8
- }
- \new Staff{
- c8 c8 c8 c8
- \times 4/5 {
- c8 c8 c8 c8 c8
- }
- }
->>
-@end lilypond
-
-
-When @code{strict-note-spacing} is set, notes are spaced without
-regard for clefs, bar lines, and grace notes,
-
-@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
-\override Score.SpacingSpanner #'strict-note-spacing = ##t
-\new Staff { c8[ c \clef alto c \grace { c16[ c] } c8 c c] c32[ c32] }
-@end lilypond
-
-
-@node Line length
-@subsection Line length
-
-@cindex page breaks
-@cindex breaking pages
-
-@funindex indent
-@funindex line-width
-@funindex ragged-right
-@funindex ragged-last
-
-@c Although line-width can be set in \layout, it should be set in paper
-@c block, to get page layout right.
-@c Setting indent in \paper block makes not much sense, but it works.
-
-@c Bit verbose and vague, use examples?
-The most basic settings influencing the spacing are @code{indent} and
-@code{line-width}. They are set in the @code{\layout} block. They
-control the indentation of the first line of music, and the lengths of
-the lines.
-
-If @code{ragged-right} is set to true in the @code{\layout} block, then
-systems ends at their natural horizontal length, instead of being spread
-horizontally to fill the whole line. This is useful for
-short fragments, and for checking how tight the natural spacing is.
-
-@cindex page layout
-@cindex vertical spacing
-
-The option @code{ragged-last} is similar to @code{ragged-right}, but
-only affects the last line of the piece. No restrictions are put on
-that line. The result is similar to formatting text paragraphs. In a
-paragraph, the last line simply takes its natural horizontal length.
-@c Note that for text there are several options for the last line.
-@c While Knuth TeX uses natural length, lead typesetters use the same
-@c stretch as the previous line. eTeX uses \lastlinefit to
-@c interpolate between both these solutions.
-
-@example
-\layout @{
- indent = #0
- line-width = #150
- ragged-last = ##t
-@}
-@end example
-
-
-@node Breaks
-@section Breaks
-
-@menu
-* Line breaking::
-* Page breaking::
-* Optimal page breaking::
-* Optimal page turning::
-@end menu
-
-@node Line breaking
-@subsection Line breaking
-
-@cindex line breaks
-@cindex breaking lines
-
-Line breaks are normally computed automatically. They are chosen so
-that lines look neither cramped nor loose, and that consecutive lines
-have similar density.
-
-Occasionally you might want to override the automatic breaks; you can
-do this by specifying @code{\break}. This will force a line break at
-this point. Line breaks can only occur at places where there are bar
-lines. If you want to have a line break where there is no bar line,
-you can force an invisible bar line by entering @code{\bar
-""}. Similarly, @code{\noBreak} forbids a line break at a
-point.
-
-
-@cindex regular line breaks
-@cindex four bar music.
-
-For line breaks at regular intervals use @code{\break} separated by
-skips and repeated with @code{\repeat}:
-@example
-<< \repeat unfold 7 @{
- s1 \noBreak s1 \noBreak
- s1 \noBreak s1 \break @}
- @emph{the real music}
->>
-@end example
-
-@noindent
-This makes the following 28 measures (assuming 4/4 time) be broken every
-4 measures, and only there.
-
-@refcommands
-
-@code{\break}, and @code{\noBreak}.
-@funindex \break
-@funindex \noBreak
-
-@seealso
-
-Internals: @internalsref{LineBreakEvent}.
-
-A linebreaking configuration can now be saved as a @code{.ly} file
-automatically. This allows vertical alignments to be stretched to
-fit pages in a second formatting run. This is fairly new and
-complicated; see @inputfileref{input/regression/,page-layout-twopass.ly}
-for details.
-
-@refbugs
-
-Line breaks can only occur if there is a ``proper'' bar line. A note
-which is hanging over a bar line is not proper, such as
-
-@lilypond[quote,ragged-right,relative=2,fragment,verbatim]
-c4 c2 c2 \break % this does nothing
-c2 c4 | % a break here would work
-c4 c2 c4 ~ \break % as does this break
-c4 c2 c4
-@end lilypond
-
-
-@node Page breaking
-@subsection Page breaking
-
-The default page breaking may be overriden by inserting
-@code{\pageBreak} or @code{\noPageBreak} commands. These commands are
-analogous to @code{\break} and @code{\noBreak}. They should be
-inserted at a bar line. These commands force and forbid a page-break
-from happening. Of course, the @code{\pageBreak} command also forces
-a line break.
-
-Page breaks are computed by the @code{page-breaking} function.
-LilyPond provides two algorithms for computing page
-breaks, @code{ly:optimal-breaking} and @code{ly:page-turn-breaking}. The
-default is @code{ly:optimal-breaking}, but the value can be changed in
-the @code{\paper} block:
-
-@example
-\paper@{
- #(define page-breaking ly:page-turn-breaking)
-@}
-@end example
-
-The old page breaking algorithm is called
-@code{optimal-page-breaks}. If you are having trouble with the new page
-breakers, you can enable the old one as a workaround.
-
-@refcommands
-
-@funindex \pageBreak
-@code{\pageBreak}
-@funindex \noPageBreak
-@code{\noPageBreak}
-
-
-@node Optimal page breaking
-@subsection Optimal page breaking
-
-@funindex ly:optimal-breaking
-
-The @code{ly:optimal-breaking} function is LilyPond's default method of
-determining page breaks. It attempts to find a page breaking that minimizes
-cramping and stretching, both horizontally and vertically. Unlike
-@code{ly:page-turn-breaking}, it has no concept of page turns.
-
-
-@node Optimal page turning
-@subsection Optimal page turning
-
-@funindex ly:page-turn-breaking
-
-Often it is necessary to find a page breaking configuration so that there is
-a rest at the end of every second page. This way, the musician can turn the
-page without having to miss notes. The @code{ly:page-turn-breaking} function
-attempts to find a page breaking minimizing cramping and stretching, but with
-the additional restriction that it is only allowed to introduce page turns
-in specified places.
-
-There are two steps to using this page breaking function. First, you must
-enable it in the @code{\paper} block. Then, you must tell the function
-where you would like to allow page breaks.
-
-There are two ways to achieve the second step. First, you can specify each
-potential page turn manually, by inserting @code{\allowPageTurn} into your
-input file at the appropriate places.
-
-If this is too tedious, you can add a @code{Page_turn_engraver} to a Staff or
-Voice context. The @code{Page_turn_engraver} will scan the context for
-sections without notes (note that it does not scan for rests; it scans for
-the absence of notes. This is so that single-staff polyphony with rests in one
-of the parts does not throw off the @code{Page_turn_engraver}). When it finds
-a sufficiently long section without notes, the @code{Page_turn_engraver} will
-insert an @code{\allowPageTurn} at the final barline in that section, unless
-there is a ``special'' barline (such as a double bar), in which case the
-@code{\allowPageTurn} will be inserted at the final ``special'' barline in
-the section.
-
-@funindex minimumPageTurnLength
-The @code{Page_turn_engraver} reads the context property
-@code{minimumPageTurnLength} to determine how long a note-free section must
-be before a page turn is considered. The default value for
-@code{minimumPageTurnLength} is @code{#(ly:make-moment 1 1)}. If you want
-to disable page turns, you can set it to something very large.
-
-@example
-\new Staff \with @{ \consists "Page_turn_engraver" @}
-@{
- a4 b c d |
- R1 | % a page turn will be allowed here
- a4 b c d |
- \set Staff.minimumPageTurnLength = #(ly:make-moment 5 2)
- R1 | % a page turn will not be allowed here
- a4 b r2 |
- R1*2 | % a page turn will be allowed here
- a1
-@}
-@end example
-
-@funindex minimumRepeatLengthForPageTurn
-The @code{Page_turn_engraver} detects volta repeats. It will only allow a page
-turn during the repeat if there is enough time at the beginning and end of the
-repeat to turn the page back. The @code{Page_turn_engraver} can also disable
-page turns if the repeat is very short. If you set the context property
-@code{minimumRepeatLengthForPageTurn} then the @code{Page_turn_engraver} will
-only allow turns in repeats whose duration is longer than this value.
-
-@refbugs
-
-The @code{Page_turn_engraver} does not respect time-scaled music. For example, the
-following example does not behave as expected:
-
-@example
-\new Staff \with @{ \consists "Page_turn_engraver" @}
-@{
- a4 b c d |
- R1 | % a page turn will be allowed here
- a4 b \times 2/3 @{c d e@} |
- R1 | % a page turn will NOT be allowed here
- a1
-@}
-@end example
-
-There should only be one @code{Page_turn_engraver} in a score. If there is more
-than one, they will interfere with each other.
-
-
-@node Displaying spacing
-@section Displaying spacing
-
-@funindex annotate-spacing
-@cindex Spacing, display of properties
-
-To graphically display the dimensions of vertical properties
-that may be altered for page formatting, use
-
-@lilypond[verbatim]
-\paper { annotate-spacing = ##t }
-{ c4 }
-@end lilypond
-
-@noindent
-@c FIXME: really bad vagueness due to bug in annotate-spacing. -gp
-Some unit dimensions are measured in staff spaces, while others
-are measured in millimeters.
-The pairs
-(@var{a},@var{b}) are intervals, where @var{a} is the lower edge and
-@var{b} the upper edge of the interval.
-
-
* Building complicated functions::
* Markup programmer interface::
* Contexts for programmers::
-* Scheme procedures as properties::
@end menu
@menu
* Overview of music functions::
* Simple substitution functions::
-* Paired substitution functions::
+* Paired substition functions::
* Mathematics in functions::
* Void functions::
@end menu
@node Overview of music functions
@subsection Overview of music functions
-Making a function which substitutes a variable into LilyPond
+Making a funcion which substitutes a variable into LilyPond
code is easy. The general form of these functions is
@example
@end lilypond
-@node Paired substitution functions
-@subsection Paired substitution functions
+@node Paired substition functions
+@subsection Paired substition functions
Some @code{\override} commands require a pair of numbers
(called a @code{cons cell} in Scheme). To pass these numbers
\withAlt #1.5 {c' c'} c'2 }
@end lilypond
+
@node Void functions
@subsection Void functions
@end example
Scheme code is evaluated as soon as the parser encounters it. To
-define some Scheme code in a macro (to be called later), use
+define some scheme code in a macro (to be called later), use
@ref{Void functions} or
@example
interfaces, for example, a note is an @code{event}, but it is also a
@code{note-event}, a @code{rhythmic-event}, and a
@code{melodic-event}. All classes of music are listed in the
-Program reference, under
+Profram reference, under
@internalsref{Music classes}.
@item
@subsection Displaying music expressions
@cindex internal storage
-@funindex \displayMusic
-@funindex \displayLilyMusic
+@findex \displayMusic
+@findex \displayLilyMusic
When writing a music function it is often instructive to inspect how
a music expression is stored internally. This can be done with the
@end example
The @code{display-scheme-music} function is the function used by
-@code{\displayMusic} to display the Scheme representation of a music
+@code{\displayMusic} to display the scheme representation of a music
expression.
@example
(ly:make-pitch 0 0 0))
@end example
-Then the note pitch is accessed through the @code{'pitch} property
+Then the note pitch is accessed thourgh the @code{'pitch} property
of the @code{NoteEvent} object,
@example
@code{SequentialMusic} with the two @code{EventChords}.
@example
-doubleSlur = #(define-music-function (parser location note) (ly:music?)
+doubleSlur = #(def-music-function (parser location note) (ly:music?)
"Return: @{ note ( note ) @}.
`note' is supposed to be an EventChord."
(let ((note2 (ly:music-deep-copy note)))
used elsewhere.
Now we have a @code{result-event-chord}, which is a
-@code{NoteEventChord} expression and is a copy of @code{event-chord}. We
+@code{oteEventChord} expression and is a copy of @code{event-chord}. We
add the marcato to its elements list property.
@example
@end multitable
@end quotation
-The whole Scheme language is accessible inside the
+The whole scheme language is accessible inside the
@code{markup} macro. For example, You may use function calls inside
@code{markup} in order to manipulate character strings. This is
useful when defining new markup commands (see
@subsection New markup command definition
New markup commands can be defined
-with the @code{define-markup-command} Scheme macro.
+with the @code{define-markup-command} scheme macro.
@lisp
(define-markup-command (@var{command-name} @var{layout} @var{props} @var{arg1} @var{arg2} ...)
@subsection Context evaluation
@cindex calling code during interpreting
-@funindex \applyContext
+@findex \applyContext
Contexts can be modified during interpretation with Scheme code. The
syntax for this is
@cindex calling code on layout objects
-@funindex \applyOutput
+@findex \applyOutput
The most versatile way of tuning an object is @code{\applyOutput}. Its
(set! (ly:grob-property grob 'transparent) #t)))
@end example
-
-@node Scheme procedures as properties
-@section Scheme procedures as properties
-
-Properties (like thickness, direction, etc.) can be set at fixed values
-with \override, e.g.
-
-@example
-\override Stem #'thickness = #2.0
-@end example
-
-Properties can also be set to a Scheme procedure,
-
-@lilypond[fragment,verbatim,quote,relative=2]
-\override Stem #'thickness = #(lambda (grob)
- (if (= UP (ly:grob-property grob 'direction))
- 2.0
- 7.0))
-c b a g b a g b
-@end lilypond
-
-Procedures may also be combined like that with
-"grob closure". Here is a setting from
-@code{AccidentalSuggestion},
-
-@example
-(X-offset .
- ,(ly:make-simple-closure
- `(,+
- ,(ly:make-simple-closure
- (list ly:self-alignment-interface::centered-on-x-parent))
- ,(ly:make-simple-closure
- (list ly:self-alignment-interface::x-aligned-on-self)))))
-@end example
-
-
soprano part).
@example
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' @{
\clef treble
\key c \major
\new Lyrics \lyricsto "one" \text
>>
\layout @{ @}
- \midi @{ @}
+ \midi @{ \tempo 4=60 @}
@}
@end example
Now we want to add a cello part. Let's look at the ``Notes only'' example:
@example
-\version "2.9.13"
+\version "2.7.39"
melody = \relative c' @{
\clef treble
\key c \major
\score @{
\new Staff \melody
\layout @{ @}
-\midi @{ @}
+\midi @{ \tempo 4=60 @}
@}
@end example
notes.
@example
-\version "2.9.13"
+\version "2.7.39"
sopranoMusic = \relative c' @{
\clef treble
\key c \major
\new Lyrics \lyricsto "one" \sopranoLyrics
>>
\layout @{ @}
- \midi @{ @}
+ \midi @{ \tempo 4=60 @}
@}
@end example
\new Staff \celloMusic
>>
\layout @{ @}
- \midi @{ @}
+ \midi @{ \tempo 4=60 @}
@}
@end example
easily fixed. Here's the complete soprano and cello template.
@lilypond[quote,verbatim,ragged-right]
-\version "2.9.13"
+\version "2.7.39"
sopranoMusic = \relative c' {
\clef treble
\key c \major
\new Staff \celloMusic
>>
\layout { }
- \midi { }
+ \midi { \tempo 4=60 }
}
@end lilypond
\score @{
@{ c'4 a b c' @}
\layout @{ @}
+ \paper @{ @}
\midi @{ @}
\header @{ @}
@}
@node Scheme tutorial
@appendix Scheme tutorial
-@funindex #
+@findex #
@cindex Scheme
@cindex GUILE
@cindex Scheme, in-line code
@item Booleans
Boolean values are True or False. The Scheme for True is @code{#t}
and False is @code{#f}.
-@funindex ##t
-@funindex ##f
+@findex ##t
+@findex ##f
@item Numbers
Numbers are entered in the standard fashion,
#'twentyFour
@end example
-@funindex #'symbol
+@findex #'symbol
@cindex quoting in Scheme
The quote mark @code{'} prevents the Scheme interpreter from substituting
#'(staff clef key-signature)
#'((1) (2))
@end example
-
-
-
@ifhtml
the
@end ifhtml
-@ref{Cheat sheet}, which is a table listing of the most common
-commands for quick reference.
+@ref{Cheat sheet}, which is a table listing all commands for quick
+reference.
@menu
* First steps::
@node More about pitches
@section More about pitches
-A @rglos{sharp} pitch is made by adding @samp{is} to
-the name, a @rglos{flat} pitch by adding @samp{es}. As
+A @rglos{sharp} (@texisharp{}) pitch is made by adding @samp{is} to
+the name, a @rglos{flat} (@texiflat{}) pitch by adding @samp{es}. As
you might expect, a @rglos{double sharp} or @rglos{double flat} is
made by adding @samp{isis} or @samp{eses}@footnote{This syntax
derived from note naming conventions in Nordic and Germanic languages,
solution is to use `relative octave' mode. This is the
most convenient way to copy existing music.
-In relative mode, a note without octavation quotes (i.e., the @code{'}
+In relative mode, a note without octavation quotes (i.e. the @code{'}
or @code{,} after a note) is chosen so that it is closest to the
previous one. For example, @samp{c f} goes up while @samp{c g} goes
down.
To mark a file for version 2.6.0, use
@example
-\version "2.9.13"
+\version "2.6.0"
@end example
@noindent
resulting in a centered hyphen between two syllables
@example
-A -- le gri -- a
+Twin -- kle twin -- kle
@end example
-@c no ragged-right here, because otherwise the hypens get lost.
-@lilypond[fragment,quote]
+@lilypond[fragment,quote,ragged-right]
<<
\relative {
\time 2/4
f4 f c' c
}
- \addlyrics { A -- le gri -- a }
+ \addlyrics { Twin -- kle twin -- kle }
>>
@end lilypond
* Fixing overlapping notation::
* Common tweaks::
* Default files::
-* Fitting music onto fewer pages::
* Advanced tweaks with Scheme::
@end menu
\once \override TextScript #'staff-padding = #2.6
c4^"piu mosso" fis a g
\break
-c'4^"piu mosso" b a b
+c,,4^"piu mosso" b a b
\once \override TextScript #'padding = #2.6
c4^"piu mosso" d e f
\once \override TextScript #'staff-padding = #2.6
@end quotation
@noindent
-So to move dynamics around vertically, we use
+So to move dynamics around, we use
@example
\override DynamicLineSpanner #'padding = #2.0
@multitable @columnfractions .33 .66
@headitem Object type @tab Object name
-@item Dynamics (vertically) @tab @code{DynamicLineSpanner}
-@item Dynamics (horizontally) @tab @code{DynamicText}
+@item Dynamics @tab @code{DynamicLineSpanner}
@item Ties @tab @code{Tie}
@item Slurs @tab @code{Slur}
@item Articulations @tab @code{Script}
a substantial amount of technical knowledge or time is required
to understand these files.
-@itemize @bullet
+@itemize bullet
@item Linux: @file{@{INSTALLDIR@}/lilypond/usr/share/lilypond/current/}
@file{ly/declarations-init.ly} define all the common tweaks.
-@node Fitting music onto fewer pages
-@section Fitting music onto fewer pages
-
-Sometimes you can end up with one or two staves on a second
-(or third, or fourth...) page. This is annoying, especially
-if you look at previous pages and it looks like there is plenty
-of room left on those.
-
-When investigating layout issues, @code{annotate-spacing} is
-an invaluable tool. This command prints the values of various
-layout spacing commands; see @ref{Displaying spacing} for more
-details. From the output of @code{annotate-spacing}, we can
-see which margins we may wish to alter.
-
-Other than margins, there are a few other options to save space:
-
-@itemize
-@item
-You may tell LilyPond to place systems as close together as
-possible (to fit as many systems as possible onto a page), but
-then to space those systems out so that there is no blank
-space at the bottom of the page.
-
-@example
-\paper @{
-between-system-padding = #0.1
-between-system-space = #0.1
-ragged-last-bottom = ##f
-ragged-bottom = ##f
-@}
-@end example
-
-@item
-You may force the number of systems (i.e., if LilyPond wants
-to typeset some music with 11 systems, you could force it to
-use 10).
-
-@example
-\paper @{
-system-count = #10
-@}
-@end example
-
-@item
-Avoid (or reduce) objects which increase the vertical size of
-a system. For example, volta repeats (or alternate repeats)
-require extra space. If these repeats are spread over two
-systems, they will take up more space than one system with
-the volta repeats and another system without.
-
-Another example is moving dynamics which ``stick out'' of
-a system.
-
-@lilypond[verbatim,quote,fragment]
-\relative c' {
- e4 c g\f c
- \override DynamicLineSpanner #'padding = #-1.8
- \override DynamicText #'extra-offset = #'( -2.1 . 0)
- e4 c g\f c
-}
-@end lilypond
-
-@item
-Alter the horizontal spacing via @code{SpacingSpanner}. See
-@ref{Changing horizontal spacing} for more details.
-
-@lilypond[verbatim,quote]
-\score {
- \relative c'' {
- g4 e e2 | f4 d d2 | c4 d e f | g4 g g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- d4 d d d | d4 e f2 | e4 e e e | e4 f g2 |
- g4 e e2 | f4 d d2 | c4 e g g | c,1 |
- }
- \layout {
- \context {
- \Score
- \override SpacingSpanner
- #'base-shortest-duration = #(ly:make-moment 1 4)
- }
- }
-}
-@end lilypond
-
-@end itemize
-
-
@node Advanced tweaks with Scheme
@section Advanced tweaks with Scheme
@menu
* Suggestions for writing LilyPond files::
-* Saving typing with identifiers and functions::
-* Style sheets::
+* Typesetting existing music::
* Updating old files::
* Troubleshooting (taking it all apart)::
+* Saving typing with identifiers and functions::
+* Style sheets::
@end menu
little examples in the tutorial, but whole pieces. But how should you
go about doing it?
-As long as LilyPond can understand your files and produces the output
-that you want, it doesn't matter what your files look like. However,
-there are a few other things to consider when writing lilypond files.
-
-@itemize @bullet
-@item What if you make a mistake? The structure of a lilypond
-file can make certain errors easier (or harder) to find.
-
-@item What if you want to share your files with somebody
-else? In fact, what if you want to alter your own files in
-a few years? Some lilypond files are understandable at
-first glance; other files may leave you scratching your head
-for an hour.
-
-@item What if you want to upgrade your lilypond file for use
-with a later version of lilypond? The input syntax changes
-occasionally as lilypond improves. Most changes can be
-done automatically with @code{convert-ly}, but some changes
-might require manual assistance. Lilypond files can be
-structured in order to be easier (or header) to update.
-@end itemize
-
-@menu
-* General suggestions::
-* Typesetting existing music::
-* Large projects::
-@end menu
-
-
-@node General suggestions
-@subsection General suggestions
+The best answer is ``however you want to do it.'' As long as LilyPond
+can understand your files and produces the output that you want, it
+doesn't matter what your files look like. That said, sometimes we
+make mistakes when writing files. If LilyPond can't understand your
+files, or produces output that you don't like, how do you fix the
+problem?
Here are a few suggestions that can help you to avoid or fix
problems:
@itemize @bullet
@item @strong{Include @code{\version} numbers in every file}. Note that all
-templates contain a @code{\version "2.9.13"} string. We
+templates contain a @code{\version "2.8.0"} string. We
highly recommend that you always include the @code{\version}, no matter
how small your file is. Speaking from personal experience, it's
quite frustrating to try to remember which version of LilyPond you were
imbalance
in the number of @code{@{} and @code{@}}.
-@item @strong{Explicity add durations} at the beginnings of sections
-and identifiers. If you specify @code{c4 d e} at the beginning of a
-phrase (instead of just @code{c d e}) you can save yourself some
-problems if you rearrange your music later.
-
-@item @strong{Separate tweaks} from music definitions. See
-@ref{Saving typing with identifiers and functions} and
-@ref{Style sheets}.
-
@end itemize
@node Typesetting existing music
-@subsection Typesetting existing music
+@section Typesetting existing music
If you are entering music from an existing score (i.e., typesetting a
piece of existing sheet music),
@end itemize
-@node Large projects
-@subsection Large projects
+@node Updating old files
+@section Updating old files
+
+The LilyPond input syntax occasionally changes. As LilyPond itself
+improves, the syntax (input language) is modified accordingly. Sometimes
+these changes are made to make the input easier to read and write or
+sometimes the changes are made to accomodate new features of LilyPond.
+
+LilyPond comes with a file that makes this updating easier:
+@code{convert-ly}. For details about how to run this program, see
+@ref{Updating files with convert-ly}.
-When working on a large project, having a clear structure to your
-lilypond files becomes vital.
+Unforunately, @code{convert-ly} cannot handle all input changes. It
+takes care of simple search-and-replace changes (such as @code{raggedright}
+becoming @code{ragged-right}), but some changes are too
+complicated. The syntax changes that @code{convert-ly} cannot handle
+are listed in @ref{Updating files with convert-ly}.
-@itemize @bullet
+For example, in LilyPond 2.4 and earlier, accents and non-English
+letters were entered using LaTeX -- for example,
+"@code{No\"el}" (this would print the French word for
+`Christmas'). In LilyPond 2.6 and above, the special
+"@code{ë}" must be entered directly into the LilyPond file as an
+UTF-8 character. @code{convert-ly} cannot change all the LaTeX
+special characters into UTF-8 characters; you must manually update
+your old LilyPond files.
-@item @strong{Use an identifier for each voice}, with a minimum of
-structure inside the definition. The structure of the
-@code{\score} section is the most likely thing to change;
-the @code{violin} definition is extremely unlikely to change
-in a new version of LilyPond.
+
+@node Troubleshooting (taking it all apart)
+@section Troubleshooting (taking it all apart)
+
+Sooner or later, you will write a file that LilyPond cannot
+compile. The messages that LilyPond gives may help
+you find the error, but in many cases you need to do some
+investigation to determine the source of the problem.
+
+The most powerful tools for this purpose are the
+single line comment (indicated by @code{%}) and the block
+comment (indicated by @code{%@{ ... %@}}). If you don't
+know where a problem is, start commenting out huge portions
+of your input file. After you comment out a section, try
+compiling the file again. If it works, then the problem
+must exist in the portion you just commented. If it doesn't
+work, then keep on commenting out material until you have
+something that works.
+
+In an extreme case, you might end up with only
@example
-violin = \relative c'' @{
-g4 c'8. e16
-@}
-...
\score @{
- \new GrandStaff @{
- \new Staff @{
- \violin
- @}
- @}
+ <<
+ % \melody
+ % \harmony
+ % \bass
+ >>
+ \layout@{@}
@}
@end example
-@item @strong{Separate tweaks from music definitions}. This
-point was made in @ref{General suggestions}, but for large
-projects it is absolutely vital. We might need to change
-the definition of @code{fthenp}, but then we only need
-to do this once, and we can still avoid touching anything
-inside @code{violin}.
+@noindent
+(in other words, a file without any music)
+
+If that happens, don't give up. Uncomment a bit -- say,
+the bass part -- and see if it works. If it doesn't work,
+then comment out all of the bass music (but leave
+@code{\bass} in the @code{\score} uncommented.
@example
-fthenp = _\markup@{
- \dynamic f \italic \small @{ 2nd @} \hspace #0.1 \dynamic p @}
-violin = \relative c'' @{
-g4\fthenp c'8. e16
+bass = \relative c' @{
+%@{
+ c4 c c c
+ d d d d
+%@}
@}
@end example
-@end itemize
+Now start slowly uncommenting more and more of the
+@code{bass} part until you find the problem line.
@node Saving typing with identifiers and functions
@example
%%% global.ly
-\version "2.9.13"
+\version "2.8.0"
#(ly:set-option 'point-and-click #f)
\include "../init/init-defs.ly"
\include "../init/init-layout.ly"
@end example
-@node Updating old files
-@section Updating old files
-
-The LilyPond input syntax occasionally changes. As LilyPond itself
-improves, the syntax (input language) is modified accordingly. Sometimes
-these changes are made to make the input easier to read and write or
-sometimes the changes are made to accomodate new features of LilyPond.
-
-LilyPond comes with a file that makes this updating easier:
-@code{convert-ly}. For details about how to run this program, see
-@ref{Updating files with convert-ly}.
-
-Unforunately, @code{convert-ly} cannot handle all input changes. It
-takes care of simple search-and-replace changes (such as @code{raggedright}
-becoming @code{ragged-right}), but some changes are too
-complicated. The syntax changes that @code{convert-ly} cannot handle
-are listed in @ref{Updating files with convert-ly}.
-
-For example, in LilyPond 2.4 and earlier, accents and non-English
-letters were entered using LaTeX -- for example,
-"@code{No\"el}" (this would print the French word for
-`Christmas'). In LilyPond 2.6 and above, the special
-"@code{ë}" must be entered directly into the LilyPond file as an
-UTF-8 character. @code{convert-ly} cannot change all the LaTeX
-special characters into UTF-8 characters; you must manually update
-your old LilyPond files.
-
-
-@node Troubleshooting (taking it all apart)
-@section Troubleshooting (taking it all apart)
-
-Sooner or later, you will write a file that LilyPond cannot
-compile. The messages that LilyPond gives may help
-you find the error, but in many cases you need to do some
-investigation to determine the source of the problem.
-
-The most powerful tools for this purpose are the
-single line comment (indicated by @code{%}) and the block
-comment (indicated by @code{%@{ ... %@}}). If you don't
-know where a problem is, start commenting out huge portions
-of your input file. After you comment out a section, try
-compiling the file again. If it works, then the problem
-must exist in the portion you just commented. If it doesn't
-work, then keep on commenting out material until you have
-something that works.
-
-In an extreme case, you might end up with only
-
-@example
-\score @{
- <<
- % \melody
- % \harmony
- % \bass
- >>
- \layout@{@}
-@}
-@end example
-
-@noindent
-(in other words, a file without any music)
-
-If that happens, don't give up. Uncomment a bit -- say,
-the bass part -- and see if it works. If it doesn't work,
-then comment out all of the bass music (but leave
-@code{\bass} in the @code{\score} uncommented.
-
-@example
-bass = \relative c' @{
-%@{
- c4 c c c
- d d d d
-%@}
-@}
-@end example
-
-Now start slowly uncommenting more and more of the
-@code{bass} part until you find the problem line.
-
-
## value of DOCUMENTATION here.
documentation-dir=$(if $(findstring no,$(DOCUMENTATION)),,Documentation)
-SCRIPTS = configure autogen.sh lexer-gcc-3.1.sh Doxyfile
+SCRIPTS = configure aclocal.m4 autogen.sh lexer-gcc-3.1.sh Doxyfile
README_FILES = ChangeLog COPYING DEDICATION ROADMAP THANKS HACKING
-TOPDOC_FILES=AUTHORS README INSTALL NEWS
-TOPDOC_TXT_FILES = $(addprefix $(top-build-dir)/Documentation/topdocs/$(outdir)/,$(addsuffix .txt,$(TOPDOC_FILES)))
+README_TXT_FILES = AUTHORS.txt README.txt INSTALL.txt NEWS.txt
IN_FILES := $(call src-wildcard,*.in)
-
PATCH_FILES = emacsclient.patch server.el.patch darwin.patch
EXTRA_DIST_FILES = VERSION .cvsignore SConstruct \
$(README_FILES) $(SCRIPTS) $(IN_FILES) $(PATCH_FILES)
+NON_ESSENTIAL_DIST_FILES = $(README_TXT_FILES)
INSTALLATION_DIR=$(local_lilypond_datadir)
INSTALLATION_FILES=$(config_make) VERSION
STEPMAKE_TEMPLATES=toplevel po install
include $(depth)/make/stepmake.make
-local-dist: dist-toplevel-txt-files
-
-dist-toplevel-txt-files:
- -mkdir -p $(distdir)
- ln $(TOPDOC_TXT_FILES) $(distdir)/
- ln $(top-src-dir)/stepmake/aclocal.m4 $(distdir)/
-
doc:
$(MAKE) -C Documentation
echo '<html><body>Redirecting to the documentation index...</body></html>' >> $(outdir)/index.html
cd $(top-build-dir) && $(FIND) . -name '*.html' -print | $(footifymail) xargs $(footify)
-
+ cd $(top-build-dir) && find . -name \*.html~ -print | xargs rm -f
cd $(top-build-dir) && find Documentation input \
$(web-ext:%=-path '*/out-www/*.%' -or) -type l \
- | grep -v 'lily-[0-9].*.pdf' \
> $(outdir)/weblist
ls $(outdir)/*.html >> $(outdir)/weblist
-## urg: this is too hairy, should write a python script to do this.
-
## rewrite file names so we lose out-www
- rm -rf $(outdir)/web-root/
- mkdir $(outdir)/web-root/
-## urg slow.
+ rm -rf $(outdir)/web-root/
+ mkdir $(outdir)/web-root/
cat $(outdir)/weblist | (cd $(top-build-dir); tar -cf- -T- ) | \
tar -C $(outdir)/web-root/ -xf -
for dir in $(outdir)/web-root/ ; do \
tree-bin = $(tree-prefix)/bin
tree-lib = $(tree-prefix)/lib
tree-share = $(tree-prefix)/share
-tree-share-prefix = $(tree-share)/lilypond/$(TOPLEVEL_VERSION)
-tree-share-prefix-current = $(tree-share)/lilypond/current
-tree-lib-prefix = $(tree-lib)/lilypond/$(TOPLEVEL_VERSION)
-tree-lib-prefix-current = $(tree-lib)/lilypond/current
+tree-share-prefix = $(tree-share)/lilypond/current
+tree-lib-prefix = $(tree-lib)/lilypond/current
C_DIRS = flower lily
c-clean:
cd $(top-build-dir)/$(outbase) && rm -rf bin lib share
mkdir -p $(tree-bin)
mkdir -p $(tree-share-prefix)
- ln -s $(TOPLEVEL_VERSION) $(tree-share-prefix-current)
mkdir -p $(tree-lib-prefix)
- ln -s $(TOPLEVEL_VERSION) $(tree-lib-prefix-current)
mkdir -p $(tree-share-prefix)/dvips
mkdir -p $(tree-share-prefix)/elisp
mkdir -p $(tree-share-prefix)/fonts
-cd $(tree-share-prefix)/fonts/type1 && \
ln -s ../../../../../../mf/$(outconfbase)/*.pfa .
+
TAGS.make: dummy
etags -o $@ $(find $(srcdir) -name 'GNUmakefile*' -o -name '*.make')
-local-clean: build-dir-setup-clean local-web-clean
-
-local-web-clean:
- rm -rf $(outdir)/web-root/
-
-
-
+local-clean: build-dir-setup-clean
build-dir-setup-clean:
cd $(top-build-dir) && rm -rf share
need to install that development version; you can run it from the
build tree.
-put the following script in your PATH, with $LILY_SRC_DIR set to the
-source directory.
+Use the scripts below to configure and select to use the
+lilypond from the local build tree like this
- #!/bin/sh
+ clily && make
+ lily/out/lilypond input/simple.ly
+
+or
+
+ ./configure && make
+ LILYPONDPREFIX=$(pwd)/out out/lily/lilypond input/simple.ly
+
+
+clily:
+#!/bin/bash
+
+[ -x configure ] || ./autogen.sh --noconf
+rm -f config.cache
+./configure --prefix=$(pwd)/out --infodir=$(pwd)/share/info --disable-optimising --enable-gui "$@"
+
+here-lily:
+# source me - switching to older versions of LilyPond
+
+export PATH=$(pwd)/lily/out:$(pwd)/scripts/out:$PATH
+
+unset LILYPONDPREFIX
+unset TEXMF
+
+# ugh: must fool-proof other TeX environment variables
+TEXINPUTS=:
+MFINPUTS=:
+TFMFONTS=:
+
+. VERSION
+FULL_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$PATCH_LEVEL
+if [ -n "$MY_PATCH_LEVEL" ]; then
+ FULL_VERSION=$FULL_VERSION.$MY_PATCH_LEVEL
+fi
+
+datadir=$(pwd)/share/lilypond/$FULL_VERSION
+export TEXMF="{$datadir,"`kpsexpand \\$TEXMF`"}"
+
+export GS_FONTPATH="$datadir/fonts/type1:/usr/share/texmf/fonts/type1/bluesky/cm:/usr/share/texmf/fonts/type1/public/ec-fonts-mftraced"
+export GS_LIB="$datadir/ps:$GS_FONTPATH"
- exec $LILY_SRC_DIR/out/bin/lilypond --relocate "$@"
--- /dev/null
+
+
+INSTALL - compiling and installing GNU LilyPond
+***********************************************
+
+Abstract
+========
+
+ This document explains what you need to install LilyPond, and what
+you should do. If you are going to compile and install LilyPond often,
+e.g. when doing development, you might want to check out the
+`buildscripts/set-lily.sh' script. It sets some environment variables
+and symlinks, which comes in handly when you have to compile LilyPond
+more often.
+
+Obtaining
+=========
+
+ You can get the latest version of LilyPond at
+ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/
+(ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/).
+
+ _If you upgrade by patching do remember to rerun autoconf after
+applying the patch_.
+
+ If you do not want to download the entire archive for each version,
+the safest method for upgrading is to use `xdelta', see
+`ftp://ftp.xcf.berkeley.edu/pub/xdelta/'.
+
+ The following command produces `lilypond-1.1.55.tar.gz' from
+`lilypond-1.1.54' identical (up to compression dates) to the .55 on the
+FTP site.
+ xdelta patch lilypond-1.1.54-1.1.55.xd lilypond-1.1.54.tar.gz
+
+Prerequisites
+=============
+
+ For compilation you need:
+
+ * A GNU system: GNU LilyPond is known to run on these GNU systems:
+ Linux (PPC, intel), FreeBSD, AIX, NeXTStep, IRIX, Digital Unix
+ and Solaris.
+
+ * Lots of disk space: LilyPond takes between 30 and 100 mb to
+ compile if you use debugging information. If you are short on
+ disk-space run configure with `--disable-debugging'.
+
+ * Although we recommend to use Unix, LilyPond is known to run on
+ Windows NT/95/98 as well. See Section Windows NT/95,es.
+
+ * EGCS 1.1 or newer. Check out `ftp://ftp.gnu.org/pub/gcc/'.
+
+ * Python 1.5, Check out `ftp://ftp.python.org' or
+ `ftp://ftp.cwi.nl/pub/python'.
+
+ * GUILE 1.3.4, check out
+ http://www.gnu.org/software/guile/guile.html
+ (http://www.gnu.org/software/guile/guile.html).
+
+ * GNU make. Check out ftp://ftp.gnu.org/make/
+ (ftp://ftp.gnu.org/make/).
+
+ * Flex (version 2.5.4 or newer). Check out ftp://ftp.gnu.org/flex/
+ (ftp://ftp.gnu.org/flex/).
+
+ * Bison (version 1.25 or newer). Check out ftp://ftp.gnu.org/bison/
+ (ftp://ftp.gnu.org/bison/).
+
+ * Texinfo. Check out ftp://ftp.gnu.org/pub/texinfo/
+ (ftp://ftp.gnu.org/pub/texinfo/). Most documentation is in
+ texinfo.
+
+ * The geometry package for LaTeX is needed to use ly2dvi. Available
+ at
+ ftp://ftp.ctan.org/tex-archive/macros/latex/contrib/supported/geometry
+ (ftp://ftp.ctan.org/tex-archive/macros/latex/contrib/supported/geometry)
+ or at mirror site ftp://ftp.dante.de (ftp://ftp.dante.de)
+
+ * MetaPost, if you want to use direct PostScript output. Please note
+ that tetex-0.4pl8 (included with Redhat 5.x) does not include
+ `mfplain.mp', which is needed for producing the scaleable font
+ files.
+
+
+Running
+=======
+
+ GNU LilyPond does use a lot of resources. For operation you need the
+following software
+
+ * TeX
+
+ * A PostScript printer and/or viewer (such as Ghostscript) is
+ strongly recommended. Xdvi will show all embedded PostScript
+ too if you have Ghostscript installed.
+
+ * GUILE 1.3.4, check out http://www.gnu.org/software/guile/
+ (http://www.gnu.org/programs/guile.html)
+
+ For running LilyPond successfully you have to help TeX and MetaFont
+find various files. The recommended way of doing so is adjusting the
+environment variables in the start-up scripts of your shell. An
+example is given here for the Bourne shell:
+ export MFINPUTS="/usr/local/share/lilypond/mf:"
+ export TEXINPUTS="/usr/local/share/lilypond/tex:/usr/local/share/lilypond/ps:"
+
+ The empty path component represents TeX and MetaFont's default
+search paths. Scripts with the proper paths for the bourne and C-shell
+respectively are generated in `buildscripts/out/lilypond-profile' and
+`buildscripts/out/lilypond-login' during compilation.
+
+ LilyPond is a hiddeously big, slow and bloated program. A fast CPU
+and plenty of RAM is recommended for comfortable use.
+
+Website
+=======
+
+ The website is the most convenient form to use for reading the
+documentation on-line documentation. It is made by entering
+
+ make website
+ This does require a fully functioning
+
+ If you want to auto-generate Lily's website, you'll need some
+additional conversion tools.
+
+ * xpmtoppm (from the Portable Bitmap Utilities) (For RedHat Linux
+ users: it is included within the package libgr-progs).
+ the original is at
+ ftp://ftp.x.org/contrib/utilities/netpbm-1mar1994.p1.tar.gz
+ (ftp://ftp.x.org/contrib/utilities/netpbm-1mar1994.p1.tar.gz)
+
+ * pnmtopng, which is also in libgr-progs for RedHat. The original is
+ at
+ ftp://swrinde.nde.swri.edu/pub/png/applications/pnmtopng-2.37.2.tar.gz
+ (ftp://swrinde.nde.swri.edu/pub/png/applications/pnmtopng-2.37.2.tar.gz).i
+
+ The version of `pnmtopng' that is distributed with RedHat 5.1 and
+ 5.2 contains a bug: pnmtopng is dynamically linked to the wrong
+ version of libpng, which results in cropped images. Recompile it
+ from source, and make sure that the pnmtopng binary is linked
+ statically to the libpng that is included in libgr. RedHat 6.0
+ does not have this problem.
+
+ tar xzf libgr-2.0.13.tar.gz
+ make
+ cd png
+ rm libpng.so*
+ make pnmtopng
+
+ You can then install the new pnmtopng into `/usr/local/bin/'
+
+ * Bib2html http://pertsserver.cs.uiuc.edu/~hull/bib2html.
+ (http://pertsserver.cs.uiuc.edu/~hull/bib2html.) Which, in
+ turn depends on man2html for proper installation. man2html can be
+ had from
+ http://askdonald.ask.uni-karlsruhe.de/hppd/hpux/Networking/WWW/Man2html-1.05
+ (http://askdonald.ask.uni-karlsruhe.de/hppd/hpux/Networking/WWW/Man2html-1.05).
+
+ The website will build without this utility, but you will not see
+ our hypertextified bibliography.
+
+ * Doc++ (optional) to read the source code.
+
+
+Configuring and compiling
+=========================
+
+ to install GNU LilyPond, simply type:
+
+ gunzip -c lilypond-x.y.z | tar xf -
+ cd lilypond-x.y.z
+ ./configure # fill in your standard prefix with --prefix
+ make
+ make install
+
+ This will install a number of files, something close to:
+
+ /usr/local/man/man1/mi2mu.1
+ /usr/local/man/man1/convert-mudela.1
+ /usr/local/man/man1/mudela-book.1
+ /usr/local/man/man1/lilypond.1
+ /usr/local/bin/lilypond
+ /usr/local/bin/mi2mu
+ /usr/local/bin/convert-mudela
+ /usr/local/bin/mudela-book
+ /usr/local/bin/abc2ly
+ /usr/local/share/lilypond/*
+ /usr/local/share/locale/{it,nl}/LC_MESSAGES/lilypond.mo
+
+ The above assumes that you are root and have the GNU development
+tools, and your make is GNU make. If this is not the case, you can
+adjust your environment variables to your taste:
+
+
+ export CPPFLAGS="-I /home/me/my_include -DWEIRD_FOOBAR"
+ ./configure
+
+ `CPPFLAGS' are the preprocessor flags.
+
+ The configure script is Cygnus configure, and it will accept
+`--help'. If you are not root, you will probably have to make it with a
+different `--prefix' option. Our favourite location is
+
+
+ ./configure --prefix=$HOME/usr
+
+ In this case, you will have to set up MFINPUTS, and TEXINPUTS
+accordingly.
+
+ Since GNU LilyPond currently is beta, you are advised to also use
+
+
+ --enable-debugging
+ --enable-checking
+
+ Options to configure include:
+
+``--enable-printing''
+ Enable debugging print routines (lilypond `-D' option)
+
+``--enable-optimise''
+ Set maximum optimisation: compile with `-O2'. This can be
+ unreliable on some compiler/platform combinations (eg, DEC Alpha
+ and PPC)
+
+``--enable-profiling''
+ Compile with support for profiling.
+
+``--enable-config''
+ Output to a different configuration file. Needed for
+ multi-platform builds
+
+ All options are documented in the `configure' help The option
+`--enable-optimise' is recommended for Real Life usage.
+
+ If you do
+
+
+ make all
+
+ everything will be compiled, but nothing will be installed. The
+resulting binaries can be found in the subdirectories `out/' (which
+contain all files generated during compilation).
+
+Configuring for multiple platforms
+==================================
+
+ If you want to compile LilyPond with different configuration
+settings, then, you can use the `--enable-config' option. Example:
+suppose I want to build with and without profiling. Then I'd use the
+following for the normal build,
+
+
+ ./configure --prefix=~ --disable-optimise --enable-checking
+ make
+ make install
+
+ and for the profiling version, I specify a different configuration.
+
+
+ ./configure --prefix=~ --enable-profiling --enable-config=optprof --enable-optimise --disable-checking
+ make config=optprof
+ make config=optprof install
+
+Installing
+==========
+
+ if you have done a successful `make', then a simple
+
+
+ make install
+
+ should do the trick.
+
+ If you are doing an upgrade, please remember to remove obsolete
+`.pk' and `.tfm' files of the fonts. A script has been provided to do
+the work for you, see `bin/clean-fonts.sh'.
+
+Redhat linux
+============
+
+ RedHat Linux users can compile an RPM. A spec file is in
+`make/out/lilypond.spec', it is distributed along with the sources.
+
+ You can make the rpm by issuing
+
+ rpm -tb lilypond-x.y.z.tar.gz
+ rpm -i /usr/src/redhat/RPMS/i386/lilypond-x.y.z
+
+ Precompiled i386 RedHat RPMS are available from
+ftp://freshmeat.net/pub/rpms/lilypond/
+(ftp://freshmeat.net/pub/rpms/lilypond/) and
+http://linux.umbc.edu/software/lilypond/rpms/
+(http://linux.umbc.edu/software/lilypond/rpms/).
+
+ For compilation on a RedHat system you need these packages, in
+addition to the those needed for running:
+ * glibc-devel
+
+ * libstdc++-devel
+
+ * guile-devel
+
+ * flex
+
+ * bison
+
+ * texinfo
+
+Debian GNU/linux
+================
+
+ A Debian package is also available; contact Anthony Fok
+<foka@debian.org>. The build scripts are in the subdirectory `debian/'.
+
+Windows NT/95
+=============
+
+ Separate instructions on building for W32 are available; See the
+files in `Documentation/ntweb/', included with the sources.
+
+Problems
+========
+
+ For help and questions use <help-gnu-music@gnu.org> and
+<gnu-music-discuss@gnu.org>. Please consult the faq before mailing
+your problems.
+
+ If you find bugs, please send bug reports to <bug-gnu-music@gnu.org>.
+
+ Known bugs that are LilyPond's fault are listed in `TODO', or
+demonstrated in `input/bugs/'.
+
+ Known bugs that are not LilyPond's fault are documented here.
+
+LinuxPPC Bugs:
+**************
+
+ * egcs-1.1.2-12c (stock LinuxPPC R5) has a serious bug, upgrade to
+ fixed in egcs-1.1.2-12f or gcc-2.95-0a,
+ `ftp://dev.linuxppc.org/users/fsirl/R5/RPMS/ppc/'
+
+ * egcs-1.0.2 (LinuxPPC R4): all compiling with `-O2' is suspect, in
+ particular guile-1.3, and Lily herself will break.
+
+Linux-i386
+**********
+
+ * SuSE6.2 and similar platforms (glibc 2.1, libstdc++ 2.9.0)
+
+ Lily will crash during parsing (which suggests a C++ library
+ incompatibility). Precise cause, precise platform description or
+ solution are not known.
+
+ Note that this only happens on some computers with the said
+ platform.
+
+ * libg++ 2.7
+
+ LilyPond occasionally crashes while parsing the initialisation
+ files. This is a very obscure bug, and usually entering the
+ commandline differently "fixes" it.
+
+ lilypond input.ly
+
+ and
+ lilypond -I. ./input.ly
+ makes a difference
+
+ Typical stacktrace:
+ SIGSEGV
+ __libc_malloc (bytes=16384)
+ ?? ()
+ yyFlexLexer::yy_create_buffer ()
+ Includable_lexer::new_input (this=0x8209a00, s={strh_ = {
+
+ This behaviour has been observed with machines that have old libg++
+ versions (LinuxPPC feb '98, RedHat 4.x).
+
+Solaris:
+********
+
+ * Sparc64/Solaris 2.6, GNU make-3.77
+
+ GNU make-3.77 is buggy on this platform, upgrade to 3.78.1 or
+ newer.
+
+ * Sparc64/Solaris 2.6, ld
+
+ Not yet resolved.
+
+AIX
+***
+
+ * AIX 4.3 ld
+
+ The following is from the gcc install/SPECIFIC file.
+ Some versions of the AIX binder (linker) can fail with a
+ relocation overflow severe error when the -bbigtoc option
+ is used to link GCC-produced object files into an
+ executable that overflows the TOC. A fix for APAR IX75823
+ (OVERFLOW DURING LINK WHEN USING GCC AND -BBIGTOC) is
+ available from IBM Customer Support and from its
+ 27service.boulder.ibm.com website as PTF U455193.
+
+ Binutils does not support AIX 4.3 (at least through release
+ 2.9). GNU as and GNU ld will not work properly and one
+ should not configure GCC to use those GNU utilities. Use
+ the native AIX tools which do interoperate with GCC.
+
+ add -Wl,-bbigtoc to USER_LDFLAGS, ie:
+ LDFLAGS='-Wl,-bbigtoc' ./configure
+
+
--- /dev/null
+
+
+This is the toplevel README to LilyPond
+***************************************
+
+ LilyPond is a music typesetter. It produces beautiful sheet music
+using a high level description file as input. LilyPond is part of the
+GNU Project.
+
+Versioning
+==========
+
+ LilyPond uses a versioning scheme similar to the Linux kernel. In a
+version "x.y.z", an even second number 'y' denotes a stable version.
+For development versions 'y' is odd. For using straightforward score
+production, please use the latest stable version. Development versions
+may not produce good or nice scores.
+
+Requirements
+============
+
+ For the compilation and running of LilyPond you need some additional
+packages. Please refer to the installation instructions.
+
+ NOTE: If you downloaded a binary (.rpm or a W95/NT .zip file), you
+don't have to compile LilyPond.
+
+Installation
+============
+
+ For your convenience, a formatted copy of the INSTALL instructions
+are in the toplevel directory, as INSTALL.txt
+
+Documentation
+=============
+
+ The real documentation is the directory Documentation/
+
+ If you want to read the documentation online, these are options:
+ * use `.html'. Refer to INSTALL.txt for info on how to make the
+ .html documentation.
+
+ * use `.html'. Point your browser to
+ `http://www.cs.uu.nl/~hanwen/lilypond/index.html'.
+
+ * use `.dvi', for the tutorial and reference manual. Do
+
+ make -C Documentation/user/ dvi
+
+ * use ASCII. Do using
+ make -C doc
+
+
+Comments
+========
+
+ LilyPond is a long way from finished and polished. We do appreciate
+criticism, comments, bugreports, patches, etc.
+
+ Please send your e-mail to one of the MAILING LISTS
+
+ and _not_ to us personally. See `Documentation/mail.texi' for more
+info.
+
+Windows 32
+==========
+
+ If you have received this file as part of a DOS/Window32 distribution
+(`LilyPond-*.zip'), it is advisable to also download the source
+package, since it might contain more documentation
+`ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/'
+
+ If you decide to build LilyPond from source, please read the
+INSTALL.txt document first, especially the Windows NT/95 section.
+
+Caveats
+=======
+
+ If you have installed a previous version, be sure to remove old font
+files, eg.,
+ rm `find /var/lib/texmf/fonts -name 'feta*'`
+
+ a script to do this for you is in `buildscripts/clean-fonts.sh'
+
+Bugs
+====
+
+ Send bug reports to <bug-gnu-music@gnu.org>. For help and questions
+use <help-gnu-music@gnu.org> and <gnu-music-discuss@gnu.org>. Please
+consult the FAQ and installation instructions before mailing your
+problems.
+
+CDROM distributions
+===================
+
+ If you have received LilyPond on a cdrom, chances are that
+development has moved some patchlevels up. Please check the latest
+version of LilyPond before reporting bugs.
+
BoolOption ('static', 'build static libraries',
1),
BoolOption ('gui', 'build with GNOME backend (EXPERIMENTAL)',
- 0),
+ 1),
BoolOption ('verbose', 'run commands with verbose flag',
0),
BoolOption ('checksums', 'use checksums instead of timestamps',
return sorted
-def symlink_tree (target, source, env):
- def mkdirs (dir):
- def mkdir (dir):
- if not dir:
- os.chdir (os.sep)
- return
- if not os.path.isdir (dir):
- if os.path.exists (dir):
- os.unlink (dir)
- os.mkdir (dir)
- os.chdir (dir)
- map (mkdir, string.split (dir, os.sep))
- def symlink (src, dst):
- os.chdir (absbuild)
- dir = os.path.dirname (dst)
- mkdirs (dir)
- if src[0] == '#':
- frm = os.path.join (srcdir, src[1:])
- else:
- depth = len (string.split (dir, '/'))
- if src.find ('@') > -1:
- frm = os.path.join ('../' * depth,
- string.replace (src, '@',
- env['out']))
- else:
- frm = os.path.join ('../' * depth, src,
- env['out'])
- if src[-1] == '/':
- frm = os.path.join (frm, os.path.basename (dst))
- if env['verbose']:
- print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
- os.symlink (frm, os.path.basename (dst))
- shutil.rmtree (run_prefix)
- prefix = os.path.join (env['out'], 'usr')
- map (lambda x: symlink (x[0], os.path.join (prefix,
- x[1] % {'ver' : version})),
- # ^# := source dir
- # @ := out
- # /$ := add dst file_name
- (('python', 'lib/lilypond/python'),
- # ugh
- ('python', 'share/lilypond/%(ver)s/python'),
- ('lily/', 'bin/lilypond'),
- ('scripts/', 'bin/convert-ly'),
- ('scripts/', 'bin/lilypond-book'),
- ('scripts/', 'bin/ps2png'),
- ('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
- ('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
- ('#ps/music-drawing-routines.ps',
- 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
- ('mf', 'share/lilypond/%(ver)s/otf'),
- ('mf', 'share/lilypond/%(ver)s/tfm'),
- ('tex', 'share/lilypond/%(ver)s/tex/enc'),
- ('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
- ('mf', 'share/lilypond/%(ver)s/fonts/map'),
- ('mf', 'share/lilypond/%(ver)s/fonts/otf'),
- ('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
- ('mf', 'share/lilypond/%(ver)s/fonts/type1'),
- ('#tex', 'share/lilypond/%(ver)s/tex/source'),
- ('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
- ('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
- ('#ly', 'share/lilypond/%(ver)s/ly'),
- ('#scm', 'share/lilypond/%(ver)s/scm'),
- ('#scripts', 'share/lilypond/%(ver)s/scripts'),
- ('#ps', 'share/lilypond/%(ver)s/ps'),
- ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
- ('elisp', 'share/lilypond/%(ver)s/elisp')))
-
- print "FIXME: BARF BARF BARF"
- os.chdir (absbuild)
- out = env['out']
- ver = version
- prefix = os.path.join (env['out'], 'usr/share/lilypond/%(ver)s/fonts'
- % vars ())
- for ext in ('enc', 'map', 'otf', 'svg', 'tfm', 'pfa'):
- dir = os.path.join (absbuild, prefix, ext)
- os.system ('rm -f ' + dir)
- mkdirs (dir)
- os.chdir (dir)
- os.system ('ln -s ../../../../../../../mf/%(out)s/*.%(ext)s .'
- % vars ())
- os.chdir (srcdir)
-
def configure (target, source, env):
- dre = re.compile ('\n(200[0-9]{5})')
- vre = re.compile ('.*?\n[^-.0-9]*([0-9][0-9]*\.[0-9]([.0-9]*[0-9])*)',
+ vre = re.compile ('^.*[^-.0-9]([0-9][0-9]*\.[0-9]([.0-9]*[0-9])*).*$',
re.DOTALL)
def get_version (program):
command = '(pkg-config --modversion %(program)s || %(program)s --version || %(program)s -V) 2>&1' % vars ()
output = pipe.read ()
if pipe.close ():
return None
- splits = re.sub ('^|\s', '\n', output)
- date_hack = re.sub (dre, '\n0.0.\\1', splits)
- m = re.match (vre, date_hack)
- v = m.group (1)
+ v = re.sub (vre, '\\1', output)
if v[-1] == '\n':
v = v[:-1]
return string.split (v, '.')
test_program (optional, 'bison', '1.25', 'Bison -- parser generator',
'bison')
test_program (optional, 'dvips', '0.0', 'Dvips', 'tetex-bin')
- test_program (optional, 'fontforge', '0.0.20050624', 'FontForge',
- 'fontforge')
+# test_program (optional, 'fontforge', '0.0.20041224', 'FontForge',
+# 'fontforge')
test_program (optional, 'flex', '0.0', 'Flex -- lexer generator',
'flex')
test_program (optional, 'guile', '1.6', 'GUILE scheme', 'guile')
- test_program (optional, 'gs', '8.15',
+ test_program (optional, 'gs', '8.14',
'Ghostscript PostScript interpreter',
'gs or gs-afpl or gs-esp or gs-gpl')
- test_program (optional, 'mftrace', '1.1.19', 'Metafont tracing Type1',
+ test_program (optional, 'mftrace', '1.1.0', 'Metafont tracing Type1',
'mftrace')
test_program (optional, 'makeinfo', '4.7', 'Makeinfo tool', 'texinfo')
test_program (optional, 'perl', '4.0',
context.Result (ret)
return ret
+ def CheckLibkpathseaSo (context):
+ saveCFLAGS = []
+ if context.env.has_key ('CFLAGS'):
+ saveCFLAGS = context.env['CFLAGS']
+ CFLAGS_shared_no_debugging = filter (lambda x: x != '-g',
+ saveCFLAGS)\
+ + ['-shared']
+ # FIXME: how does this work, with scons
+ context.env.Replace (CFLAGS = CFLAGS_shared_no_debugging)
+ #context.env.Replace (CFLAGS = '')
+ #context.env.Append (CFLAGS = ['-shared'])
+ context.Message ('Checking for libkpathsea... ')
+ ret = conf.TryLink ('''#include <kpathsea/kpathsea.h>
+ int main ()
+ {
+ kpse_var_expand ("\$TEXMF");
+ return 0;
+ }
+ ''', '.c')
+ context.env.Replace (CFLAGS = saveCFLAGS)
+ # FIXME: this prints 'ok' already
+ context.Result (ret)
+ if not ret:
+ return 0
+
+ sys.stdout.write ('Checking for libkpathsea.so... ')
+ testfile = str (context.sconf.lastTarget)
+ shared_size = os.path.getsize (testfile)
+ ret = shared_size < 40000
+ if ret:
+ print 'ok'
+ else:
+ print 'no'
+ return ret
+
conf = Configure (env, custom_tests = { 'CheckYYCurrentBuffer'
- : CheckYYCurrentBuffer })
+ : CheckYYCurrentBuffer,
+ 'CheckLibkpathseaSo'
+ : CheckLibkpathseaSo })
defines = {
'DIRSEP' : "'%s'" % os.sep,
else:
env.Append (CPPPATH = [PYTHON_INCLUDE])
- headers = ('assert.h', 'grp.h', 'libio.h', 'pwd.h',
- 'sys/stat.h', 'utf8/wchar.h', 'wchar.h', 'Python.h')
+ headers = ('sys/stat.h', 'assert.h', 'kpathsea/kpathsea.h', 'libio.h',
+ 'Python.h')
for i in headers:
if conf.CheckCHeader (i):
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
conf.env['DEFINES'][key] = 1
- functions = ('chroot', 'fopencookie', 'funopen',
- 'gettext', 'isinf',
- 'mbrtowc', 'memmem', 'snprintf', 'vsnprintf', 'wcrtomb')
+ functions = ('fopencookie', 'funopen',
+ 'gettext', 'isinf', 'memmem', 'snprintf', 'vsnprintf')
for i in functions:
if 0 or conf.CheckFunc (i):
key = re.sub ('[./]', '_', 'HAVE_' + string.upper (i))
if conf.CheckYYCurrentBuffer ():
conf.env['DEFINES']['HAVE_FLEXLEXER_YY_CURRENT_BUFFER'] = 1
+ if conf.CheckLibkpathseaSo ():
+ conf.env['DEFINES']['HAVE_LIBKPATHSEA_SO'] = '1'
+
if conf.CheckLib ('dl'):
pass
+ if conf.CheckLib ('kpathsea'):
+ conf.env['DEFINES']['KPATHSEA'] = 1
+
+ # huh?
+ if conf.CheckLib ('kpathsea', 'kpse_find_file'):
+ conf.env['DEFINES']['HAVE_KPSE_FIND_FILE'] = '1'
+ if conf.CheckLib ('kpathsea', 'kpse_find_tfm'):
+ conf.env['DEFINES']['HAVE_KPSE_FIND_TFM'] = '1'
+
if env['fast']:
cpppath = []
if env.has_key ('CPPPATH'):
'Development files for pango, with FreeType2',
'pango1.0'):
conf.env['DEFINES']['HAVE_PANGO_FT2'] = '1'
+ conf.env['DEFINES']['HAVE_PANGO16'] = '1'
if test_lib (optional, 'fontconfig', '2.2.0',
'Development files for fontconfig', 'fontconfig1'):
if env['gui']:
test_lib (required, 'gtk+-2.0', '2.4.0',
'Development files for GTK+', 'gtk2.0')
+ if test_lib (required, 'pango', '1.6.0',
+ 'Development files for pango', 'pango1.0'):
+ conf.env['DEFINES']['HAVE_PANGO16'] = '1'
+ if conf.CheckCHeader ('pango/pangofc-fontmap.h'):
+ conf.env['DEFINES']['HAVE_PANGO_PANGOFC_FONTMAP_H'] = '1'
if env['fast']:
# Using CCFLAGS = -I<system-dir> rather than CPPPATH = [
# <system-dir>] speeds up SCons
LILYPONDPREFIX = os.path.join (run_prefix, 'share/lilypond/', version)
-if not os.path.exists (LILYPONDPREFIX):
- os.makedirs (LILYPONDPREFIX)
-
-env.Command (LILYPONDPREFIX, ['#/SConstruct', '#/VERSION'], symlink_tree)
-env.Depends ('lily', LILYPONDPREFIX)
-
env.Append (ENV = {
+ #'LILYPONDPREFIX' : os.path.join (run_prefix, 'share/lilypond/', version),
'LILYPONDPREFIX' : LILYPONDPREFIX,
+ # ugh, can't use LILYPONDPREFIX here
+ #'TEXMF' : '{' + os.path.join (run_prefix, 'share/lilypond/', version)\
+ #+ ',' \
'TEXMF' : '{$LILYPONDPREFIX,'
+ os.popen ('kpsexpand \$TEXMF').read ()[:-1] + '}',
})
env.Append (CCFLAGS = ['-g'])
if env['optimising']:
env.Append (CCFLAGS = '-O2')
+ env.Append (CXXFLAGS = ['-DSTRING_UTILS_INLINED'])
if env['warnings']:
env.Append (CCFLAGS = ['-W', '-Wall'])
env.Append (CXXFLAGS = ['-Wconversion'])
os.unlink (config_cache)
Exit (s)
-def symlink_tree ():
- print "BOE"
- raise urg
-
# Declare SConscript phonies
env.Alias ('minimal', config_cache)
+env.Alias ('mf-essential', config_cache)
-if 0:
- env.Alias ('mf-essential', config_cache)
- env.Alias ('minimal', ['python', 'lily', 'mf-essential'])
- env.Alias ('all', ['minimal', 'mf', '.'])
-
-else:
- env.Alias ('minimal', ['python', 'lily', 'mf'])
- env.Alias ('all', ['minimal', '.'])
-
-
+env.Alias ('minimal', ['lily', 'mf-essential'])
+env.Alias ('all', ['minimal', 'mf', '.'])
# Do we want the doc/web separation?
env.Alias ('doc',
- ['minimal',
- 'Documentation',
+ ['Documentation',
'Documentation/user',
'Documentation/topdocs',
'Documentation/bibliography',
LILYPONDPREFIX = LILYPONDPREFIX,
# FIXME: move to lily/SConscript?
- LIBPATH = [os.path.join (absbuild, 'flower', env['out'])],
+ LIBPATH = [os.path.join (absbuild, 'flower', env['out']),
+ os.path.join (absbuild, 'kpath-guile', env['out']),],
CPPPATH = [outdir, ],
LILYPOND_PATH = ['.',
'$srcdir/input',
'$absbuild/Documentation/user/$out'],
)
+def symlink_tree (target, source, env):
+ def mkdirs (dir):
+ def mkdir (dir):
+ if not dir:
+ os.chdir (os.sep)
+ return
+ if not os.path.isdir (dir):
+ if os.path.exists (dir):
+ os.unlink (dir)
+ os.mkdir (dir)
+ os.chdir (dir)
+ map (mkdir, string.split (dir, os.sep))
+ def symlink (src, dst):
+ os.chdir (absbuild)
+ dir = os.path.dirname (dst)
+ mkdirs (dir)
+ if src[0] == '#':
+ frm = os.path.join (srcdir, src[1:])
+ else:
+ depth = len (string.split (dir, '/'))
+ if src.find ('@') > -1:
+ frm = os.path.join ('../' * depth,
+ string.replace (src, '@',
+ env['out']))
+ else:
+ frm = os.path.join ('../' * depth, src,
+ env['out'])
+ if src[-1] == '/':
+ frm = os.path.join (frm, os.path.basename (dst))
+ if env['verbose']:
+ print 'ln -s %s -> %s' % (frm, os.path.basename (dst))
+ os.symlink (frm, os.path.basename (dst))
+ shutil.rmtree (run_prefix)
+ prefix = os.path.join (env['out'], 'usr')
+ map (lambda x: symlink (x[0], os.path.join (prefix,
+ x[1] % {'ver' : version})),
+ # ^# := source dir
+ # @ := out
+ # /$ := add dst file_name
+ (('python', 'lib/lilypond/python'),
+ # ugh
+ ('python', 'share/lilypond/%(ver)s/python'),
+ ('lily/', 'bin/lilypond'),
+ ('scripts/', 'bin/convert-ly'),
+ ('scripts/', 'bin/lilypond-book'),
+ ('scripts/', 'bin/ps2png'),
+ ('mf', 'share/lilypond/%(ver)s/dvips/mf-out'),
+ ('#ps', 'share/lilypond/%(ver)s/dvips/ps'),
+ ('#ps/music-drawing-routines.ps',
+ 'share/lilypond/%(ver)s/tex/music-drawing-routines.ps'),
+ ('mf', 'share/lilypond/%(ver)s/otf'),
+ ('mf', 'share/lilypond/%(ver)s/tfm'),
+ ('tex', 'share/lilypond/%(ver)s/tex/enc'),
+ ('#mf', 'share/lilypond/%(ver)s/fonts/mf'),
+ ('mf', 'share/lilypond/%(ver)s/fonts/map'),
+ ('mf', 'share/lilypond/%(ver)s/fonts/otf'),
+ ('mf', 'share/lilypond/%(ver)s/fonts/tfm'),
+ ('mf', 'share/lilypond/%(ver)s/fonts/type1'),
+ ('#tex', 'share/lilypond/%(ver)s/tex/source'),
+ ('tex', 'share/lilypond/%(ver)s/tex/tex-out'),
+ ('mf', 'share/lilypond/%(ver)s/tex/mf-out'),
+ ('#ly', 'share/lilypond/%(ver)s/ly'),
+ ('#scm', 'share/lilypond/%(ver)s/scm'),
+ ('#scripts', 'share/lilypond/%(ver)s/scripts'),
+ ('#ps', 'share/lilypond/%(ver)s/ps'),
+ ('po/@/nl.mo', 'share/locale/nl/LC_MESSAGES/lilypond.mo'),
+ ('elisp', 'share/lilypond/%(ver)s/elisp')))
+
+ print "FIXME: BARF BARF BARF"
+ os.chdir (absbuild)
+ out = env['out']
+ ver = version
+ prefix = os.path.join (env['out'], 'usr/share/lilypond/%(ver)s/fonts'
+ % vars ())
+ for ext in ('enc', 'map', 'otf', 'svg', 'tfm', 'pfa'):
+ dir = os.path.join (absbuild, prefix, ext)
+ os.system ('rm -f ' + dir)
+ mkdirs (dir)
+ os.chdir (dir)
+ os.system ('ln -s ../../../../../../../mf/%(out)s/*.%(ext)s .'
+ % vars ())
+ os.chdir (srcdir)
+
+if 1: #env['debugging']:
+ stamp = os.path.join (run_prefix, 'stamp')
+ env.Command (stamp, ['#/SConstruct', '#/VERSION'],
+ [symlink_tree, 'touch $TARGET'])
+ env.Depends ('lily', stamp)
+
#### dist, tar
def plus (a, b):
a + b
and 'web' not in COMMAND_LINE_TARGETS\
and 'install' not in COMMAND_LINE_TARGETS\
and 'clean' not in COMMAND_LINE_TARGETS:
- subdirs = [ 'python',
- 'lily',
+ subdirs = ['lily',
'flower',
+ 'kpath-guile',
'mf',
+ 'python',
]
if os.path.isdir ('%(srcdir)s/CVS' % vars ()):
Release 2.9
***********
-
DEVELOPMENT TEAM
Han-Wen Nienhuys - Core development
Jan Nieuwenhuizen - Core development
+Pedro Kroger - Build Meister
Graham Percival - Documentation Editor
Mats Bengtsson - Support Guru
-
CONTRIBUTORS
-Angelo Contardi
-David Feuer
-Erik Sandberg
Erlend Aasland
-Guido Amoruso
+David Feuer
Heikki Junes
Joe Neeman
+Erik Sandberg
SPONSORS
+Trevor Bača
Andrew Sidwell
-Anthony Youngman
Chris Sawer
-David Griffel
Jamie Bullock
-Kieren MacMillan
-Michael Meixner
-Paul Scott
Steve Doonan
Trent Johnston
-Trevor Bača
-Vivian Barty-Taylor
DOCUMENTATION HELPERS
BUG HUNTERS/SUGGESTIONS
Albert Frantz
-Anthony Youngman
Aurèle Duda
-Ben Hoefer
Bernie Arai
Cameron Horsburgh
-Charles Cave
-Christian Hitz
-Christopher Ellis
Claude Routhier
+Christopher Ellis
+Christian Hitz
Colin Wilding
-Daniel Tonda Castillo
David Rogers
Francisco Vila
-Harald Wellmann
-Johannes Schindelin
J. Leung
-Karim Haddad
+Harald Wellmann
Karl Hammar
Keith Packard
-Kieren MacMillan
-Lee T. Wilkirson
-Mark Dewey
-Marcus Macauley
-Markus Schneider
-Matti Aaltonen
-Michael Meixner
-Michael Welsh Duggan
-Milan Zamazal
Orm Finnendahl
-Paul Scott
-Phillip Kirlin
Quentin Spencer
-Rainer Typke
Rick Hansen
-Ruud van Silfhout
Sietse Brouwer
Stephen Carter
-Stephen Kress
-Thies Albrecht
Trent Johnston
-Trevor Bača
-Vaclav Smilauer
Werner Lemberg
-Will Oram
Zoltan V. Laszlo
Release 2.8
Paul Scott
Ralph Little
Richard Schoeller
-Robert Vlasaty
+Robert Vlatasy
Roman Kurakin
Russell Lang
Scott Russell
Pedro Kroger
Ray McKinney
Reuben Thomas
-Robert Vlasaty
+Robert Vlatasy
Stef Epardaud
Thomas Willhalm
Thomas Scharkowski
PACKAGE_NAME=LilyPond
MAJOR_VERSION=2
MINOR_VERSION=9
-PATCH_LEVEL=22
+PATCH_LEVEL=7
MY_PATCH_LEVEL=
# Setup LilyPond environment. For the LilyPond build, we override
# some of these commands in the ENVironment.
-lilypond_book_flags = '''--format=$LILYPOND_BOOK_FORMAT --process="lilypond -I$srcdir -I$srcdir/input/test $__verbose --backend=eps --formats=ps,png --header=texidoc -dinternal-type-checking -ddump-signatures -danti-alias-factor=2 -dgs-font-load" '''
-
env.Append (
- BSTINPUTS = '${SOURCE.dir}:${TARGET.dir}:',
- BIB2HTML = '$PYTHON $srcdir/buildscripts/bib2html.py',
+ _fixme = _fixme,
+ ##ABC2LY = 'abc2ly',
+ ##LILYPOND = 'lilypond',
LILYOND_BOOK = 'lilypond-book',
+
+ #ugr
+ #LILYPOND_BOOK_FORMAT = 'texi',
LILYPOND_BOOK_FORMAT = '',
- LILYPOND_BOOK_FLAGS = lilypond_book_flags,
+ #LILYPOND_BOOK_FLAGS = ['--format=$LILYPOND_BOOK_FORMAT'],
+ LILYPOND_BOOK_FLAGS = '''--format=$LILYPOND_BOOK_FORMAT --process="lilypond --backend=eps --formats=ps,png --header=texidoc -I$srcdir/input/test -e '(ly:set-option (quote internal-type-checking) #t)'" ''',
+
LILYPOND_PATH = [],
# The SCons way around FOO_PATH:
+ ##LILYPOND_INCFLAGS = '$( ${_concat(INCPREFIX, LILYPOND_PATH, INCSUFFIX, __env__, RDirs)} $)',
LILYPOND_INCFLAGS = '$( ${_concat(INCPREFIX, LILYPOND_PATH, INCSUFFIX, __env__)} $)',
MAKEINFO_PATH = [],
MAKEINFO_FLAGS = [],
MAKEINFO_INCFLAGS = '$( ${_concat(INCPREFIX, MAKEINFO_PATH, INCSUFFIX, __env__, RDirs)} $)',
- #TEXI2DVI_FLAGS = [],
+ # should not be necessary
+ # PYTHONPATH = ['$absbuild/python/$out'],
+ TEXI2DVI_FLAGS = [],
_TEXI2DVI_FLAGS = '$( ${_concat(" ", TEXI2DVI_FLAGS,)} $)',
)
TEXIDVI =\
Builder (action = 'cd ${TARGET.dir} && \
- texi2dvi --batch -I $srcdir/Documentation/user $_TEXI2DVI_FLAGS ${SOURCE.file}',
+ texi2dvi --batch $_TEXI2DVI_FLAGS ${SOURCE.file}',
suffix = '.dvi', src_suffix = '.texi')
env.Append (BUILDERS = {'TEXIDVI': TEXIDVI})
suffix = '.eps', src_suffix = '.png')
env.Append (BUILDERS = {'PNG2EPS': PNG2EPS})
-EPS2PNG =\
- Builder (action = 'convert $SOURCE $TARGET',
- suffix = '.png', src_suffix = '.eps')
-env.Append (BUILDERS = {'EPS2PNG': EPS2PNG})
+
+
+# FIXME: cleanup, see above
+
+
+env.Append (
+
+ #urg
+ BSTINPUTS = '${SOURCE.dir}:${TARGET.dir}:',
+ BIB2HTML = '$PYTHON $srcdir/buildscripts/bib2html.py',
+)
+
def add_ps_target (target, source, env):
base = os.path.splitext (str (target[0]))[0]
def add_enc_src (target, source, env):
base = os.path.splitext (str (target[0]))[0]
- #return (target, source + [base + '.enc'])
- return (target + [base + '.pfb', base + '.svg'], source + [base + '.enc'])
-
-def add_svg (target, source, env):
- base = os.path.splitext (str (target[0]))[0]
- return (target + [base + '.svg'], source)
+ return (target, source + [base + '.enc'])
# FIXME UGH, should fix --output option for mftrace
a = 'cd ${TARGET.dir} && \
if test -e ${SOURCE.filebase}.enc; then encoding="--encoding=${SOURCE.filebase}.enc"; fi; \
MFINPUTS=$srcdir/mf:.: \
-$MFTRACE --formats=pfa,pfb,svg --simplify --keep-trying --no-afm \
+$MFTRACE --formats=pfa --simplify --keep-trying --no-afm \
$$encoding $__verbose \
--include=${TARGET.dir} \
${SOURCE.file}'
suffix = '.otf',
src_suffix = '.pe',
# emitter = add_cff_cffps_svg
- emitter = add_svg
)
env.Append (BUILDERS = {'OTF': otf})
'step-bindir',
]
+# naming
def at_copy (target, source, env):
n = str (source[0])
s = open (n).read ()
AT_COPY = Builder (action = at_copy, src_suffix = ['.in', '.py', '.sh',])
env.Append (BUILDERS = {'AT_COPY': AT_COPY})
+# naming
def at_copy_ext (target, source, env):
n = str (source[0])
s = open (n).read ()
suffix = '.mo', src_suffix = '.po')
env.Append (BUILDERS = {'MO': MO})
+# ' '; ?
ugh = 'ln -f po/lilypond.pot ${TARGET.dir}/lilypond.po ; '
a = ugh + 'xgettext --default-domain=lilypond --join \
--output-dir=${TARGET.dir} --add-comments \
POMERGE = Builder (action = a, suffix = '.pom', src_suffix = '.po')
env.Append (BUILDERS = {'POMERGE': POMERGE})
+#UGRr
a = 'BSTINPUTS=$BSTINPUTS $BIB2HTML -o $TARGET $SOURCE'
BIB2HTML = Builder (action = a, suffix = '.html', src_suffix = '.bib')
env.Append (BUILDERS = {'BIB2HTML': BIB2HTML})
env.Append (BUILDERS = {'LYS2TELY': LYS2TELY})
-def mutopia (ly=None, abc=None):
+def mutopia (ly = None, abc = None):
+
+ # FIXME: ugr, huh? The values from ../SConstruct get appended
+ # to the predefined values from this builder context:
+
+ # abc2ly/usr/bin/python ..../abc2.py
+
+ # Override them again to fix web build...
+
+
+ #BUILD_ABC2LY = '${set__x}$PYTHON $srcdir/scripts/abc2ly.py'
+ #BUILD_LILYPOND = '$absbuild/$out/lilypond ${__verbose}'
e = env.Copy (
- LILYPOND_BOOK_FLAGS = lilypond_book_flags,
- )
+ #LILYPOND = BUILD_LILYPOND,
+ #ABC2LY = BUILD_ABC2LY,
+ )
if not abc:
abc = base_glob ('*.abc')
if not ly:
ly = base_glob ('*.ly') + map (e.ABC, abc)
pdf = map (e.LilyPond, ly)
+
+ # We need lily and mf to build these.
env.Depends (pdf, ['#/lily', '#/mf'])
env.Alias ('doc', pdf)
Export ('mutopia')
+
def collate (title = 'collated files'):
ly = base_glob ('*.ly')
e = env.Copy (
TITLE = title,
- LILYPOND_BOOK_FLAGS = lilypond_book_flags,
- # __verbose = ' --verbose',
- )
+ LILYPOND_BOOK_FLAGS = '''--process="lilypond --backend=eps --formats=ps,png --header=texidoc -I$srcdir/input/test -e '(ly:set-option (quote internal-type-checking) #t)'" ''',
+ __verbose = ' --verbose',
+ )
+ #
tely = e.LYS2TELY ('collated-files', ly)
texi = e.TEXI (tely)
+ # We need lily and mf to build these.
env.Depends (texi, ['#/lily', '#/mf'])
dvi = e.TEXIDVI (texi)
pspdf = e.DVIPDF (dvi)
"""
headertext_nopics= r"""
-<p>No examples were found in this directory.
+<p>Nothing to be seen here, move along.
"""
#
allfiles = []
for d in dirs:
- allfiles = allfiles + find ('*.ly', d)
-
-allfiles = filter (lambda x: not x.endswith ('snippet-map.ly') and not re.search ('lily-[0-9]+', x), allfiles)
+ allfiles = allfiles + find ('*.ly.txt', d)
gen_list (allfiles, outfile)
#!@TARGET_PYTHON@
import sys
import optparse
-import os
-
-## so we can call directly as buildscripts/output-distance.py
-me_path = os.path.abspath (os.path.split (sys.argv[0])[0])
-sys.path.insert (0, me_path + '/../python/')
-
import safeeval
Y_AXIS = 1
INFTY = 1e6
-OUTPUT_EXPRESSION_PENALTY = 1
-ORPHAN_GROB_PENALTY = 1
-inspect_max_count = 0
+OUTPUT_EXPRESSION_PENALTY = 100
+ORPHAN_GROB_PENALTY = 1000
def max_distance (x1, x2):
dist = 0.0
empty_interval = (INFTY, -INFTY)
empty_bbox = (empty_interval, empty_interval)
-def interval_is_empty (i):
- return i[0] > i[1]
-
def interval_length (i):
return max (i[1]-i[0], 0)
return (max (i1[0], i2[0]),
min (i1[1], i2[1]))
-def bbox_is_empty (b):
- return (interval_is_empty (b[0])
- or interval_is_empty (b[1]))
-
def bbox_union (b1, b2):
return (interval_union (b1[X_AXIS], b2[X_AXIS]),
interval_union (b2[Y_AXIS], b2[Y_AXIS]))
def __repr__ (self):
return '%s: (%.2f,%.2f), (%.2f,%.2f)\n' % (self.name,
- self.bbox[0][0],
- self.bbox[0][1],
- self.bbox[1][0],
- self.bbox[1][1])
+ self.bbox[0][0],
+ self.bbox[0][1],
+ self.bbox[1][0],
+ self.bbox[1][1])
def axis_centroid (self, axis):
return apply (sum, self.bbox[axis]) / 2
def expression_distance (self, other):
if self.output_expression == other.output_expression:
- return 0
+ return 0.0
else:
- return 1
-
-################################################################
-# single System.
+ return OUTPUT_EXPRESSION_PENALTY
+ def distance(self, other, max_distance):
+ return (self.expression_distance (other)
+ + self.centroid_distance (other, max_distance)
+ + self.bbox_distance (other))
+
class SystemSignature:
def __init__ (self, grob_sigs):
d = {}
def grobs (self):
return reduce (lambda x,y: x+y, self.grob_dict.values(), [])
-################################################################
-## comparison of systems.
-
class SystemLink:
def __init__ (self, system1, system2):
self.system1 = system1
self.link_list_dict = {}
self.back_link_dict = {}
-
- ## pairs
- self.orphans = []
-
- ## pair -> distance
- self.geo_distances = {}
-
- ## pairs
- self.expression_changed = []
-
- self._geometric_distance = None
- self._expression_change_count = None
- self._orphan_count = None
-
for g in system1.grobs ():
-
- ## skip empty bboxes.
- if bbox_is_empty (g.bbox):
- continue
-
closest = system2.closest (g.name, g.centroid)
self.link_list_dict.setdefault (closest, [])
self.link_list_dict[closest].append (g)
self.back_link_dict[g] = closest
+ def distance (self):
+ d = 0.0
- def calc_geometric_distance (self):
- total = 0.0
+ scale = max (bbox_diameter (self.system1.bbox),
+ bbox_diameter (self.system2.bbox))
+
for (g1,g2) in self.back_link_dict.items ():
- if g2:
- d = g1.bbox_distance (g2)
- if d:
- self.geo_distances[(g1,g2)] = d
-
- total += d
-
- self._geometric_distance = total
-
- def calc_orphan_count (self):
- count = 0
- for (g1, g2) in self.back_link_dict.items ():
if g2 == None:
- self.orphans.append ((g1, None))
-
- count += 1
+ d += ORPHAN_GROB_PENALTY
+ else:
+ d += g1.distance (g2, scale)
- self._orphan_count = count
-
- def calc_output_exp_distance (self):
- d = 0
- for (g1,g2) in self.back_link_dict.items ():
- if g2:
- d += g1.expression_distance (g2)
+ for (g1,g2s) in self.link_list_dict.items ():
+ if len (g2s) != 1:
+ d += ORPHAN_GROB_PENALTY
- self._expression_change_count = d
+ return d
- def output_expression_details_string (self):
- return ', '.join ([g1.name for g1 in self.expression_changed])
-
- def geo_details_string (self):
- results = [(d, g1,g2) for ((g1, g2), d) in self.geo_distances.items()]
- results.sort ()
- results.reverse ()
-
- return ', '.join (['%s: %f' % (g1.name, d) for (d, g1, g2) in results])
+################################################################
+# Files/directories
- def orphan_details_string (self):
- return ', '.join (['%s-None' % g1.name for (g1,g2) in self.orphans if g2==None])
+import glob
+import shutil
+import re
- def geometric_distance (self):
- if self._geometric_distance == None:
- self.calc_geometric_distance ()
- return self._geometric_distance
-
- def orphan_count (self):
- if self._orphan_count == None:
- self.calc_orphan_count ()
-
- return self._orphan_count
-
- def output_expression_change_count (self):
- if self._expression_change_count == None:
- self.calc_output_exp_distance ()
- return self._expression_change_count
-
- def distance (self):
- return (self.output_expression_change_count (),
- self.orphan_count (),
- self.geometric_distance ())
-
def read_signature_file (name):
print 'reading', name
-
- entries = open (name).read ().split ('\n')
- def string_to_tup (s):
- return tuple (map (float, s.split (' ')))
-
- def string_to_entry (s):
- fields = s.split('@')
- fields[2] = string_to_tup (fields[2])
- fields[3] = string_to_tup (fields[3])
-
- return tuple (fields)
-
- entries = [string_to_entry (e) for e in entries
- if e and not e.startswith ('#')]
+ exp_str = ("[%s]" % open (name).read ())
+ entries = safeeval.safe_eval (exp_str)
grob_sigs = [GrobSignature (e) for e in entries]
sig = SystemSignature (grob_sigs)
return sig
-################################################################
-# different systems of a .ly file.
-
-class FileLink:
- def __init__ (self):
- self.original_name = ''
- self.base_names = ('','')
- self.system_links = {}
- self._distance = None
-
- def add_system_link (self, link, number):
- self.system_links[number] = link
-
- def calc_distance (self):
- d = 0.0
-
- orphan_distance = 0.0
- for l in self.system_links.values ():
- d = max (d, l.geometric_distance ())
- orphan_distance += l.orphan_count ()
-
- return d + orphan_distance
-
- def distance (self):
- if type (self._distance) != type (0.0):
- return self.calc_distance ()
-
- return self._distance
-
- def text_record_string (self):
- return '%-30f %-20s\n' % (self.distance (),
- self.original_name)
-
- def source_file (self):
- for ext in ('.ly', '.ly.txt'):
- if os.path.exists (self.base_names[1] + ext):
- return self.base_names[1] + ext
- return ''
-
- def add_file_compare (self, f1, f2):
- system_index = []
-
- def note_system_index (m):
- system_index.append (int (m.group (1)))
- return ''
-
- base1 = re.sub ("-([0-9]+).signature", note_system_index, f1)
- base2 = re.sub ("-([0-9]+).signature", note_system_index, f2)
-
- self.base_names = (os.path.normpath (base1),
- os.path.normpath (base2))
-
- def note_original (match):
- self.original_name = match.group (1)
- return ''
-
- if not self.original_name:
- self.original_name = os.path.split (base1)[1]
-
- ## ugh: drop the .ly.txt
- for ext in ('.ly', '.ly.txt'):
- try:
- re.sub (r'\\sourcefilename "([^"]+)"',
- note_original, open (base1 + ext).read ())
- except IOError:
- pass
-
- s1 = read_signature_file (f1)
- s2 = read_signature_file (f2)
-
- link = SystemLink (s1, s2)
-
- self.add_system_link (link, system_index[0])
-
- def link_files_for_html (self, old_dir, new_dir, dest_dir):
- for ext in ('.png', '.ly'):
- for oldnew in (0,1):
- link_file (self.base_names[oldnew] + ext,
- dest_dir + '/' + self.base_names[oldnew] + ext)
-
- def html_record_string (self, old_dir, new_dir):
- def img_cell (ly, img, name):
- if not name:
- name = 'source'
- else:
- name = '<tt>%s</tt>' % name
-
- return '''
-<td align="center">
-<a href="%(img)s">
-<img src="%(img)s" style="border-style: none; max-width: 500px;">
-</a><br>
-<font size="-2">(<a href="%(ly)s">%(name)s</a>)
-</font>
-</td>
-''' % locals ()
-
-
- img_1 = self.base_names[0] + '.png'
- ly_1 = self.base_names[0] + '.ly'
- img_2 = self.base_names[1] + '.png'
- ly_2 = self.base_names[1] + '.ly'
- html_2 = self.base_names[1] + '.html'
- name = self.original_name
-
- html_entry = '''
-<tr>
-<td>
-%f<br>
-(<a href="%s">details</a>)
-</td>
-
-%s
-%s
-</tr>
-''' % (self.distance (), html_2,
- img_cell (ly_1, img_1, name), img_cell (ly_2, img_2, name))
-
-
- return html_entry
-
-
- def html_system_details_string (self):
- systems = self.system_links.items ()
- systems.sort ()
-
- html = ""
- for (c, link) in systems:
- e = '<td>%d</td>' % c
- for d in link.distance ():
- e += '<td>%f</td>' % d
-
- e = '<tr>%s</tr>' % e
-
- html += e
-
- e = '<td>%d</td>' % c
- for s in (link.output_expression_details_string (),
- link.orphan_details_string (),
- link.geo_details_string ()):
- e += "<td>%s</td>" % s
-
-
- e = '<tr>%s</tr>' % e
- html += e
-
- original = self.original_name
- html = '''<html>
-<head>
-<title>comparison details for %(original)s</title>
-</head>
-<body>
-<table border=1>
-<tr>
-<th>system</th>
-<th>output</th>
-<th>orphan</th>
-<th>geo</th>
-</tr>
-
-%(html)s
-</table>
-
-</body>
-</html>
-''' % locals ()
- return html
-
- def write_html_system_details (self, dir1, dir2, dest_dir):
- dest_file = os.path.join (dest_dir, self.base_names[1] + '.html')
-
- details = open_write_file (dest_file)
- details.write (self.html_system_details_string ())
-
-################################################################
-# Files/directories
-
-import glob
-import re
-
-
-
def compare_signature_files (f1, f2):
s1 = read_signature_file (f1)
s2 = read_signature_file (f2)
self.result_dict = {}
self.missing = []
self.added = []
- self.file_links = {}
-
+
def compare_trees (self, dir1, dir2):
self.compare_directories (dir1, dir2)
- (root, dirs, files) = os.walk (dir1).next ()
+ (root, files, dirs) = os.walk (dir1).next ()
for d in dirs:
d1 = os.path.join (dir1, d)
d2 = os.path.join (dir2, d)
-
- if os.path.islink (d1) or os.path.islink (d2):
- continue
if os.path.isdir (d2):
self.compare_trees (d1, d2)
def compare_directories (self, dir1, dir2):
-
+
(paired, m1, m2) = paired_files (dir1, dir2, '*.signature')
self.missing += [(dir1, m) for m in m1]
self.added += [(dir2, m) for m in m2]
for p in paired:
- if (inspect_max_count
- and len (self.file_links) > inspect_max_count):
-
- continue
-
f2 = dir2 + '/' + p
f1 = dir1 + '/' + p
- self.compare_files (f1, f2)
-
- def compare_files (self, f1, f2):
- name = os.path.split (f1)[1]
- name = re.sub ('-[0-9]+.signature', '', name)
+ distance = compare_signature_files (f1, f2)
+ self.result_dict[f2] = (distance, f1)
+
+ def create_text_result_page (self, dir1, dir2):
+ self.write_text_result_page (dir2 + '/' + os.path.split (dir1)[1] + '.txt')
- file_link = None
- try:
- file_link = self.file_links[name]
- except KeyError:
- file_link = FileLink ()
- self.file_links[name] = file_link
-
- file_link.add_file_compare (f1,f2)
-
- def write_text_result_page (self, filename, threshold):
+ def write_text_result_page (self, filename):
print 'writing "%s"' % filename
out = None
if filename == '':
out = sys.stdout
else:
- out = open_write_file (filename)
-
- ## todo: support more scores.
- results = [(link.distance(), link)
- for link in self.file_links.values ()]
+ out = open (filename, 'w')
+
+ results = [(score, oldfile, file) for (file, (score, oldfile)) in self.result_dict.items ()]
results.sort ()
results.reverse ()
+ for (s, oldfile, f) in results:
+ out.write ('%-30f %-20s\n' % (s, f))
+
+ for (dir, file) in self.missing:
+ out.write ('%10s%-20s %s\n' % ('', 'missing',os.path.join (dir, file)))
+ for (dir, file) in self.added:
+ out.write ('%20s%-10s %s\n' % ('','added', os.path.join (dir, file)))
+
+ def print_results (self):
+ self.write_text_result_page ('')
- for (score, link) in results:
- if score > threshold:
- out.write (link.text_record_string ())
-
- out.write ('\n\n')
- out.write ('%d below threshold\n' % len ([1 for s,l in results
- if threshold >= s > 0.0]))
- out.write ('%d unchanged\n' % len ([1 for (s,l) in results if s == 0.0]))
-
- def create_text_result_page (self, dir1, dir2, dest_dir, threshold):
- self.write_text_result_page (dest_dir + '/index.txt', threshold)
-
- def create_html_result_page (self, dir1, dir2, dest_dir, threshold):
+ def create_html_result_page (self, dir1, dir2):
dir1 = dir1.replace ('//', '/')
dir2 = dir2.replace ('//', '/')
- results = [(link.distance(), link)
- for link in self.file_links.values ()]
+ threshold = 1.0
+
+ results = [(score, oldfile, file) for (file, (score, oldfile)) in self.result_dict.items ()
+ if score > threshold]
+
results.sort ()
results.reverse ()
html = ''
old_prefix = os.path.split (dir1)[1]
- for (score, link) in results:
- if score <= threshold:
- continue
+ os.mkdir (dir2 + '/' + old_prefix)
+ for (score, oldfile, newfile) in results:
+ old_base = re.sub ("-[0-9]+.signature", '', os.path.split (oldfile)[1])
+ new_base = re.sub ("-[0-9]+.signature", '', newfile)
+
+ for ext in 'png', 'ly':
+ shutil.copy2 (old_base + '.' + ext, dir2 + '/' + old_prefix)
- link.write_html_system_details (dir1, dir2, dest_dir)
- link.link_files_for_html (dir1, dir2, dest_dir)
- html += link.html_record_string (dir1, dir2)
+ img_1 = os.path.join (old_prefix, old_base + '.png')
+ ly_1 = os.path.join (old_prefix, old_base + '.ly')
+ img_2 = new_base.replace (dir2, '') + '.png'
+ img_2 = re.sub ("^/*", '', img_2)
+
+ ly_2 = img_2.replace ('.png','.ly')
+
+ def img_cell (ly, img):
+ return '''
+<td align="center">
+<a href="%(img)s">
+<img src="%(img)s" style="border-style: none; max-width: 500px;">
+</a><br>
+<font size="-2">(<a href="%(ly)s">source</a>)
+</font>
+</td>
+''' % locals ()
+
+ html_entry = '''
+<tr>
+<td>
+%f
+</td>
+
+%s
+%s
+</tr>
+''' % (score, img_cell (ly_1, img_1), img_cell (ly_2, img_2))
+
+
+ html += html_entry
html = '''<html>
-<table rules="rows" border bordercolor="blue">
+<table>
<tr>
<th>distance</th>
-<th>%(dir1)s</th>
-<th>%(dir2)s</th>
+<th>old</th>
+<th>new</th>
</tr>
%(html)s
</table>
</html>''' % locals()
-
- html += ('<p>')
- below_count =len ([1 for s,l in results
- if threshold >= s > 0.0])
-
- if below_count:
- html += ('<p>%d below threshold</p>' % below_count)
-
- html += ('<p>%d unchanged</p>'
- % len ([1 for (s,l) in results if s == 0.0]))
-
-
- dest_file = dest_dir + '/index.html'
- open_write_file (dest_file).write (html)
+
+ open (os.path.join (dir2, old_prefix) + '.html', 'w').write (html)
+
- def print_results (self, threshold):
- self.write_text_result_page ('', threshold)
-def compare_trees (dir1, dir2, dest_dir, threshold):
- data = ComparisonData ()
+def compare_trees (dir1, dir2):
+ data = ComparisonData ()
data.compare_trees (dir1, dir2)
- data.print_results (threshold)
-
- if os.path.isdir (dest_dir):
- system ('rm -rf %s '% dest_dir)
-
- data.create_html_result_page (dir1, dir2, dest_dir, threshold)
- data.create_text_result_page (dir1, dir2, dest_dir, threshold)
+ data.print_results ()
+ data.create_html_result_page (dir1, dir2)
+ data.create_text_result_page (dir1, dir2)
################################################################
# TESTING
-def mkdir (x):
- if not os.path.isdir (x):
- print 'mkdir', x
- os.makedirs (x)
-
-def link_file (x, y):
- mkdir (os.path.split (y)[0])
- try:
- os.link (x, y)
- except OSError, z:
- print 'OSError', x, y, z
- raise OSError
-
-def open_write_file (x):
- d = os.path.split (x)[0]
- mkdir (d)
- return open (x, 'w')
-
-
+import os
def system (x):
print 'invoking', x
def test_compare_trees ():
system ('rm -rf dir1 dir2')
system ('mkdir dir1 dir2')
- system ('cp 20{-*.signature,.ly,.png} dir1')
- system ('cp 20{-*.signature,.ly,.png} dir2')
- system ('cp 20expr{-*.signature,.ly,.png} dir1')
- system ('cp 19{-*.signature,.ly,.png} dir2/')
- system ('cp 19{-*.signature,.ly,.png} dir1/')
- system ('cp 19-1.signature 19-sub-1.signature')
- system ('cp 19.ly 19-sub.ly')
- system ('cp 19.png 19-sub.png')
-
- system ('mkdir -p dir1/subdir/ dir2/subdir/')
- system ('cp 19-sub{-*.signature,.ly,.png} dir1/subdir/')
- system ('cp 19-sub{-*.signature,.ly,.png} dir2/subdir/')
- system ('cp 20grob{-*.signature,.ly,.png} dir2/')
- system ('cp 20grob{-*.signature,.ly,.png} dir1/')
+ system ('cp 20{-0.signature,.ly,.png} dir1')
+ system ('cp 20{-0.signature,.ly,.png} dir2')
+ system ('cp 20expr{-0.signature,.ly,.png} dir1')
+ system ('cp 19{-0.signature,.ly,.png} dir2/')
+ system ('cp 19{-0.signature,.ly,.png} dir1/')
+ system ('cp 20grob{-0.signature,.ly,.png} dir2/')
- ## introduce differences
- system ('cp 19-1.signature dir2/20-1.signature')
- system ('cp 20-1.signature dir2/subdir/19-sub-1.signature')
+ ## introduce difference
+ system ('cp 19-0.signature dir2/20-0.signature')
- ## radical diffs.
- system ('cp 19-1.signature dir2/20grob-1.signature')
- system ('cp 19-1.signature dir2/20grob-2.signature')
-
- compare_trees ('dir1', 'dir2', 'compare-dir1dir2', 0.5)
+ compare_trees ('dir1', 'dir2')
def test_basic_compare ():
(print-score-with-defaults
p (scorify-music m p)))))
-\sourcefilename "my-source.ly"
-
%(papermod)s
-<<
-\new Staff \relative c {
- c4^"%(userstring)s" %(extragrob)s
- }
-\new Staff \relative c {
- c4^"%(userstring)s" %(extragrob)s
+
+\relative c {
+ c^"%(userstring)s" %(extragrob)s
}
->>
"""
dicts = [{ 'papermod' : '',
'userstring': 'blabla' },
{ 'papermod' : '',
'name' : '20grob',
- 'extragrob': 'r2. \\break c1',
- 'userstring': 'test' }
-
- ]
+ 'extragrob': 'c4',
+ 'userstring': 'test' }]
for d in dicts:
open (d['name'] + '.ly','w').write (ly_template % d)
names = [d['name'] for d in dicts]
system ('lilypond -ddump-signatures --png -b eps ' + ' '.join (names))
- test_compare_signatures (names)
-def test_compare_signatures (names, timing=False):
-
- import time
-
- times = 1
- if timing:
- times = 100
-
- t0 = time.clock ()
-
- count = 0
- for t in range (0, times):
- sigs = dict ((n, read_signature_file ('%s-1.signature' % n)) for n in names)
- count += 1
-
- if timing:
- print 'elapsed', (time.clock() - t0)/count
-
-
- t0 = time.clock ()
- count = 0
+ sigs = dict ((n, read_signature_file ('%s-0.signature' % n)) for n in names)
combinations = {}
for (n1, s1) in sigs.items():
for (n2, s2) in sigs.items():
combinations['%s-%s' % (n1, n2)] = SystemLink (s1,s2).distance ()
- count += 1
-
- if timing:
- print 'elapsed', (time.clock() - t0)/count
results = combinations.items ()
results.sort ()
for k,v in results:
print '%-20s' % k, v
- assert combinations['20-20'] == (0.0,0.0,0.0)
- assert combinations['20-20expr'][0] > 0.0
- assert combinations['20-19'][2] < 10.0
- assert combinations['20-19'][2] > 0.0
+ assert combinations['20-20'] == 0.0
+ assert combinations['20-20expr'] > 50.0
+ assert combinations['20-19'] < 10.0
+
+
+def test_sigs (a,b):
+ sa = read_signature_file (a)
+ sb = read_signature_file (b)
+ link = SystemLink (sa, sb)
+ print link.distance()
def run_tests ():
+ do_clean = 1
dir = 'output-distance-test'
- do_clean = not os.path.exists (dir)
-
print 'test results in ', dir
if do_clean:
system ('rm -rf ' + dir)
system ('mkdir ' + dir)
os.chdir (dir)
- if do_clean:
- test_basic_compare ()
-
+
+ test_basic_compare ()
test_compare_trees ()
################################################################
p = optparse.OptionParser ("output-distance - compare LilyPond formatting runs")
p.usage = 'output-distance.py [options] tree1 tree2'
- p.add_option ('', '--test-self',
+ p.add_option ('', '--test',
dest="run_test",
action="store_true",
help='run test method')
-
- p.add_option ('--max-count',
- dest="max_count",
- metavar="COUNT",
- type="int",
- default=0,
- action="store",
- help='only analyze COUNT signature pairs')
-
- p.add_option ('', '--threshold',
- dest="threshold",
- default=0.3,
- action="store",
- type="float",
- help='threshold for geometric distance')
(o,a) = p.parse_args ()
p.print_usage()
sys.exit (2)
- global inspect_max_count
- inspect_max_count = o.max_count
-
- compare_trees (a[0], a[1], os.path.join (a[1], 'compare-' + a[0]),
- o.threshold)
+ compare_trees (a[0], a[1])
if __name__ == '__main__':
main()
+++ /dev/null
-#!/usr/bin/python
-import os
-import sys
-
-for i in sys.argv[1:]:
- print os.path.realpath(i)
bindir = @bindir@
build_lilypond_datadir = @build_package_datadir@
build_lilypond_libdir = @build_package_libdir@
-datarootdir = @datarootdir@
datadir = @datadir@
docdir = $(datadir)/doc
elispdir = $(datadir)/emacs/site-lisp
LN = @LN@
LN_S = @LN_S@
MAKEINFO_PROGRAM = @MAKEINFO@
+MAKEINFO_VERSION = @MAKEINFO_VERSION@
METAFONT = @METAFONT@ -progname=mf
MFMODE = @MFMODE@
MFTRACE = @MFTRACE@
WINDRES = @WINDRES@
YACC = @YACC@
ZIP = @ZIP@
+
+
+
# must come before any header checks
STEPMAKE_COMPILE
-# os.path.realpath() requires python 2.2 and unix
-STEPMAKE_PYTHON(REQUIRED, 2.2)
AC_CHECK_PROG(FCMATCH, fc-match, fc-match)
AC_MSG_CHECKING([New Century Schoolbook PFB files])
AC_SUBST(NCSB_SOURCE_FILES)
NCSB_FILE=`$FCMATCH --verbose "Century Schoolbook L:style=$style" | grep 'file:'`
NCSB_FILE=`echo $NCSB_FILE | sed 's/^.*"\(.*\)".*$/\1/g'`
- NCSB_FILE=`$PYTHON "$srcdir/buildscripts/readlink.py" $NCSB_FILE`
+ NCSB_FILE=`readlink -f $NCSB_FILE`
NCSB_SOURCE_FILES="$NCSB_FILE $NCSB_SOURCE_FILES"
done
else
regtool add '/root/LilyPond/shell/generate/command'
regtool set '/root/LilyPond/shell/generate/command/' $ROOT'\bin\bash.exe --login -c '"'"'/usr/bin/lily-wins "%1"'"'"
-# FIXME: move to new postinstall-lilypond-doc.sh
-[ -d /usr/share/info/lilypond ] && (cd /usr/share/info/lilypond && ln -sf ../../doc/lilypond/Documentation/user/out-www/*png .)
+(cd /usr/share/info/lilypond && ln -sf ../../doc/lilypond/Documentation/user/out-www/*png .)
;; The following are refreshed in LilyPond-command:
;; - current-midi depends on cursor position and
- ("Midi" . ("")) ;
+ ("Midi" . (,(concat LilyPond-midi-command " " (LilyPond-string-current-midi)))) ;
;; - all-midi depends on number of midi-score.
- ("MidiAll" . (""))
+ ("MidiAll" . (,(concat LilyPond-all-midi-command " " (LilyPond-string-all-midi))))
)
"AList of commands to execute on the current document.
ssize n = s.length ();
if (n && s[n - 1] == '/')
s[n - 1] = 0;
- if (s.rfind ('/') != NPOS)
- s = s.substr (0, s.rfind ('/'));
- else
- s = "";
-
+ s = s.substr (0, s.rfind ('/'));
return s;
}
/* Join components to full file_name. */
string
-File_name::dir_part () const
+File_name::to_string () const
{
string s;
if (!root_.empty ())
s = root_ + ::to_string (ROOTSEP);
-
if (!dir_.empty ())
{
s += dir_;
+ if (!base_.empty () || !ext_.empty ())
+ s += ::to_string (DIRSEP);
}
-
- return s;
-}
-
-
-string
-File_name::file_part () const
-{
- string s;
- s = base_;
+ s += base_;
if (!ext_.empty ())
s += ::to_string (EXTSEP) + ext_;
return s;
}
-string
-File_name::to_string () const
-{
- string d = dir_part ();
- string f = file_part ();
-
- if (!f.empty ()
- && !dir_.empty())
- {
- d += ::to_string (DIRSEP);
- }
-
- return d + f;
-}
-
File_name::File_name (string file_name)
{
#ifdef __CYGWIN__
+++ /dev/null
-# flower/lib/include/Makefile
-
-depth = ../..
-
-STEPMAKE_TEMPLATES=c++
-
-include $(depth)/make/stepmake.make
-
-
bool is_absolute () const;
string to_string () const;
-
- string dir_part () const;
- string file_part () const;
};
#endif /* FILE_NAME */
template<class T> struct Interval_t;
template<class T> struct PQueue;
-template<class T, class A> class Matrix;
+
typedef Interval_t<Real> Interval;
#ifndef INTERNATIONAL_HH
#define INTERNATIONAL_HH
-#include <stdarg.h>
-
#include "std-string.hh"
/**
string _f (char const *format, ...)
__attribute__ ((format (printf, 1, 2)));
string _f (char const *format, string s, string s2 = "", string s3 = "");
-/**
- va_list version of _f
- */
-string v_f (char const *format, va_list args);
#endif // INTERNATIONAL_HH
at (RIGHT) = t;
}
- static bool left_less (Interval_t<T> const &a, Interval_t<T> const &b)
+ static int left_comparison (Interval_t<T> const &a, Interval_t<T> const &b)
{
- return a[LEFT] < b[RIGHT];
+ return sign (a[LEFT] - b[RIGHT]);
}
};
+++ /dev/null
-/*
- matrix.hh -- declare and implement 2d arrays
-
- source file of the Flower Library
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#ifndef MATRIX_HH
-#define MATRIX_HH
-
-#include "std-vector.hh"
-
-template<class T, class A=std::allocator<T> >
-class Matrix
-{
-public:
- Matrix<T, A> ()
- {
- rank_ = 0;
- }
-
- Matrix<T, A> (vsize rows, vsize columns, T const &t)
- : data_(rows * columns, t)
- {
- rank_ = rows;
- }
-
- const T &at (vsize row, vsize col) const
- {
- assert (row < rank_ && col * rank_ + row < data_.size ());
-
- return data_[col * rank_ + row];
- }
-
- T &at (vsize row, vsize col)
- {
- assert (row < rank_ && col * rank_ + row < data_.size ());
-
- return data_[col * rank_ + row];
- }
-
- void resize (vsize rows, vsize columns, T const &t)
- {
- if (rows == rank_)
- data_.resize (rows * columns, t);
- else
- {
- vector<T,A> new_data;
- new_data.resize (rows * columns, t);
- vsize cur_cols = rank_ ? data_.size () / rank_: 0;
-
- for (vsize i = 0; i < cur_cols; i++)
- for (vsize j = 0; j < rank_; j++)
- new_data[i*rows + j] = data_[i*rank_ + j];
- rank_ = rows;
- data_ = new_data;
- }
- }
-
-private:
- vector<T, A> data_;
- vsize rank_;
-};
-
-#endif /* MATRIX_HH */
#include "compare.hh"
-#if 0
-/*
- leads to dubious crashes - libstdc++ bug?
- */
-#ifndef NDEBUG
-#define _GLIBCXX_DEBUG 1
-#endif
-#endif
-
#include <string>
using namespace std;
#ifndef STD_VECTOR_HH
#define STD_VECTOR_HH
-#if 0
-
-/*
- leads to dubious crashes - libstdc++ bug?
-*/
-#ifndef NDEBUG
-#define _GLIBCXX_DEBUG 1
-#endif
-#endif
-
#include <algorithm> /* find, reverse, sort */
#include <functional> /* unary_function */
#include <cassert>
v.insert (v.end (), w.begin (), w.end ());
}
-template<typename T, typename Compare>
-vsize
-lower_bound (vector<T> const &v,
- T const &key,
- Compare less,
- vsize b=0, vsize e=VPOS)
+template<class T>
+void
+binary_search_bounds (vector<T> const &table,
+ T const &key, int (*compare) (T const &, T const &),
+ vsize *lo,
+ vsize *hi)
{
- if (e == VPOS)
- e = v.size ();
- typename vector<T>::const_iterator i = lower_bound (v.begin () + b,
- v.begin () + e,
- key,
- less);
+ if (*lo >= *hi)
+ return;
+
+ int cmp;
+ int result;
+
+ /* binary search */
+ do
+ {
+ cmp = (*lo + *hi) / 2;
- return i - v.begin ();
+ result = (*compare) (key, table[cmp]);
+
+ if (result < 0)
+ *hi = cmp;
+ else
+ *lo = cmp;
+ }
+ while (*hi - *lo > 1);
}
-template<typename T, typename Compare>
-vsize
-upper_bound (vector<T> const &v,
- T const &key,
- Compare less,
- vsize b=0, vsize e=VPOS)
+template<typename T>
+void
+binary_search_bounds (vector<T*> const &table,
+ T const *key, int (*compare) (T *const &, T *const &),
+ vsize *lo,
+ vsize *hi)
{
- if (e == VPOS)
- e = v.size ();
+ vsize cmp;
+ int result;
- typename vector<T>::const_iterator i = upper_bound (v.begin () + b,
- v.begin () + e,
- key,
- less);
+ /* binary search */
+ do
+ {
+ cmp = (*lo + *hi) / 2;
+
+ result = (*compare) ((T *) key, table[cmp]);
- return i - v.begin ();
+ if (result < 0)
+ *hi = cmp;
+ else
+ *lo = cmp;
+ }
+ while (*hi - *lo > 1);
}
-template<typename T, typename Compare>
+#if 0
+/* FIXME: what if COMPARE is named: int operator == (T const&, T const&),
+ wouldn't that work for most uses of BINARY_SEARCH?
+*/
+template<typename T>
vsize
binary_search (vector<T> const &v,
- T const &key,
- Compare less=less<T> (),
+ T const &key, int (*compare) (T const &, T const &),
vsize b=0, vsize e=VPOS)
{
- vsize lb = lower_bound (v, key, less, b, e);
+ if (e == VPOS)
+ e = v.size ();
+ typename vector<T>::const_iterator i = find (v.begin () + b,
+ v.begin () + e,
+ key);
+ if (i != v.end ())
+ return i - v.begin ();
+ return VPOS;
+}
+#else // c&p from array.icc; cannot easily use stl_algo:find b.o. compare func.
+template<class T>
+vsize
+binary_search (vector<T> const &table,
+ T const &key,
+ int (*compare) (T const &, T const &),
+ vsize lo=0,
+ vsize hi=VPOS)
+{
+ if (hi == VPOS)
+ hi = table.size ();
- if (lb == v.size () || less (key, v[lb]))
+ if (lo >= hi)
return VPOS;
- return lb;
+
+ binary_search_bounds (table, key, compare, &lo, &hi);
+
+ if (! (*compare) (key, table[lo]))
+ return lo;
+
+ /* not found */
+ return VPOS;
}
-template<typename T, typename Compare>
+
+#endif
+
+
+#if 0
+/* FIXME: the COMPARE functionality is broken? */
+template<typename T>
void
-vector_sort (vector<T> &v,
- Compare less,
- vsize b=0, vsize e=VPOS)
+vector_sort (vector<T> &v, int (*compare) (T const &, T const &),
+ vsize lower=VPOS, vsize upper=VPOS)
{
- if (e == VPOS)
- e = v.size ();
+ typename vector<T>::iterator b = v.begin ();
+ typename vector<T>::iterator e = v.begin ();
+ if (lower == VPOS)
+ {
+ lower = 0;
+ upper = v.size ();
+ }
+ sort (b + lower, e + upper, compare);
+}
+#else
- sort (v.begin () + b, v.begin () + e, less);
+// ugh, c&p
+template<typename T> void
+vector_sort (vector<T> &v, int (*compare) (T const &, T const &),
+ vsize lower=VPOS, vsize upper=VPOS)
+{
+ if (lower == VPOS)
+ {
+ lower = 0;
+ upper = v.size () - 1;
+ }
+ if (upper == VPOS || lower >= upper)
+ return;
+ swap (v[lower], v[(lower + upper) / 2]);
+ vsize last = lower;
+ for (vsize i = lower +1; i <= upper; i++)
+ if (compare (v[i], v[lower]) < 0)
+ swap (v[++last], v[i]);
+ swap (v[lower], v[last]);
+ vector_sort (v, compare, lower, last - 1);
+ vector_sort (v, compare, last + 1, upper);
}
+#endif
template<typename T>
void
{
va_list args;
va_start (args, format);
- string str = v_f (format, args);
+ string str = String_convert::vform_string (gettext (format), args);
va_end (args);
return str;
}
-string
-v_f (char const *format, va_list args)
-{
- return String_convert::vform_string (gettext (format), args);
-}
-
string
_f (char const *format, string s, string s2, string s3)
{
{
ssize len = s.length ();
char *dest = new char[len + 1];
- copy (s.begin (), s.end (), dest);
- dest[len] = 0;
-
+ //s.copy (dest, len + 1);
+ memcpy (dest, s.c_str (), len + 1);
return dest;
}
vector<string>
string_split (string str, char c)
{
- ssize i = str.find (c);
-
vector<string> a;
+ ssize i = str.find (c);
while (i != NPOS)
{
string s = str.substr (0, i);
depth = ..
-SUBDIRS = test regression tutorial no-notation mutopia manual
+SUBDIRS = test regression tutorial no-notation mutopia
examples = typography-demo les-nereides wilhelmus proportional bach-schenker
-\version "2.9.16"
+\version "2.7.39"
\header {
composer = "ARTHUR GRAY"
+++ /dev/null
-
-depth = ../..
-
-STEPMAKE_TEMPLATES=documentation texinfo tex
-LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc
-
-## Hmm, would this work? No -- if we really want examples, move
-## to other dir (input/) comes to mind.
-## examples = font20 ancient-font
-## LOCALSTEPMAKE_TEMPLATES += ly mutopia
-
-EXTRA_DIST_FILES= README
-
-include $(depth)/make/stepmake.make
-
-TITLE=LilyPond Examples from the Manual
+++ /dev/null
-This is for large examples that are included in the manual. Most of these
-examples are distinct snippets; files that are also included in the
-regression tests should be copied from input/regression/ into this
-direction and listed here.
-
+++ /dev/null
-# -*-python-*-
-
-Import ('env', 'collate')
-collate (title = 'LilyPond Examples from the Manual')
+++ /dev/null
-
-\version "2.7.39"
-
-\header {
-
- texidoc = "There are many types of bar lines available."
-
-}
-
-\layout { ragged-right = ##t }
-
-\relative {
- \override Score.RehearsalMark #'padding = #3
-
- c4 \bar "|" \mark \markup { \simple #"|" }
- c \bar "|:" \mark \markup { \simple #"|:" }
- c \bar "||" \mark \markup { \simple #"||" }
- c \bar ":|" \mark \markup { \simple #":|" }
- c \bar ".|" \mark \markup { \simple #".|" }
- c \bar ".|." \mark \markup { \simple #".|." }
- c \bar ":|:" \mark \markup { \simple #":|:" }
- c \bar "|." \mark \markup { \simple #"|." }
- c \bar ":" \mark \markup { \simple #":" }
-
- c c c
- \bar "||:" \mark \markup { \tiny \typewriter "unbroken" \simple
-#"||:" }
- c c c c
- \break
- \bar "||:" \mark \markup { \tiny \typewriter "broken" \simple
-#"||:" }
- c
-}
+++ /dev/null
-\header {
- texidoc = "
-
-Bar numbers can be printed at regular intervals, inside a box or a circle.
-
-" }
-
-\version "2.7.39"
-
-\relative c'{
- \override Score.BarNumber #'break-visibility = #end-of-line-invisible
- \set Score.barNumberVisibility = #(every-nth-bar-number-visible 4)
- \override Score.BarNumber #'font-size = #2
-
- \override Score.BarNumber #'stencil
- = #(make-stencil-boxer 0.1 0.25 ly:text-interface::print)
- \repeat unfold 5 { c1 } \bar "|"
-
- \override Score.BarNumber #'stencil
- = #(make-stencil-circler 0.1 0.25 ly:text-interface::print)
- \repeat unfold 4 { c1 } \bar "|."
-}
-
-
+++ /dev/null
-\version "2.9.13"
-\header {
-
-texidoc = " Chord names are generated from a list pitches. The
-functions which construct these names can be customised. Here are shown
-Jazz chords, following Ignatzek (pp. 17-18, 1995) and
-an alternative Jazz chord notation.
-
-Chords following Banter (1987) can also be printed from this file, but
-are turned off for brevity.
-
-"
-
-}
-
-chs = \transpose c' c'
-{
- <c e g>1
- <c es g>% m = minor triad
- <c e gis>
- <c es ges> \break
- <c e g bes>
- <c es g bes>
- <c e g b> % triangle = maj
- <c es ges beses>
- <c es ges b> \break
- <c e gis bes>
- <c es g b>
- <c e gis b>
- <c es ges bes>\break
- <c e g a> % 6 = major triad with added sixth
- <c es g a> % m6 = minor triad with added sixth
- <c e g bes d'>
- <c es g bes d'> \break
- <c es g bes d' f' a' >
- <c es g bes d' f' >
- <c es ges bes d' >
- <c e g bes des' > \break
- <c e g bes dis'>
- <c e g bes d' f'>
- <c e g bes d' fis'>
- <c e g bes d' f' a'>\break
- <c e g bes d' fis' as'>
- <c e gis bes dis'>
- <c e g bes dis' fis'>
- <c e g bes d' f' as'>\break
- <c e g bes des' f' as'>
- <c e g bes d' fis'>
- <c e g b d'>
- <c e g bes d' f' as'>\break
- <c e g bes des' f' as'>
- <c e g bes des' f' a'>
- <c e g b d'>
- <c e g b d' f' a'>\break
- <c e g b d' fis'>
- <c e g bes des' f ' a'>
- <c f g>
- <c f g bes>\break
- <c f g bes d'>
- <c e g d'> % add9
- <c es g f'>
-}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% alternate Jazz notation
-
-efullmusicJazzAlt =
-{
- <c e gis>1-\markup { "+" }
- <c e g b>-\markup { \normal-size-super
- % \override #'(font-family . math) "N" }
- \override #'(font-family . math) "M" }
- %%c:3.5.7 = \markup { \override #'(font-family . math) "M" }
- %%c:3.5.7 = \markup { \normal-size-super "maj7" }
-
- <c es ges>-\markup { \super "o" } % should be $\circ$ ?
- <c es ges bes>-\markup { \super \combine "o" "/" }
- <c es ges beses>-\markup { \super "o7" }
-}
-
-efullJazzAlt = #(sequential-music-to-chord-exceptions efullmusicJazzAlt #f)
-
-epartialmusicJazzAlt = {
- <c d>1-\markup { \normal-size-super "2" }
- <c es>-\markup { "m" }
- <c f>-\markup { \normal-size-super "sus4" }
- <c g>-\markup { \normal-size-super "5" }
-
- %% TODO, partial exceptions
- <c es f>-\markup { "m" }-\markup { \normal-size-super "sus4" }
- <c d es>-\markup { "m" }-\markup { \normal-size-super "sus2" }
-}
-
-epartialJazzAlt = #(sequential-music-to-chord-exceptions epartialmusicJazzAlt #f)
-
-jazzAltProperties = \sequential {
- \set majorSevenSymbol = #whiteTriangleMarkup
- \set chordNameSeparator = #(make-simple-markup "/")
- \set chordNameExceptionsFull = #efullJazzAlt
- \set chordNameExceptionsPartial = #epartialJazzAlt
- \set chordNameFunction = #jazz-chord-names
-}
-
-banterProperties = \sequential {
- \set chordNameFunction = #banter-chord-names
-}
-
-\score{
- <<
- \new ChordNames {
- \set instrumentName = #"Ignatzek (default)"
- \set shortInstrumentName = #"Def"
- \chs
- }
-
- \new ChordNames {
- \jazzAltProperties
- \set instrumentName = #"Alternative"
- \set shortInstrumentName = #"Alt"
- \chs
- }
-
-%{
-
- %% This is the Banter (1987) style. It gives exceedingly
- %% verbose (wide) names, making the output file take up to 4 pages.
- %% (FIXME: how big is is now?)
- %% Turned off by default.
-
- %% FIXME: use smaller font for Banter (or remove some esoteric
- %% chords).
-
- \new ChordNames {
- \banterProperties
- \set instrumentName = #"Banter"
- \set shortInstrumentName = #"Ban"
- \chs
- }
-%}
-
- \new Staff \transpose c c' { \chs }
- >>
- \layout {
- indent = 3.\cm
- \context {
- \ChordNames
- \consists Instrument_name_engraver
- }
- }
-}
-
+++ /dev/null
-\version "2.7.39"
-\header {
- texidoc = "@cindex Chord Names German
-The english naming of chords (default) can be changed to german
-(@code{\germanChords} replaces B and Bes to H and B), semi-german
-(@code{\semiGermanChords} replaces B and Bes to H and Bb), italian
-(@code{\italianChords} uses Do Re Mi Fa Sol La Si), or french
-(@code{\frenchChords} replaces Re to Ré).
-
-" }
-
-scm = \chordmode {
- e1/d c:m
- % c/c cis/cis
- % yeah, we get the idea. -hwn
-
- % cisis/cisis ces/ces ceses/ceses
- b/b bis/bis bes/bes
- % beses/beses
-}
-
-
-\layout {
- ragged-right = ##t
- \context {\ChordNames \consists Instrument_name_engraver }
-}
-
-<<
- \new ChordNames {
- \set instrumentName = #"default"
- \scm
- }
- \new ChordNames {
- \set instrumentName = #"german"
- \germanChords \scm }
- \new ChordNames {
- \set instrumentName = #"semi-german"
- \semiGermanChords \scm }
- \new ChordNames {
- \set instrumentName = #"italian"
- \italianChords \scm }
- \new ChordNames {
- \set instrumentName = #"french"
- \frenchChords \scm }
-
- \context Voice { \scm }
->>
+++ /dev/null
-% possible rename to ancient- or gregorian- ?
-\header {
- texidoc = "@cindex Divisiones
-
-Divisiones are ancient variants of breathing signs.
-Choices are @code{divisioMinima}, @code{divisioMaior},
-@code{divisioMaxima} and @code{finalis}, @code{virgula} and
-@code{caesura}.
-
-" }
-
-\version "2.7.39"
-
-\include "gregorian-init.ly"
-
-\score {
- <<
- \context VaticanaVoice {
- \override TextScript #'padding = #3
- g a g
- s^\markup { "divisio minima" }
- \divisioMinima
- g a g
- s^\markup { "divisio maior" }
- \divisioMaior
- g a g
- s^\markup { "divisio maxima" }
- \divisioMaxima
- \break
- g a g
- s^\markup { "finalis" }
- \finalis
- g a g
- s^\markup { "virgula" }
- \virgula
- g a g
- s^\markup { "caesura" }
- \caesura
- g a g
- }
- >>
-}
+++ /dev/null
-%% texidoc = "Include file for engraver example."
-\version "2.7.39"
-topVoice = \relative c' {
- \key d\major
- es8([ g] a[ fis])
- b4
- b16[-. b-. b-. cis-.]
- d4->
-}
-
-botVoice = \relative c' {
- \key d\major
- c8[( f] b[ a)]
- es4
- es16[-. es-. es-. fis-.]
- b4->
-}
-
-hoom = \relative c {
- \key d \major
- \clef bass
- g8-. r
- r4
- fis8-.
- r8
- r4
- b'4->
-}
-
-pah = \relative c' {
- r8 b-.
- r4
- r8 g8-.
- r16 g-. r8
- \clef treble
- fis'4->
-}
+++ /dev/null
-
-#(set-global-staff-size 16)
-
-\paper {
- %% ugh. text on toplevel is a bit broken... .
-
- oddHeaderMarkup = \markup {}
- evenHeaderMarkup = \markup {}
- oddFooterMarkup = \markup {}
- evenFooterMarkup = \markup {}
- }
-
-\version "2.7.39"
-
-#(define (doc-char name)
- (make-line-markup
- (list
- (make-pad-to-box-markup
- '(0 . 30)
- '(-2 . 2)
- (make-typewriter-markup (make-small-markup name)))
- (make-pad-to-box-markup
- '(-2 . 2)
- '(-2 . 2)
- (make-musicglyph-markup name)))))
-
-#(define (min-length lst n)
- "(min (length lst) n)"
-
- (if (or (null? lst) (<= n 0))
- 0
- (1+ (min-length (cdr lst) (1- n)) )))
-
-#(define (doc-chars names acc)
- (let*
- ((n (min-length names 2))
- (head (take names n))
- (tail (drop names n))
- )
-
- (if (null? head)
- acc
- (doc-chars tail
- (cons (make-line-markup (map doc-char head)) acc)))
- ))
-
-#(define (group-lines lines)
- (let*
- ((n (min-length lines 25))
- (head (take lines n))
- (tail (drop lines n))
- )
-
- (cons
- (make-column-markup head)
- (if (null? tail)
- '()
- (group-lines tail)))))
-
-#(let*
- ((lines (doc-chars
- (ly:otf-glyph-list (ly:font-load "emmentaler-20"))
- '()))
- (pages (group-lines (reverse lines))))
-
- (for-each
- (lambda (x)
- (collect-scores-for-book parser
- (make-override-markup '(word-space . 8) x)))
- pages))
-
-
+++ /dev/null
-
-\header { texidoc = "Ossia fragments can be done with starting and
-stopping staves. " }
-
-\version "2.7.39"
-\paper { ragged-right = ##t }
-
-<<
- \new Staff \with
- {
- \remove "Time_signature_engraver"
- fontSize = #-2
- \override StaffSymbol #'staff-space = #(magstep -2)
- firstClef = ##f
- }
- \relative c'' {
- \stopStaff
- \skip 2
-
- \startStaff
- \clef treble
- bes8[^"ossia" g bes g]
- \stopStaff
-
- s2
-
- \startStaff
- f8 d g4
- }
- \new Staff \relative
- {
- \time 2/4
- c4 c g' g a a g2
- }
-
->>
+++ /dev/null
-\version "2.9.16"
-\header {
- title = "Screech and boink"
- subtitle = "Random complex notation"
- composer = "Han-Wen Nienhuys"
-}
-
-\score {
- \context PianoStaff <<
- \new Staff = "up" {
- \time 4/8
- \key c \minor
-
-
- << {
- \revert Stem #'direction
- \change Staff = down
- \set subdivideBeams = ##t
- g16.[
- \change Staff = up
- c'''32 \change Staff = down
- g32 \change Staff = up
- c'''32 \change Staff = down
- g16]
- \change Staff = up
- \stemUp
- \set followVoice = ##t
- c'''32([ b''16 a''16 gis''16 g''32)] } \\
- { s4 \times 2/3 { d'16[ f' g'] } as'32[ b''32 e'' d''] } \\
- { s4 \autoBeamOff d''8.. f''32 } \\
- { s4 es''4 }
- >>
- }
-
- \new Staff = "down" {
- \clef bass
- \key c \minor
- \set subdivideBeams = ##f
- \override Stem #'french-beaming = ##t
- \override Beam #'thickness = #0.3
- \override Stem #'thickness = #4.0
- g'16[ b16 fis16 g16]
- << \makeClusters {
- as16 <as b>
- <g b>
- <g cis>
- } \\
- {
- \override Staff.Arpeggio #'arpeggio-direction =#down
- <cis, e, gis, b, cis>4\arpeggio }
- >>
- }
- >>
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 60 8)
- }
- }
-
-
-
- \layout {
- ragged-right = ##t
-
- \context {
- \Staff
- \consists Horizontal_bracket_engraver
- }
-
- }
-}
+++ /dev/null
-
-% this chart is used in the manual too.
-
-\version "2.7.39"
-\header { texidoc = "@cindex Script Abbreviations
-
-Some articulations may be entered using an abbreviation.
-
-"
-
-}
-
-\score {
- \context Voice {
- \override TextScript #'font-family = #'typewriter
- \override TextScript #'font-shape = #'upright
- c''4-._"c-." s4
- c''4--_"c--" s4
- c''4-+_"c-+" s4
- c''4-|_"c-|" s4
- c''4->_"c->" s4
- c''4-^_"c-^" s4
- c''4-__"c-_" s4
- }
- }
-
+++ /dev/null
-\version "2.7.39"
-
-% this chart is used in the manual too.
-
-\header {
- texidoc ="@cindex Feta scripts
-
-This chart shows all articulations, or scripts, that feta font contains.
-
-"
-}
-
-\score {
- <<
- \override Score.LyricText #'font-family = #'typewriter
- \override Score.LyricText #'font-shape = #'upright
- \context Staff {
- \set Score.timing = ##f
- \set Score.barAlways = ##t
- \override Score.SeparationItem #'padding = #2.5
- \override Staff.BarLine #'transparent = ##t
- c''\accent c''\marcato c''\staccatissimo c''\espressivo
- c''\staccato c''\tenuto c''\portato
- c''\upbow c''\downbow c''\flageolet
- c''\thumb c''^\lheel c''\rheel
- c''^\ltoe c''\rtoe c''\open
- c''\stopped c''\turn c''\reverseturn
- c''\trill c''\prall c''\mordent
- c''\prallprall c''\prallmordent c''\upprall
- c''\downprall c''\upmordent c''\downmordent
- c''\pralldown c''\prallup c''\lineprall
- c''\signumcongruentiae c''\shortfermata c''\fermata
- c''\longfermata c''\verylongfermata c''\segno
- c''\coda c''\varcoda
- }
- \context Lyrics \lyricmode {
- accent__ marcato__ staccatissimo__ espressivo__
- staccato__ tenuto__ portato__
- upbow__ downbow__ flageolet__
- thumb__ lheel__ rheel__
- ltoe__ rtoe__ open__
- stopped__ turn__ reverseturn__
- trill__ prall__ mordent__
- prallprall__ prallmordent__ upprall__
- downprall__ upmordent__ downmordent__
- pralldown__ prallup__ lineprall__
- signumcongruentiae__ shortfermata__ fermata__
- longfermata__ verylongfermata__ segno__
- coda__ varcoda__
- }
- >>
- \layout {
- line-width = 5.1\in
- indent = 0.0\mm
- }
- }
-
-
copyright = "Public Domain"
}
-\version "2.9.16"
+\version "2.7.39"
global = {
\key a \minor
\override SpacingSpanner #'spacing-increment = #3
}
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 60 4)
- }
+ \midi {
+ \tempo 4 = 60
}
-
-
}
%% Local Variables:
\lyricsto "singer" \new Lyrics \firstVerse
\lyricsto "singer" \new Lyrics \secondVerse
\new PianoStaff <<
- \set PianoStaff.instrumentName = \markup {
+ \set PianoStaff.instrument = \markup {
\bold
\bigger\bigger\bigger\bigger \huge "2. " }
\new Staff \pianoRH
}
}
\midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 70 4)
- }
+ \tempo 4 = 70
}
}
}
footer = "Mutopia-2001/04/27-xx"
}
-\version "2.9.16"
+\version "2.7.39"
#(set-global-staff-size 16)
\context { \RemoveEmptyStaffContext }
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 54 4)
- }
+ \midi{
+ \tempo 4 = 54
}
-
-
}
-\version "2.9.16"
+\version "2.7.39"
forcedLastBreak = { \break }
d'[ cis] |
%% d4 d,,2 |
d4
-% #(assert-system-count-override 6)
+ #(assert-system-count-override 6)
d,,2 |
}
line-width =183.5 \mm
between-system-space = 25\mm
between-system-padding = 0\mm
- system-count = 6
%% annotatespacing = ##t
}
\score{
\sarabandeCelloStaff
\layout { }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 40 4)
- }
- }
-
-
+ \midi{ \tempo 4 = 40 }
\header{
opus= ""
piece ="Sarabande" }
#(ly:set-option 'old-relative)
-\version "2.9.16"
+\version "2.7.39"
%{
Header for Petites Preludes.
\override SpacingSpanner #'spacing-increment = #2.0
}
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 40 4)
- }
- }
-
-
+ \midi{ \tempo 4 = 40 }
}
}
\layout {}
\midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 84 4)
- }
+ \tempo 4 =84
}
}
\paper {
#(set-global-staff-size 16)
-\version "2.9.16"
+\version "2.7.39"
\header {
title = "Romanzen"
\override PianoStaff.InstrumentName #'font-shape = #'italic
\override PianoStaff.InstrumentName #'font-magnification = #3
- \set PianoStaff.instrumentName = " 2."
+ \set PianoStaff.instrument = " 2."
\new Staff = "up" {
\override Staff.DynamicLineSpanner #'direction = #DOWN
\clef G <<\global \new Voice = "upv" \righta >>
\override Staff.InstrumentName #'font-shape = #'upright
\override Staff.InstrumentName #'font-magnification = #1
\override Staff.InstrumentName #'extra-offset = #'(0 . 6)
- % \set Staff.instrumentName = "\\begin{turn}{-90}{Rechte Hand}\\end{turn}"
- \set Staff.instrumentName = \markup { \column { Rechte Hand } \hspace #2 }
+ % \set Staff.instrument = "\\begin{turn}{-90}{Rechte Hand}\\end{turn}"
+ \set Staff.instrument = \markup { \column { Rechte Hand } \hspace #2 }
\clef F <<\global \new Voice = "midv" \rightb>>
}
\new Staff = "down" {
\override VerticalAlignment #'forced-distance = #13.0
}
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 100 8)
- }
- }
-
-
+ \midi { \tempo 8=100 }
}
mutopiacomposer = "W.A.Mozart"
mutopiaopus = "KV447"
style = "classical"
- maintainer = "hanwen@xs4all.nl"
- maintainerEmail = "hanwen@xs4all.nl"
- maintainerWeb = "http://www.xs4all.nl/~hanwen/"
+ maintainer = "hanwen@cs.uu.nl"
+ maintainerEmail = "hanwen@cs.uu.nl"
+ maintainerWeb = "http://www.cs.uu.nl/~hanwen/"
lastupdated = "2002/May/21"
source = "Edition Breitkopf 2563"
footer = "Mutopia-2002/05/21-25"
\column {
\fill-line { \footer "" }
\fill-line { { "This music is part of the Mutopia project,"
- \typewriter { "http://mutopiaproject.org/" }
+ \typewriter { "http://sca.uwaterloo.ca/Mutopia/" }
} }
\fill-line { #(ly:export (string-append "It has been typeset and placed in the public "
"domain by " maintainer ".")) }
%}
-\version "2.9.16"
+\version "2.7.39"
\include "mozart-hrn3-defs.ily"
\include "mozart-hrn3-allegro.ily"
{ \transpose c' bes \allegro }
\layout { }
\header { piece = "Allegro" opus = "" }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 90 4)
- }
- }
-
-
+ \midi { \tempo 4=90 }
}
\score {
{ \transpose c' bes \romanze }
\header { piece = "Romanze" opus = "" }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 70 4)
- }
- }
-
-
+ \midi { \tempo 4 = 70 }
\layout {}
}
{
{ \transpose c' bes \rondo }
\header { piece = "Rondo" opus = "" }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 100 4)
- }
- }
-
-
+ \midi { \tempo 4 = 100 }
\layout { }
}
}
indent = 10. \mm
line-width = 189. \mm
- ragged-last-bottom = ##f
}
-\version "2.9.16"
+\version "2.9.5"
#(use-modules (srfi srfi-13)
(ice-9 format))
-\version "2.9.16"
+\version "2.7.39"
\header {
texidoc = "@cindex Dynamic Absolute Volume
Absolute dynamics have an effect on MIDI files.
a\sf
}
\layout{ ragged-right = ##t }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 60 1)
- }
- }
-
-
+\midi{
+\tempo 1 = 60
+}
}
#(ly:set-option 'old-relative)
-\version "2.9.16"
+\version "2.7.39"
\header {
texidoc = "@cindex Midi Volume Equaliser
The full orchestra plays a notes, where groups stop one after
flauti = \relative c' {
\set Staff.midiInstrument = #"flute"
- \set Staff.instrumentName = #"2 Flauti"
- \set Staff.shortInstrumentName = #"Fl."
+ \set Staff.instrument = #"2 Flauti"
+ \set Staff.instr = #"Fl."
c1\f R1*10
}
oboi = \relative c' {
\set Staff.midiInstrument = #"oboe"
- \set Staff.instrumentName = #"2 Oboi"
- \set Staff.shortInstrumentName = #"Ob."
+ \set Staff.instrument = #"2 Oboi"
+ \set Staff.instr = #"Ob."
R1*1 c1\f R1*9
}
clarinetti = \relative c' {
\set Staff.midiInstrument = #"clarinet"
- \set Staff.instrumentName = #"Clarinetti"
- \set Staff.shortInstrumentName = #"Cl"
+ \set Staff.instrument = #"Clarinetti"
+ \set Staff.instr = #"Cl"
R1*2 c1\f R1*8
}
fagotti = \relative c' {
\set Staff.midiInstrument = #"bassoon"
- \set Staff.instrumentName = #"2 Fagotti"
- \set Staff.shortInstrumentName = #"Fg."
+ \set Staff.instrument = #"2 Fagotti"
+ \set Staff.instr = #"Fg."
\clef bass
R1*3 c1\f R1*7
corni = \relative c' {
\set Staff.midiInstrument = #"french horn"
- \set Staff.instrumentName = #"Corni"
- \set Staff.shortInstrumentName = #"Cor"
+ \set Staff.instrument = #"Corni"
+ \set Staff.instr = #"Cor"
R1*4 c1\f R1*6
}
trombe = \relative c' {
\set Staff.midiInstrument = #"trumpet"
- \set Staff.instrumentName = #"Trombe"
- \set Staff.shortInstrumentName = #"Tp."
+ \set Staff.instrument = #"Trombe"
+ \set Staff.instr = #"Tp."
\clef bass
R1*5 c1\f R1*5
timpani = \relative c' {
\set Staff.midiInstrument = #"timpani"
- \set Staff.instrumentName = #"Timpani"
- \set Staff.shortInstrumentName = #"Timp."
+ \set Staff.instrument = #"Timpani"
+ \set Staff.instr = #"Timp."
R1*6 c1\f R1*4
}
violinoI = \relative c' {
\set Staff.midiInstrument = #"violin"
- \set Staff.instrumentName = #"Violino I "
- \set Staff.shortInstrumentName = #"Vl. I "
+ \set Staff.instrument = #"Violino I "
+ \set Staff.instr = #"Vl. I "
R1*7 c1\f R1*3
}
violinoII = \relative c' {
\set Staff.midiInstrument = #"violin"
- \set Staff.instrumentName = #"Violino II "
- \set Staff.shortInstrumentName = #"Vl. II "
+ \set Staff.instrument = #"Violino II "
+ \set Staff.instr = #"Vl. II "
R1*8 c1\f R1*2
}
viola = \relative c' {
\set Staff.midiInstrument = #"viola"
- \set Staff.instrumentName = #"Viola"
- \set Staff.shortInstrumentName = #"Vla."
+ \set Staff.instrument = #"Viola"
+ \set Staff.instr = #"Vla."
\clef alto
R1*9 c1\f R1*1
violoncello = \relative c' {
\set Staff.midiInstrument = #"cello"
%\set Staff.midiInstrument = #"contrabass"
- \set Staff.instrumentName = #"Violoncello"
- \set Staff.shortInstrumentName = #"Vc."
+ \set Staff.instrument = #"Violoncello"
+ \set Staff.instr = #"Vc."
\clef bass
R1*10 c1\f
\RemoveEmptyStaffContext
}
}
-
\midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 60 1)
- }
- }
-
-
+ \tempo 1 = 60
+ }
}
-\version "2.9.11"
+\version "2.7.39"
\header
{
\context {
\Voice
\remove "Forbid_line_break_engraver"
- \override TupletNumber #'text = #tuplet-number::calc-fraction-text
+ tupletNumberFormatFunction = #fraction-tuplet-formatter
tupletFullLength = ##t
allowBeamBreak = ##t
}
-\version "2.9.13"
+\version "2.7.39"
\header {
title = "Puer natus est nobis"
subtitle = "Antiphona ad introitum VII"
%%% global search/replace operations in emacs).
cantus = \new VaticanaVoice = "cantus" {
- \set Staff.instrumentName = \markup {
+ \set Staff.instrument = \markup {
\column {
" " " " " " " " "VII" " "
{
BugFree (tm). This document is intended for finding bugs and for
documenting bugfixes.
-In the web version of this document, you can click on the file name
-or figure for each example to see the corresponding input file.
-
TODO: order of tests (file names!), test only one feature per test.
Smaller and neater tests.
")
+++ /dev/null
-\version "2.9.18"
-
-\header {
- texidoc = "Accidentals can be forced with ! and ? even if the notes are tied."
-}
-
-\layout {
- ragged-right = ##t
-}
-
-\relative {
- gis'4 ~ gis!~ gis?
- }
}
-\version "2.9.13"
+\version "2.7.39"
#(set-global-staff-size 13)
\new Staff { c1 c c }
\new PianoStaff <<
\new Voice {
- \set PianoStaff.instrumentName = #"piano"
- \set PianoStaff.shortInstrumentName = #"pn"
+ \set PianoStaff.instrument = #"piano"
+ \set PianoStaff.instr = #"pn"
c1_"normal"
\overrideProperty
+++ /dev/null
-
-\header { texidoc = "The dashes in a dashed bar line covers staff
- lines exactly. Dashed barlines between staves start and end on a
- half dash precisely." }
-
-\version "2.9.13"
-
-\paper { ragged-right = ##t }
-
-\relative \new StaffGroup <<
- \new Staff {
- c4 \bar "dashed" c }
- \new Staff {
- c c
- }
->>
-
-\version "2.9.13"
+\version "2.7.39"
\header{
texidoc="
\layout { ragged-right = ##t }
onestaff = \new Staff\relative c'' {
- \set Staff.shortInstrumentName = instr
- \set Staff.instrumentName = instrument \mark "B"
+ \set Staff.instr = instr
+ \set Staff.instrument = instrument \mark "B"
c1 \mark "A" \break c2 c2 \break
}
\context GrandStaff <<
\new Staff {
- \set Staff.shortInstrumentName = instr
+ \set Staff.instr = instr
\mark "B" \break c1 \mark "A" c2 }
\new Staff { c1 c2 }
-\version "2.9.10"
-
+\version "2.7.39"
\header {
-
- texidoc = "Automatic beaming works also in ternary time sigs. In
- this case, the 8th is a beat, so the 16ths are split into two
- groups. This can be avoided by overriding @code{beatLength} to be 3
- 8th notes."
-
+ texidoc = "Automatic beaming works also in ternary time sigs."
}
-
\layout { ragged-right = ##t}
\relative c'' {
\time 6/8
c8.[ c16 c16 c16]
- \set beatLength = #(ly:make-moment 3 8)
- c8.[ c16 c16 c16]
}
\header{
texidoc="
Beaming is generated automatically. Beams may cross bar lines. In that
-case, line breaks are forbidden.
+case, line breaks are forbidden. Yet clef and key signatures are
+hidden just as with breakable bar lines.
"
}
\context Staff \relative c'' {
-
- c8[ \times 2/3 { c16 d e] }
- s4*3
-
c8.[ c16]
c8.[ c16 c8. c16]
c16[ c8.] |
c32
c2
- c8[^"over barline" c c] c8
+ c8[ c c] c8 % over barline
c16[ c8 c16]
c32[ c16 c16 c16 c32]
c32[ c16 c8 c32] % hmm ?
+++ /dev/null
-\version "2.9.12"
-
-\header {
-
- texidoc = "Falls and doits can be created with bendAfter. They run
- to the next note, or to the next barline."
-
-}
-
-\paper {
- ragged-right = ##T
-}
-
-\relative c'' {
- \override Score.SpacingSpanner #'shortest-duration-space = #3.0
- c4-\bendAfter #+5
- c4-\bendAfter #+4
- c4-\bendAfter #+3
- c4-\bendAfter #+2
- c4-\bendAfter #+1
- c4-\bendAfter #-1
- c4-\bendAfter #-2
- c4-\bendAfter #-3
- c4-\bendAfter #-4
-}
\include "gregorian-init.ly"
+
+%%
+%% Gregorian notation:
+%%
\context VaticanaStaff {
\relative c' {
- % here is no \breathe
+
+ %% we turn bars and bar numbers off for Gregorian stuff
+ \override Staff.BarLine #'transparent = ##t
+ \override Score.BarNumber #'transparent = ##t
+
+ %% here is no \breathe
c g c
- % \virgula applies rcomma, but in a smaller font
+ %% \virgula applies rcomma, but in a smaller font
c \virgula g c
- % \caesura applies rvarcomma, but in a smaller font
+ %% \caesura applies rvarcomma, but in a smaller font
c \caesura g c
- % \divisioMinima is a simple vertical stroke through the
- % uppermost staffline, just like the original implementation
- % of breathing signs.
+ %% \divisioMinima is a simple vertical stroke through the
+ %% uppermost staffline, just like the original implementation
+ %% of breathing signs.
c \divisioMinima g c
- % \divisioMaior, \divisioMaxima and \finalis look like bars and
- % are vertically centered on the staff; the direction property
- % has no effect
+ %% \divisio{maior,maxima} and \finalis look like bars and are
+ %% vertically centered on the staff; the direction property has
+ %% no effect
c \divisioMaior g c
c \divisioMaxima g c
- % this one looks almost like a "||" type bar
+ %% this one looks almost like a "||" type bar
\finalis
}
}
}
-\version "2.9.16"
+\version "2.7.39"
drh = \drummode { cymc4.^"crash" hhc16^"h.h." hh \repeat "unfold" 5 {hhc8 hho hhc8 hh16 hh} hhc4 r4 r2 }
drl = \drummode {\repeat "unfold" 3 {bd4 sn8 bd bd4 << bd ss >> } bd8 tommh tommh bd toml toml bd tomfh16 tomfh }
\override StaffSymbol #'line-count = #2
\override BarLine #'bar-size = #2
} <<
- \set Staff.instrumentName = "timbales"
+ \set Staff.instrument = "timbales"
\timb
>>
\new DrumStaff <<
- \set Staff.instrumentName = "drums"
+ \set Staff.instrument = "drums"
\new DrumVoice {\stemUp \drh }
\new DrumVoice {\stemDown \drl }
>>
\layout {}
%% broken:
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 120 4)
- }
- }
-
-
+ \midi{ \tempo 4=120 }
}
\paper {
ragged-right = ##t
-}
+}
\version "2.9.7"
-
\header {
+
texidoc = "Figured bass can also be added to Staff context directly.
In that case, the figures must be entered with @code{\\figuremode} and be directed
-to an existing @code{Staff} context.
+to an existing @code{Staff} context."
-Since these engravers are on @code{Staff} level, properties
-controlling figured bass should be set in @code{Staff} context.
-
-"
-
-}
+ }
<<
}
-\version "2.9.13"
+\version "2.7.39"
\new PianoStaff <<
\new Staff {
\override Staff.VerticalAxisGroup #'remove-empty = ##t
- \set PianoStaff.instrumentName ="up"
- \set PianoStaff.shortInstrumentName ="u"
+ \set PianoStaff.instrument="up"
+ \set PianoStaff.instr="u"
c'1\break R
}
>>
\layout { ragged-right = ##t }
-\version "2.9.13"
+\version "2.7.39"
textFlat = \markup {\smaller \flat}
\new Staff {
- \set Staff.instrumentName = \markup { \column { "Clarinetti" \line { "in B" \textFlat } } }
- \set Staff.shortInstrumentName = \markup { \smaller { "Cl(B" \textFlat ")" } }
+ \set Staff.instrument = \markup { \column { "Clarinetti" \line { "in B" \textFlat } } }
+ \set Staff.instr = \markup { \smaller { "Cl(B" \textFlat ")" } }
{ c''1 \break c'' }
}
-\version "2.9.13"
+\version "2.7.39"
\header {
texidoc = "Instrument names are also printed on partial starting measures."
}
-\relative c'' { \set Staff.instrumentName = "foo" \partial 4 c4 c1 }
+\relative c'' { \set Staff.instrument = "foo" \partial 4 c4 c1 }
-\version "2.9.13"
+\version "2.7.39"
\header{
texidoc="
Staff margins are also markings attached to barlines. They should be
\new StaffGroup <<
\context PianoStaff <<
\new Staff {
- \set PianoStaff.instrumentName = "Piano"
- \set Staff.instrumentName = "Right" { c''4 }}
+ \set PianoStaff.instrument = "Piano"
+ \set Staff.instrument = "Right" { c''4 }}
\new Staff {
- \set Staff.instrumentName = "Left"
+ \set Staff.instrument = "Left"
\clef bass c4
}
>>
+++ /dev/null
-
-\header {
-
- texidoc = "The @code{switchInstrument} music function modifies
-properties for an in staff instrument switch. "
- }
-
-\version "2.9.13"
-\addInstrumentDefinition #"bassClar"
- #`((instrumentTransposition . ,(ly:make-pitch -1 6 FLAT))
- (instrumentName . "bla")
- (shortInstrumentName . "bl")
- (clefGlyph . "clefs.F")
- (middleCPosition . 6)
- (clefPosition . 2)
- (instrumentCueName . ,(make-bold-markup "cl. B"))
- (midiInstrument . "clarinet"))
-
-
-\paper {
- ragged-right = ##t
-}
-
-\relative
-{
- c4
- \instrumentSwitch "bassClar"
- c2.\break
- c1\break
- c
-}
\layout { ragged-right = ##t }
-\version "2.9.16"
+\version "2.7.39"
\relative c'' {
\tempo \breve = 100 c1 c1 \tempo 8.. = 50 c1
-\version "2.9.13"
+\version "2.7.39"
\header {
texidoc = "There are both long and short instrument names.
\context Staff <<
- \set Staff.instrumentName = "instrument"
- \set Staff.shortInstrumentName = "instr"
+ \set Staff.instrument = "instrument"
+ \set Staff.instr = "instr"
{c''1 \break R1 }
>>
fragment = {
\key c \major
\set shapeNoteStyles = ##(do re mi fa #f la ti)
- c1 d e f g a b c d e f g a b c
- c,,2 d e f g a b c d e f g a b c
- c,,4 d e f g a b c d e f g a b c
+ c d e f g a b c d e f g a b c
}
+++ /dev/null
-\version "2.9.13"
-
-\header{
- texidoc="The optimal page breaker will stretch the
-systems horizontally so that the vertical spacing will be
-more acceptable. The page-spacing-weight parameter
-controls the relative importance of vertical/horizontal
-spacing. Because ragged-last-bottom is on, only the
-first page should be horizontally stretched.
-"
-}
-
-\paper {
- #(define page-breaking ly:optimal-breaking)
- page-spacing-weight = #10
- ragged-last-bottom = ##t
-}
-
-\relative c' {
- \repeat unfold 5 {a b c d} \pageBreak
- \repeat unfold 5 {a b c d}
-}
-
-
line-width = 5.0\cm
headerMarkup = "header"
indent =0.0
- annotate-spacing = ##f
- annotate-page = ##t
- annotate-headers = ##t
+ annotatespacing = ##f
+ annotatepage = ##t
+ annotateheaders = ##t
}
\book {
line-width = 15\cm
%rigthmargin = 3\cm
interscoreline = 3\cm
-
- annotate-spacing = ##t
-
-
-
- }
+}
\book {
setting properties on individual object. @code{\override} may still be
used for global overrides.
-By setting @code{annotate-spacing}, we can see the effect of each property.
+By setting @code{annotatespacing}, we can see the effect of each property.
"
}
+++ /dev/null
-\version "2.9.13"
-
-\header{
- texidoc="If there are no good places to have a page turn,
-the optimal-breaker will just have to recover gracefully. This
-should appear on 3 pages.
-"
-}
-
-\paper {
- #(define page-breaking ly:page-turn-breaking)
- paper-height = #70
- print-page-number = ##t
-}
-
-\relative c' {
- a b c d a b c d \break
- c d e f c d e f \break
- d e f g d e f g
-}
-
-
+++ /dev/null
-\version "2.9.13"
-
-\header{
- texidoc="The page-turn breaker will put a page turn after
-a rest unless there is a 'special' barline within the rest,
-in which case the turn will go after the special barline.
-"
-}
-
-\paper {
- #(define page-breaking ly:page-turn-breaking)
- paper-height = #70
- auto-first-page-number = ##t
- print-page-number = ##t
- print-first-page-number = ##t
-}
-
-\layout {
- \context {
- \Staff
- \consists "Page_turn_engraver"
- }
-}
-
-\relative c' {
- a b c d a b c d \break
- c d e f c d e f R1*4
- \repeat unfold 15 {d4 e f g} \break
- c d e f c d e f R1*2 \bar "||" R1*2
- \repeat unfold 15 {d4 e f g}
-}
-
-\version "2.9.13"
+\version "2.7.39"
\header {
texidoc = "Distances between prefatory items (e.g. clef, bar,
}
\relative c'' {
- \set Staff.instrumentName = "fobar"
+ \set Staff.instrument = "fobar"
\bar "||:"
\key cis \major
cis4 cis4 cis4 cis4 \clef bass cis,1
}
-\version "2.9.13"
+\version "2.7.39"
\layout {
ragged-right = ##t
}
<<
\new Staff {
- \set Staff.instrumentName = "quoteMe"
+ \set Staff.instrument = "quoteMe"
\quoteMe
}
\new Staff {
- \set Staff.instrumentName = "orig (killCues)"
+ \set Staff.instrument = "orig (killCues)"
\killCues \original
}
\new Staff {
- \set Staff.instrumentName = "orig+quote"
+ \set Staff.instrument = "orig+quote"
\cueStaff
}
>>
@code{rest-event} is not in @code{quotedEventTypes}."
}
-\version "2.9.13"
+\version "2.7.39"
\layout {
ragged-right = ##t
}
<<
\new Staff {
- \set Staff.instrumentName = "quoteMe"
+ \set Staff.instrument = "quoteMe"
\quoteMe
}
\new Staff {
- \set Staff.instrumentName = "orig"
+ \set Staff.instrument = "orig"
\original
}
\new Staff \relative c'' <<
- \set Staff.instrumentName = "orig+quote"
+ \set Staff.instrument = "orig+quote"
\set Staff.quotedEventTypes = #'(note-event articulation-event)
\original
{ s4 \quoteDuring #"quoteMe" { s2. } }
}
\paper { ragged-right= ##t }
-\version "2.9.13"
+\version "2.7.39"
quoted = \relative c'' {
R1
\grace g16 f4 \grace a16 bes4 \grace b16 c4 c4
<<
\new Staff {
- \set Staff.instrumentName = "quoted"
+ \set Staff.instrument = "quoted"
\quoted
}
\new Staff \new Voice \relative c'' {
- \set Staff.instrumentName = "quoted"
+ \set Staff.instrument = "quoted"
R1
\cueDuring #"quoted" #1 { \grace s16. r2 }
c2^"original"
+++ /dev/null
-\version "2.9.7"
-
-\header {
-
- texidoc = " Voices from different cues must not be tied together. In
-this example, the first note has a tie. This note should not be tied
-to the 2nd note. "
-
-}
-
-\paper {
- ragged-right = ##t
-}
-
-cueI = \relative c'' {
- a1 ~ | a | a |
-}
-\addquote "cueI" { \cueI }
-
-cueII = \relative c' {
- R1 | e | a |
-}
-\addquote "cueII" { \cueII }
-
-\new Staff {
- \cueDuring "cueI" #UP { R1 } |
- R1
- \cueDuring "cueII" #UP { R1 } |
-}
@code{rest-event} is not in @code{quotedEventTypes}."
}
-\version "2.9.13"
+\version "2.7.39"
\layout {
ragged-right = ##t
}
<<
\new Staff {
- \set Staff.instrumentName = "quoteMe"
+ \set Staff.instrument = "quoteMe"
\quoteMe
}
\new Staff {
- \set Staff.instrumentName = "orig"
+ \set Staff.instrument = "orig"
\original
}
\new Staff \relative c'' <<
- \set Staff.instrumentName = "orig+quote"
+ \set Staff.instrument = "orig+quote"
\set Staff.quotedEventTypes = #'(note-event articulation-event)
\original
\new Voice {
+++ /dev/null
-\version "2.9.20"
-
-\header {
- texidoc = "Percent repeats are also centered when there is a grace note in a parallel staff. "
-}
-
-\layout {
- ragged-right =##t
-}
-
-\relative <<
- \new Staff { \repeat percent 3 c1}
- \new Staff { c1 c \grace b8 c1 }
->>
+++ /dev/null
-
-\header {
-
- texidoc = "In rest-note collisions, the rest moves in discrete
- steps, and inside the staff, it moves in whole staff spaces."
-
- }
-
-
-\version "2.9.18"
-\new Staff {
-
- <<
- \relative c'' {
- f e d c b a g f e d c
- }
- \\
- {
- r4 r r r r r r r r r r
- }
- >>
- <<
- {
- r4 r r r r r r r r r r
- }
- \\
- \relative c'' {
- f e d c b a g f e d c
- }
- >>
-}
-\header
-{
- texidoc = "Grace note runs have their own spacing variables in
- @code{Score.GraceSpacing}. So differing grace note lengths inside a
- run are spaced accordingly. "
+
+\version "2.7.39"
+\header {
+ texidoc = "Grace note spacing. "
}
-\version "2.9.13"
-
-\paper { ragged-right = ##t }
-
-\relative c''
-{
- c4
- \grace { c16 }
- c
- \grace { c16 }
- d
- \grace { c16[ d e f] }
- c
- \grace { c8[ c16 d c8] }
- c
- \override Score.GraceSpacing #'spacing-increment = #2.0
-
- \grace { c4 c16 d16 }
- c
-}
+\layout { ragged-right = ##t}
+
+
+\context Voice \relative c'' { \grace { c16[ d] } c4 }
+
+
+
+
+++ /dev/null
-
-\header
-
-{
-
- texidoc = "With @code{strict-grace-spacing}, grace notes don't influence
-spacing."
-
-}
-
-\version "2.9.12"
-\paper {
- ragged-right = ##t
-}
-
-<<
- \override Score.SpacingSpanner #'strict-grace-spacing = ##t
- \new Staff {
- c'4
- \afterGrace
- c'4
- { c'16[ c'16 c'16 c'16] }
- c'4
- }
- \new Staff {
- c'16[ c'16 c'16 c'16]
- c'16[ c'16 c'16 c'16]
- c'4
- }
->>
+++ /dev/null
-\header {
-
- texidoc = "In the absence of NoteSpacings, wide objects still get
-extra space. In this case, the slash before the barline gets a little
-more space. "
-
-}
-\layout { ragged-right = ##t }
-\version "2.9.21"
-{
- \time 2/4
- \repeat "percent" 3 { c'4 }
-}
+++ /dev/null
-\header {
-
- texidoc = "New sections for spacing can be started with
-@code{\newSpacingSection}. In this example, a section is started at
-the 4/16, and a 16th in the second section takes as much space as a
-8th in first section."
-
-}
-
-\paper
-{
- ragged-right = ##t
- }
-\version "2.9.8"
-\relative {
- \time 2/4
- c4 c8 c
- c8 c c4 c16[ c c8] c4
-
- \newSpacingSection
- \time 4/16
- c8[ c16 c]
- c16[ c c8]
-}
-
-
+++ /dev/null
-\header{
- texidoc = "Combinations of rotation and color do work."
-}
-
-\version "2.9.15"
-\relative c'{
- \override Hairpin #'rotation = #'(20 -1 0)
- \override Hairpin #'color = #(x11-color 'LimeGreen)
- g4\< b d f'\!
-}
-\version "2.9.13"
+\version "2.7.39"
\header {
texidoc = "The @code{\\tag} command marks music expressions with a
\simultaneous {
\new Staff {
- \set Staff.instrumentName = #"both"
+ \set Staff.instrument = #"both"
\common
}
\new Staff {
- \set Staff.instrumentName = #"part"
+ \set Staff.instrument = #"part"
\keepWithTag #'part \common
}
\new Staff {
- \set Staff.instrumentName = #"score"
+ \set Staff.instrument = #"score"
\keepWithTag #'score \common
}
}
--- /dev/null
+\version "2.7.39"
+\header {
+
+ texidoc = "Tie engraver uses @code{busyGrobs} to keep track of
+note heads. By throwing many mixed tuplets on the queue,
+one may have collisions between ties and beams.
+"
+
+}
+
+\layout {
+ ragged-right = ##t
+}
+
+
+\context Staff \relative c''
+<<
+ { \times 2/3 { c'8~ c8~ c8~ c8~ c8~ c8 } }
+ \\
+ { \voiceTwo \times 2/5 { a,4 ~a4 ~a4~ a4~ a4 }}
+ \\
+ { \voiceThree { b,8 ~ b8 ~ b8 ~ b8 }}
+>>
+
+
+
+
+++ /dev/null
-\header
-{
- texidoc = "Individual chord notes can also be tied"
-}
-\version "2.9.15"
-
-\paper {
- ragged-right = ##t
-}
-
-\relative {
- <c~ e g> <c e g~> <c e g>
-}
-
-
+++ /dev/null
-\header {
-
- texidoc = "For whole notes, the inside ties do not cross the center
- of the note head, horizontally. "
-
-
- }
-\version "2.9.10"
-
-\paper { ragged-right = ##t }
-\relative
-{
- <f d a>1~
- <f d a>1~
- <f d a>1~
-}
-\version "2.9.11"
+\version "2.7.39"
\header {
texidoc = "In combination with a beam, the bracket of the tuplet
}
-\version "2.9.11"
+\version "2.7.39"
\paper {
ragged-right = ##t
\relative c'' {
- \override TupletNumber #'text = #tuplet-number::calc-fraction-text
+ \set tupletNumberFormatFunction = #fraction-tuplet-formatter
\override TupletBracket #'edge-text = #(cons
(markup #:fontsize 6
+++ /dev/null
-\header {
-
-
- texidoc = "tuplet can be made to run to prefatory matter or
-the next note, by setting @code{tupletFullLengthNote}."
-
- }
-
-\version "2.9.12"
-
-\new RhythmicStaff {
- \set tupletFullLength = ##t
- \time 4/4
- \times 4/5 {
- c'4 c'1
- }
- \set tupletFullLengthNote = ##t
- \time 2/4
- \times 2/3 {
- c4 c c
- }
- \time 3/4
- c'4 c'4 c'4
-}
}
-\version "2.9.11"
+\version "2.7.39"
\layout {
indent = 0.0\mm
\relative c'' {
- \override TupletNumber #'text = #tuplet-number::calc-fraction-text
+ \set tupletNumberFormatFunction = #fraction-tuplet-formatter
\times 17/12 { c8 c4 c8 c8}
}
-\version "2.9.11"
+\version "2.7.39"
\header {
texidoc=" Tuplets may be nested."
}
\relative c'' {
- \override TupletNumber #'text = #tuplet-number::calc-fraction-text
+ \set tupletNumberFormatFunction = #fraction-tuplet-formatter
\times 4/6 {
\times 2/3 {
a a a
+++ /dev/null
-\header {
- texidoc = "words in mixed font in a single string
- are separated by spaces as in the input string.
- Here a Russian word followed by a roman word."
-
-}
-
-\version "2.9.20"
-
-\markup { "Здравствуйт Hallo" }
-\version "2.9.13"
+\version "2.7.39"
\header {
texidoc ="Broken volta spanners behave correctly at their left edge in all cases."
voiceB = {
\clef bass
- \set Staff.instrumentName = "Bass"
- \set Staff.shortInstrumentName = "B"
+ \set Staff.instrument = "Bass"
+ \set Staff.instr = "B"
\key f \minor
\time 4/4
f1
%% sakura-sakura.ly
-\version "2.9.16"
+\version "2.7.39"
\header {
}
>>
\layout { }
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 120 4)
- }
- }
-
-
+ \midi { \tempo 4=120 }
}
%%% Local Variables:
--- /dev/null
+\version "2.7.39"
+\header {
+ title = "Screech and boink"
+ subtitle = "Random complex notation"
+ composer = "Han-Wen Nienhuys"
+}
+
+\score {
+ \context PianoStaff <<
+ \new Staff = "up" {
+ \time 4/8
+ \key c \minor
+
+
+ << {
+ \revert Stem #'direction
+ \change Staff = down
+ \set subdivideBeams = ##t
+ g16.[
+ \change Staff = up
+ c'''32 \change Staff = down
+ g32 \change Staff = up
+ c'''32 \change Staff = down
+ g16]
+ \change Staff = up
+ \stemUp
+ \set followVoice = ##t
+ c'''32([ b''16 a''16 gis''16 g''32)] } \\
+ { s4 \times 2/3 { d'16[ f' g'] } as'32[ b''32 e'' d''] } \\
+ { s4 \autoBeamOff d''8.. f''32 } \\
+ { s4 es''4 }
+ >>
+ }
+
+ \new Staff = "down" {
+ \clef bass
+ \key c \minor
+ \set subdivideBeams = ##f
+ \override Stem #'french-beaming = ##t
+ \override Beam #'thickness = #0.3
+ \override Stem #'thickness = #4.0
+ g'16[ b16 fis16 g16]
+ << \makeClusters {
+ as16 <as b>
+ <g b>
+ <g cis>
+ } \\
+ {
+ \override Staff.Arpeggio #'arpeggio-direction =#down
+ <cis, e, gis, b, cis>4\arpeggio }
+ >>
+ }
+ >>
+ \midi { \tempo 8 = 60 }
+
+ \layout {
+ ragged-right = ##t
+
+ \context {
+ \Staff
+ \consists Horizontal_bracket_engraver
+ }
+
+ }
+}
advanced. You may also find dirty tricks, or the very very
latest features that have not been documented or fully implemented
yet.
-
-In the web version of this document, you can click on the file name
-or figure for each example to see the corresponding input file.
-
This document is for LilyPond version
" (lilypond-version) ".")
}
-\version "2.9.7"
-\sourcefilename "add-staccato.ly"
+
+\version "2.7.39"
\header {
+
texidoc= "@cindex Add Stacato
Using @code{make-music}, you can add various stuff to notes. In this
example staccato dots are added to the notes."
#(define (make-script x)
(make-music 'ArticulationEvent
'articulation-type x))
-
+
#(define (add-script m x)
(if
(equal? (ly:music-property m 'name) 'EventChord)
#(define (add-staccato m)
(add-script m "staccato"))
-addStacc =
-#(define-music-function (parser location music)
- (ly:music?)
- (music-map add-staccato music))
-
\score {
\relative c'' {
- a b \addStacc { c c }
+ a b \applyMusic #(lambda (x) (music-map add-staccato x)) { c c }
}
\layout{ ragged-right = ##t }
}
+
-\version "2.9.7"
-\sourcefilename "add-text-script.ly"
+\version "2.7.39"
\header {
texidoc= "@cindex make-music Fingering
You can add various stuff to notes using @code{make-music}.
In this example, an extra fingering is attached to a note.
+
+In general, first do a @code{display} of the music you want to
+create, then write a function that will structure the music for you.
"
}
(make-music 'TextScriptEvent
'direction DOWN
'text (make-simple-markup x)))
-
+
#(define (add-text-script m x)
(if (equal? (ly:music-property m 'name) 'EventChord)
(set! (ly:music-property m 'elements)
(add-text-script e x))))
m)
-addScript =
-#(define-music-function (parser location script music )
- ( string? ly:music? )
- (add-text-script music script))
-
\score {
- {
- \addScript "6" { c'4-3 }
- }
+ \applyMusic #(lambda (x) (add-text-script x "6") (display-music x) x ) { c'4-3 }
+ \layout{ ragged-right = ##t }
}
+
--- /dev/null
+
+\version "2.7.39"
+
+\header {
+
+ texidoc = "There a many types of bar lines available."
+
+}
+
+\layout { ragged-right = ##t }
+
+\relative {
+ \override Score.RehearsalMark #'padding = #3
+
+ c4 \bar "|" \mark \markup { \simple #"|" }
+ c \bar "|:" \mark \markup { \simple #"|:" }
+ c \bar "||" \mark \markup { \simple #"||" }
+ c \bar ":|" \mark \markup { \simple #":|" }
+ c \bar ".|" \mark \markup { \simple #".|" }
+ c \bar ".|." \mark \markup { \simple #".|." }
+ c \bar ":|:" \mark \markup { \simple #":|:" }
+ c \bar "|." \mark \markup { \simple #"|." }
+ c \bar ":" \mark \markup { \simple #":" }
+ c
+}
--- /dev/null
+\header {
+ texidoc = "
+
+Bar numbers can be printed at regular intervals, inside a box or a circle.
+
+" }
+
+\version "2.7.39"
+
+\relative c'{
+ \override Score.BarNumber #'break-visibility = #end-of-line-invisible
+ \set Score.barNumberVisibility = #(every-nth-bar-number-visible 4)
+ \override Score.BarNumber #'font-size = #2
+
+ \override Score.BarNumber #'stencil
+ = #(make-stencil-boxer 0.1 0.25 ly:text-interface::print)
+ \repeat unfold 5 { c1 } \bar "|"
+
+ \override Score.BarNumber #'stencil
+ = #(make-stencil-circler 0.1 0.25 ly:text-interface::print)
+ \repeat unfold 4 { c1 } \bar "|."
+}
+
+
--- /dev/null
+\version "2.7.39"
+\header {
+
+texidoc = " Chord names are generated from a list pitches. The
+functions which construct these names can be customised. Here are shown
+Jazz chords, following Ignatzek (pp. 17-18, 1995) and
+an alternative Jazz chord notation.
+
+Chords following Banter (1987) can also be printed from this file, but
+are turned off for brevity.
+
+"
+
+}
+
+chs = \transpose c' c'
+{
+ <c e g>1
+ <c es g>% m = minor triad
+ <c e gis>
+ <c es ges> \break
+ <c e g bes>
+ <c es g bes>
+ <c e g b> % triangle = maj
+ <c es ges beses>
+ <c es ges b> \break
+ <c e gis bes>
+ <c es g b>
+ <c e gis b>
+ <c es ges bes>\break
+ <c e g a> % 6 = major triad with added sixth
+ <c es g a> % m6 = minor triad with added sixth
+ <c e g bes d'>
+ <c es g bes d'> \break
+ <c es g bes d' f' a' >
+ <c es g bes d' f' >
+ <c es ges bes d' >
+ <c e g bes des' > \break
+ <c e g bes dis'>
+ <c e g bes d' f'>
+ <c e g bes d' fis'>
+ <c e g bes d' f' a'>\break
+ <c e g bes d' fis' as'>
+ <c e gis bes dis'>
+ <c e g bes dis' fis'>
+ <c e g bes d' f' as'>\break
+ <c e g bes des' f' as'>
+ <c e g bes d' fis'>
+ <c e g b d'>
+ <c e g bes d' f' as'>\break
+ <c e g bes des' f' as'>
+ <c e g bes des' f' a'>
+ <c e g b d'>
+ <c e g b d' f' a'>\break
+ <c e g b d' fis'>
+ <c e g bes des' f ' a'>
+ <c f g>
+ <c f g bes>\break
+ <c f g bes d'>
+ <c e g d'> % add9
+ <c es g f'>
+}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% alternate Jazz notation
+
+efullmusicJazzAlt =
+{
+ <c e gis>1-\markup { "+" }
+ <c e g b>-\markup { \normal-size-super
+ % \override #'(font-family . math) "N" }
+ \override #'(font-family . math) "M" }
+ %%c:3.5.7 = \markup { \override #'(font-family . math) "M" }
+ %%c:3.5.7 = \markup { \normal-size-super "maj7" }
+
+ <c es ges>-\markup { \super "o" } % should be $\circ$ ?
+ <c es ges bes>-\markup { \super \combine "o" "/" }
+ <c es ges beses>-\markup { \super "o7" }
+}
+
+efullJazzAlt = #(sequential-music-to-chord-exceptions efullmusicJazzAlt #f)
+
+epartialmusicJazzAlt = {
+ <c d>1-\markup { \normal-size-super "2" }
+ <c es>-\markup { "m" }
+ <c f>-\markup { \normal-size-super "sus4" }
+ <c g>-\markup { \normal-size-super "5" }
+
+ %% TODO, partial exceptions
+ <c es f>-\markup { "m" }-\markup { \normal-size-super "sus4" }
+ <c d es>-\markup { "m" }-\markup { \normal-size-super "sus2" }
+}
+
+epartialJazzAlt = #(sequential-music-to-chord-exceptions epartialmusicJazzAlt #f)
+
+jazzAltProperties = \sequential {
+ \set majorSevenSymbol = #whiteTriangleMarkup
+ \set chordNameSeparator = #(make-simple-markup "/")
+ \set chordNameExceptionsFull = #efullJazzAlt
+ \set chordNameExceptionsPartial = #epartialJazzAlt
+ \set chordNameFunction = #jazz-chord-names
+}
+
+banterProperties = \sequential {
+ \set chordNameFunction = #banter-chord-names
+}
+
+\score{
+ <<
+ \new ChordNames {
+ \set instrument = #"Ignatzek (default)"
+ \set instr = #"Def"
+ \chs
+ }
+
+ \new ChordNames {
+ \jazzAltProperties
+ \set instrument = #"Alternative"
+ \set instr = #"Alt"
+ \chs
+ }
+
+%{
+
+ %% This is the Banter (1987) style. It gives exceedingly
+ %% verbose (wide) names, making the output file take up to 4 pages.
+ %% (FIXME: how big is is now?)
+ %% Turned off by default.
+
+ %% FIXME: use smaller font for Banter (or remove some esoteric
+ %% chords).
+
+ \new ChordNames {
+ \banterProperties
+ \set instrument = #"Banter"
+ \set instr = #"Ban"
+ \chs
+ }
+%}
+
+ \new Staff \transpose c c' { \chs }
+ >>
+ \layout {
+ indent = 3.\cm
+ \context {
+ \ChordNames
+ \consists Instrument_name_engraver
+ }
+ }
+}
+
--- /dev/null
+\version "2.7.39"
+\header {
+ texidoc = "@cindex Chord Names German
+The english naming of chords (default) can be changed to german
+(@code{\germanChords} replaces B and Bes to H and B), semi-german
+(@code{\semiGermanChords} replaces B and Bes to H and Bb), italian
+(@code{\italianChords} uses Do Re Mi Fa Sol La Si), or french
+(@code{\frenchChords} replaces Re to Ré).
+
+" }
+
+scm = \chordmode {
+ e1/d c:m
+ % c/c cis/cis
+ % yeah, we get the idea. -hwn
+
+ % cisis/cisis ces/ces ceses/ceses
+ b/b bis/bis bes/bes
+ % beses/beses
+}
+
+
+\layout {
+ ragged-right = ##t
+ \context {\ChordNames \consists Instrument_name_engraver }
+}
+
+<<
+ \new ChordNames {
+ \set instrument = #"default"
+ \scm
+ }
+ \new ChordNames {
+ \set instrument = #"german"
+ \germanChords \scm }
+ \new ChordNames {
+ \set instrument = #"semi-german"
+ \semiGermanChords \scm }
+ \new ChordNames {
+ \set instrument = #"italian"
+ \italianChords \scm }
+ \new ChordNames {
+ \set instrument = #"french"
+ \frenchChords \scm }
+
+ \context Voice { \scm }
+>>
-\version "2.9.13"
+\version "2.7.39"
% Ugh, we need to override some LaTeX titling stuff
flauti = \relative c' {
- \set Staff.instrumentName = #"2 Flauti"
- \set Staff.shortInstrumentName = #"Fl."
+ \set Staff.instrument = #"2 Flauti"
+ \set Staff.instr = #"Fl."
\time 4/4
c1
\break c
}
oboi = \relative c' {
- \set Staff.instrumentName = #"2 Oboi"
- \set Staff.shortInstrumentName = #"Ob."
+ \set Staff.instrument = #"2 Oboi"
+ \set Staff.instr = #"Ob."
c1 c
}
clarinetti = \relative c' {
- \set Staff.instrumentName = \markup { \column { "Clarinetti" \line { "in B" \raisedFlat } } }
- \set Staff.shortInstrumentName = \markup { \smaller { "Cl(B" \raisedFlat ")" } }
+ \set Staff.instrument = \markup { \column { "Clarinetti" \line { "in B" \raisedFlat } } }
+ \set Staff.instr = \markup { \smaller { "Cl(B" \raisedFlat ")" } }
c1 c
}
fagotti = \relative c' {
- \set Staff.instrumentName = #"2 Fagotti"
- \set Staff.shortInstrumentName = #"Fg."
+ \set Staff.instrument = #"2 Fagotti"
+ \set Staff.instr = #"Fg."
c1 c
}
corni = \relative c' {
- \set Staff.instrumentName = \markup { \column { "Corni" \line { "in E" \raisedFlat } } }
- \set Staff.shortInstrumentName = \markup { \smaller { "Cor(E" \raisedFlat ")" } }
+ \set Staff.instrument = \markup { \column { "Corni" \line { "in E" \raisedFlat } } }
+ \set Staff.instr = \markup { \smaller { "Cor(E" \raisedFlat ")" } }
c1 c
}
trombe = \relative c' {
- \set Staff.instrumentName = \markup \column { "2 Trombe" "(C)" }
- \set Staff.shortInstrumentName = \markup \column { "Tbe." "(C)" }
+ \set Staff.instrument = \markup \column { "2 Trombe" "(C)" }
+ \set Staff.instr = \markup \column { "Tbe." "(C)" }
c1 c
}
timpani = \relative c' {
- \set Staff.instrumentName = \markup \column { "Timpani" "(C-G)" }
- \set Staff.shortInstrumentName = #"Timp."
+ \set Staff.instrument = \markup \column { "Timpani" "(C-G)" }
+ \set Staff.instr = #"Timp."
c1 c
}
violinoI = \relative c' {
- \set Staff.instrumentName = #"Violino I "
- \set Staff.shortInstrumentName = #"Vl. I "
+ \set Staff.instrument = #"Violino I "
+ \set Staff.instr = #"Vl. I "
c1 c
}
violinoII = \relative c' {
- \set Staff.instrumentName = #"Violino II "
- \set Staff.shortInstrumentName = #"Vl. II "
+ \set Staff.instrument = #"Violino II "
+ \set Staff.instr = #"Vl. II "
c1 c
}
viola = \relative c' {
- \set Staff.instrumentName = #"Viola"
- \set Staff.shortInstrumentName = #"Vla."
+ \set Staff.instrument = #"Viola"
+ \set Staff.instr = #"Vla."
c1 c
%c
}
violoncello = \relative c' {
- \set Staff.instrumentName = \markup \column { "Violoncello" "e" "Contrabasso" }
- \set Staff.shortInstrumentName = \markup \column { "Vc." "Cb." }
+ \set Staff.instrument = \markup \column { "Violoncello" "e" "Contrabasso" }
+ \set Staff.instr = \markup \column { "Vc." "Cb." }
c1 c
}
--- /dev/null
+% possible rename to ancient- or gregorian- ?
+\header {
+ texidoc = "@cindex Divisiones
+
+Divisiones are ancient variants of breathing signs.
+Choices are @code{divisioMinima}, @code{divisioMaior},
+@code{divisioMaxima} and @code{finalis}, @code{virgula} and
+@code{caesura}.
+
+" }
+
+\version "2.7.39"
+
+\include "gregorian-init.ly"
+
+\score {
+ <<
+ \context VaticanaVoice {
+ \override Staff.StaffSymbol #'color = #red
+ \override TextScript #'padding = #3
+ g a g
+ s^\markup { "divisio minima" }
+ \divisioMinima
+ g a g
+ s^\markup { "divisio maior" }
+ \divisioMaior
+ g a g
+ s^\markup { "divisio maxima" }
+ \divisioMaxima
+ \break
+ g a g
+ s^\markup { "finalis" }
+ \finalis
+ g a g
+ s^\markup { "virgula" }
+ \virgula
+ g a g
+ s^\markup { "caesura" }
+ \caesura
+ g a g
+ }
+ >>
+}
--- /dev/null
+%% texidoc = "Include file for engraver example."
+\version "2.7.39"
+topVoice = \relative c' {
+ \key d\major
+ es8([ g] a[ fis])
+ b4
+ b16[-. b-. b-. cis-.]
+ d4->
+}
+
+botVoice = \relative c' {
+ \key d\major
+ c8[( f] b[ a)]
+ es4
+ es16[-. es-. es-. fis-.]
+ b4->
+}
+
+hoom = \relative c {
+ \key d \major
+ \clef bass
+ g8-. r
+ r4
+ fis8-.
+ r8
+ r4
+ b'4->
+}
+
+pah = \relative c' {
+ r8 b-.
+ r4
+ r8 g8-.
+ r16 g-. r8
+ \clef treble
+ fis'4->
+}
% weird effects when doing instrument names for
% piano staves
- instrumentName = #'()
- shortInstrumentName = #'()
+ instrument = #'()
+ instr = #'()
\accepts "Voice"
}
-\version "2.9.16"
+\version "2.7.39"
% definitely wil be renamed to something.
%{
--- /dev/null
+
+
+\paper {
+ %% ugh. text on toplevel is a bit broken... .
+
+ oddHeaderMarkup = \markup {}
+ evenHeaderMarkup = \markup {}
+ oddFooterMarkup = \markup {}
+ evenFooterMarkup = \markup {}
+ }
+
+\version "2.7.39"
+
+#(define (doc-char name)
+ (make-line-markup
+ (list
+ (make-pad-to-box-markup
+ '(0 . 30)
+ '(-2 . 2)
+ (make-typewriter-markup (make-small-markup name)))
+ (make-pad-to-box-markup
+ '(-2 . 2)
+ '(-2 . 2)
+ (make-musicglyph-markup name)))))
+
+#(define (min-length lst n)
+ "(min (length lst) n)"
+
+ (if (or (null? lst) (<= n 0))
+ 0
+ (1+ (min-length (cdr lst) (1- n)) )))
+
+#(define (doc-chars names acc)
+ (let*
+ ((n (min-length names 2))
+ (head (take names n))
+ (tail (drop names n))
+ )
+
+ (if (null? head)
+ acc
+ (doc-chars tail
+ (cons (make-line-markup (map doc-char head)) acc)))
+ ))
+
+#(define (group-lines lines)
+ (let*
+ ((n (min-length lines 25))
+ (head (take lines n))
+ (tail (drop lines n))
+ )
+
+ (cons
+ (make-column-markup head)
+ (if (null? tail)
+ '()
+ (group-lines tail)))))
+
+#(let*
+ ((lines (doc-chars
+ (ly:otf-glyph-list (ly:font-load "emmentaler-20"))
+ '()))
+ (pages (group-lines (reverse lines))))
+
+ (for-each
+ (lambda (x)
+ (collect-scores-for-book parser
+ (make-override-markup '(word-space . 8) x)))
+ pages))
+
+
}
-\version "2.9.13"
+\version "2.7.39"
\paper {
line-width = 15\cm
\new StaffGroup \relative
<<
\new Staff {
- \set Staff.instrumentName = \markup { \hcenter-in #10 "blabla" }
+ \set Staff. instrument
+ = \markup { \hcenter-in #10 "blabla" }
c1 c1
}
\new Staff {
- \set Staff.instrumentName = \markup { \hcenter-in #10 "blo" }
+ \set Staff. instrument
+ = \markup { \hcenter-in #10 "blo" }
c1 c1
}
-\version "2.9.13"
+\version "2.7.39"
\header { texidoc = "@cindex Instrument Name Grandstaff
You can have a name for the whole @code{GrandStaff} in addition to
individual @code{Staff}s. " }
\new GrandStaff <<
\new Staff = "treble" {
- \set GrandStaff.instrumentName = "Violini "
- \set Staff.instrumentName = " vn I" { c''4 }}
- \new Staff = "bass" { \set Staff.instrumentName = " vn II" c''4 }>>
+ \set GrandStaff.instrument = "Violini "
+ \set Staff.instrument = " vn I" { c''4 }}
+ \new Staff = "bass" { \set Staff.instrument = " vn II" c''4 }>>
\layout {
-\version "2.9.16"
-\sourcefilename "music-box.ly"
-
+\version "2.7.39"
\include "deutsch.ly"
% possible rename to scheme- something. -gp
% TODO: ask if it needs to have so many empty bars in the middle. -gp
(recurse (cdr elts))
)))))
music
- ))
+ ))
#(define ((trans pitches) music)
(let* ((es (ly:music-property music 'elements))
music))
+
+
+
+\version "2.7.39"
+
pat = \transpose c c' \repeat unfold 2 {
<< { \context Staff = "up" {r8 e16 f g e f g } }
{ \context Staff = "down" <<
endb = {\stemUp \tieUp r16 c,8.~c,4~c,2 r16 h,,8.~h,,4~h,,2 c,1 \bar "|."}
endc = {\stemDown \tieDown c,,2~c,, c,,~c,, c,,1_\fermata }
-
-prelude =
-#(define-music-function (parser location patterns) (ly:music?)
- (transform patterns))
-
-
\score {
\transpose c c' \context PianoStaff <<
\new Staff = "up" { \clef "G" }
\new Staff = "down" { \clef "F" }
- { \prelude {
+ { \applyMusic #transform {
\pat {c e g c' e' }
\pat {c d a d' f' }
}
-
+
%{
%Etc.
%}
}
>>
-
+
\layout {
\context {
\PianoStaff
}
line-width = 18.0 \cm
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 80 4)
- }
- }
-
-
+ \midi {
+ \tempo 4 = 80
+ }
}
--- /dev/null
+
+\header { texidoc = "Ossia fragments can be done with starting and
+stopping staves. " }
+
+\version "2.7.39"
+\paper { ragged-right = ##t }
+
+<<
+ \new Staff \with
+ {
+ \remove "Time_signature_engraver"
+ fontSize = #-2
+ \override StaffSymbol #'staff-space = #(magstep -2)
+ firstClef = ##f
+ }
+ \relative c'' {
+ \stopStaff
+ \skip 2
+
+ \startStaff
+ \clef treble
+ bes8[^"ossia" g bes g]
+ \stopStaff
+
+ s2
+
+ \startStaff
+ f8 d g4
+ }
+ \new Staff \relative
+ {
+ \time 2/4
+ c4 c g' g a a g2
+ }
+
+>>
-\version "2.9.7"
-\sourcefilename "reverse-music.ly"
+\version "2.7.39"
% possible rename to scheme-something.
\header { texidoc="@cindex Scheme Reverse Music
Symmetric, or palindromical music can be produced, first, by printing
"
}
+music = \relative c'' { c4 d4( e4 f4 }
+
#(define (reverse-music music)
(let* ((elements (ly:music-property music 'elements))
(reversed (reverse elements))
music))
-reverseMusic =
-#(define-music-function (parser location m) (ly:music?)
- (reverse-music m)
- )
-
-music = \relative c'' { c4 d4( e4 f4 }
-
\score {
-\context Voice {
+ \context Voice {
\music
- \reverseMusic \music
+ \applyMusic #reverse-music \music
}
\layout { ragged-right = ##t}
}
+
--- /dev/null
+
+% this chart is used in the manual too.
+
+\version "2.7.39"
+\header { texidoc = "@cindex Script Abbreviations
+
+Some articulations may be entered using an abbreviation.
+
+"
+
+}
+
+\score {
+ \context Voice {
+ \override TextScript #'font-family = #'typewriter
+ \override TextScript #'font-shape = #'upright
+ c''4-._"c-." s4
+ c''4--_"c--" s4
+ c''4-+_"c-+" s4
+ c''4-|_"c-|" s4
+ c''4->_"c->" s4
+ c''4-^_"c-^" s4
+ c''4-__"c-_" s4
+ }
+ }
+
--- /dev/null
+\version "2.7.39"
+
+% this chart is used in the manual too.
+
+\header {
+ texidoc ="@cindex Feta scripts
+
+This chart shows all articulations, or scripts, that feta font contains.
+
+"
+}
+
+\score {
+ <<
+ \override Score.LyricText #'font-family = #'typewriter
+ \override Score.LyricText #'font-shape = #'upright
+ \context Staff {
+ \set Score.timing = ##f
+ \set Score.barAlways = ##t
+ \override Score.SeparationItem #'padding = #2.5
+ \override Staff.BarLine #'transparent = ##t
+ c''\accent c''\marcato c''\staccatissimo c''\espressivo
+ c''\staccato c''\tenuto c''\portato
+ c''\upbow c''\downbow c''\flageolet
+ c''\thumb c''^\lheel c''\rheel
+ c''^\ltoe c''\rtoe c''\open
+ c''\stopped c''\turn c''\reverseturn
+ c''\trill c''\prall c''\mordent
+ c''\prallprall c''\prallmordent c''\upprall
+ c''\downprall c''\upmordent c''\downmordent
+ c''\pralldown c''\prallup c''\lineprall
+ c''\signumcongruentiae c''\shortfermata c''\fermata
+ c''\longfermata c''\verylongfermata c''\segno
+ c''\coda c''\varcoda
+ }
+ \context Lyrics \lyricmode {
+ accent__ marcato__ staccatissimo__ espressivo__
+ staccato__ tenuto__ portato__
+ upbow__ downbow__ flageolet__
+ thumb__ lheel__ rheel__
+ ltoe__ rtoe__ open__
+ stopped__ turn__ reverseturn__
+ trill__ prall__ mordent__
+ prallprall__ prallmordent__ upprall__
+ downprall__ upmordent__ downmordent__
+ pralldown__ prallup__ lineprall__
+ signumcongruentiae__ shortfermata__ fermata__
+ longfermata__ verylongfermata__ segno__
+ coda__ varcoda__
+ }
+ >>
+ \layout {
+ line-width = 5.1\in
+ indent = 0.0\mm
+ }
+ }
+
+
-\version "2.9.7"
-\sourcefilename "smart-transpose.ly"
+
+\version "2.7.39"
\header {
texidoc="@cindex Smart Transpose
accidentals should be removed, as well as E-sharp (-> F), bC (-> B),
bF (-> E), B-sharp (-> C).'', as proposed by a request for a new feature.
In this manner, the most natural enharmonic notes are chosen in this example.
+
"
}
%
music = \relative c' { c4 d e f g a b c }
-naturaliseMusic =
-#(define-music-function (parser location m)
- (ly:music?)
- (naturalise m))
-
\score {
\context Staff {
\transpose c ais \music
- \naturaliseMusic \transpose c ais \music
+ \applyMusic #naturalise \transpose c ais \music
\transpose c deses \music
- \naturaliseMusic \transpose c deses \music
+ \applyMusic #naturalise \transpose c deses \music
}
\layout { ragged-right = ##t}
}
+
-\version "2.9.16"
+\version "2.7.39"
\header {
-\version "2.9.16"
+\version "2.7.39"
\header {
used contemporary pieces with many time signature changes. "
}
-\version "2.9.16"
+\version "2.7.39"
\layout {
ragged-right = ##T
}
--- /dev/null
+\version "2.7.39"
+
+\header {
+texidoc = "Applying the standard function @code{unfold-repeats} unfolds
+recursively all repeats for a correct MIDI output."
+}
+
+mel = \context Staff {
+ \repeat tremolo 8 {c'32 e' }
+ \repeat percent 2 { c''8 d'' }
+ \repeat volta 2 {c'4 d' e' f'}
+ \alternative {
+ { g' a' a' g' }
+ {f' e' d' c' }
+ }
+ \bar "|."
+}
+
+\score { {
+ \mel \break
+ \applyMusic #unfold-repeats \mel
+ }
+}
+
+
+
+
}
-\version "2.9.16"
+\version "2.7.39"
ignoreMelisma = \set ignoreMelismata = ##t
ignoreMelismaOff = \unset ignoreMelismata
\lyricsto "singer" \new Lyrics \firstVerse
\lyricsto "singer" \new Lyrics \secondVerse
\new PianoStaff <<
- \set PianoStaff.instrumentName = \markup {
+ \set PianoStaff.instrument = \markup {
\bold
\bigger\bigger\bigger\bigger
\huge
\override VerticalAlignment #'forced-distance = #10
}
}
-
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment 70 4)
+ \midi {
+ \tempo 4 = 70
}
}
-
-
- }
}
CPPPATH = [
'#/lily/include',
'#/flower/include',
+ '#/kpath-guile/include',
outdir],
LEXFLAGS = ['-Cfe', '-p', '-p'],
LIBS = ['flower'],
#include "context.hh"
#include "engraver.hh"
#include "international.hh"
+#include "music.hh"
#include "pitch.hh"
#include "protected-scm.hh"
#include "rhythmic-head.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
#include "tie.hh"
#include "warn.hh"
{
public:
bool done_;
- Stream_event *melodic_;
+ Music *melodic_;
Grob *accidental_;
Context *origin_;
Engraver *origin_engraver_;
int get_bar_number ();
void update_local_key_signature ();
void create_accidental (Accidental_entry *entry, bool, bool);
- Grob *make_standard_accidental (Stream_event *note, Grob *note_head, Engraver *trans);
- Grob *make_suggested_accidental (Stream_event *note, Grob *note_head, Engraver *trans);
+ Grob *make_standard_accidental (Music *note, Grob *note_head, Engraver *trans);
+ Grob *make_suggested_accidental (Music *note, Grob *note_head, Engraver *trans);
protected:
TRANSLATOR_DECLARATIONS (Accidental_engraver);
int
Accidental_engraver::get_bar_number ()
{
- SCM barnum = get_property ("internalBarNumber");
+ SCM barnum = get_property ("currentBarNumber");
SCM smp = get_property ("measurePosition");
int bn = robust_scm2int (barnum, 0);
continue;
accidentals_[i].done_ = true;
- Stream_event *note = accidentals_[i].melodic_;
+ Music *note = accidentals_[i].melodic_;
Context *origin = accidentals_[i].origin_;
Pitch *pitch = unsmob_pitch (note->get_property ("pitch"));
pitch, origin,
cautionaries, barnum);
-
bool cautionary = to_boolean (note->get_property ("cautionary"));
+
if (num_caut > num)
{
num = num_caut;
cautionary = true;
}
- bool forced = to_boolean (note->get_property ("force-accidental"));
- if (num == 0 && forced)
+ if (num == 0 && to_boolean (note->get_property ("force-accidental")))
num = 1;
/* Cannot look for ties: it's not guaranteed that they reach
us before the notes. */
- if (num
- && !note->in_event_class ("trill-span-event"))
+ if (num)
create_accidental (&accidentals_[i], num > 1, cautionary);
-
-
- if (forced || cautionary)
- accidentals_[i].accidental_->set_property ("forced", SCM_BOOL_T);
}
}
}
bool restore_natural,
bool cautionary)
{
- Stream_event *note = entry->melodic_;
+ Music *note = entry->melodic_;
Grob *support = entry->head_;
Pitch *pitch = unsmob_pitch (note->get_property ("pitch"));
}
Grob *
-Accidental_engraver::make_standard_accidental (Stream_event *note,
+Accidental_engraver::make_standard_accidental (Music *note,
Grob *note_head,
Engraver *trans)
{
level, so that we get the property settings for
Accidental from the respective Voice.
*/
- Grob *a = trans->make_item ("Accidental", note_head->self_scm ());
+ Grob *a
+ = make_grob_from_properties (trans,
+ ly_symbol2scm ("Accidental"),
+ note_head->self_scm (),
+ "Accidental");
/*
We add the accidentals to the support of the arpeggio,
}
Grob *
-Accidental_engraver::make_suggested_accidental (Stream_event *note,
+Accidental_engraver::make_suggested_accidental (Music *note,
Grob *note_head,
Engraver *trans)
{
(void) note;
- Grob *a = trans->make_item ("AccidentalSuggestion", note_head->self_scm ());
+ Grob *a
+ = make_grob_from_properties (trans,
+ ly_symbol2scm ("AccidentalSuggestion"),
+ note_head->self_scm (),
+ "AccidentalSuggestion");
Side_position_interface::add_support (a, note_head);
if (Grob *stem = unsmob_grob (a->get_object ("stem")))
{
int barnum = get_bar_number ();
- Stream_event *note = accidentals_[i].melodic_;
+ Music *note = accidentals_[i].melodic_;
Context *origin = accidentals_[i].origin_;
Pitch *pitch = unsmob_pitch (note->get_property ("pitch"));
void
Accidental_engraver::acknowledge_rhythmic_head (Grob_info info)
{
- Stream_event *note = info.event_cause ();
+ Music *note = info.music_cause ();
if (note
- && (note->in_event_class ("note-event")
- || note->in_event_class ("trill-span-event")))
+ && (note->is_mus_type ("note-event")
+ || note->is_mus_type ("trill-span-event")))
{
/*
string harmonics usually don't have accidentals.
"autoAccidentals "
"autoCautionaries "
- "internalBarNumber "
"extraNatural "
"harmonicAccidentals "
"localKeySignature",
*/
-#include "accidental-placement.hh"
-#include "rhythmic-head.hh"
-#include "accidental-interface.hh"
+#include "accidental-placement.hh"
+#include "skyline.hh"
#include "music.hh"
-#include "note-collision.hh"
-#include "note-column.hh"
#include "pitch.hh"
-#include "pointer-group-interface.hh"
-#include "skyline.hh"
-#include "stream-event.hh"
#include "warn.hh"
+#include "note-column.hh"
+#include "pointer-group-interface.hh"
+#include "note-collision.hh"
+#include "accidental-interface.hh"
void
a->set_property ("X-offset", Grob::x_parent_positioning_proc);
SCM cause = a->get_parent (Y_AXIS)->get_property ("cause");
- Stream_event *mcause = unsmob_stream_event (cause);
+ Music *mcause = unsmob_music (cause);
if (!mcause)
{
- programming_error ("note head has no event cause");
+ programming_error ("note head has no music cause");
return;
}
return sign (ape_priority (a) - ape_priority (b));
}
-bool ape_less (Accidental_placement_entry *const &a,
- Accidental_placement_entry *const &b)
-{
- return ape_priority (a) < ape_priority (b);
-}
-
int ape_rcompare (Accidental_placement_entry *const &a,
Accidental_placement_entry *const &b)
{
{
vector<Accidental_placement_entry*> asc = *apes;
- vector_sort (asc, &ape_less);
+ vector_sort (asc, &ape_compare);
apes->clear ();
for (vsize i = note_cols.size (); i--;)
concat (heads, extract_grob_array (note_cols[i], "note-heads"));
- vector_sort (heads, less<Grob*> ());
+ vector_sort (heads, default_compare);
uniq (heads);
common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS);
Accidental_placement_entry *head_ape = new Accidental_placement_entry;
common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS);
vector<Skyline_entry> head_skyline (empty_skyline (LEFT));
-
vector<Box> head_extents;
for (vsize i = heads.size (); i--;)
{
insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT);
}
- vector<Grob *> stems;
- for (vsize i = 0; i < heads.size (); i++)
- {
- if (Grob *s = Rhythmic_head::get_stem (heads[i]))
- stems.push_back (s);
- }
-
- vector_sort (stems, less<Grob*> ());
- uniq (stems);
- for (vsize i = 0; i < stems.size (); i ++)
- {
- int very_large = INT_MAX;
-
- Box b (heads[i]->extent (common[X_AXIS], X_AXIS),
- heads[i]->pure_height (common[Y_AXIS], 0, very_large));
-
- insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT);
- }
-
head_ape->left_skyline_ = head_skyline;
head_ape->offset_ = 0.0;
Grob *me = unsmob_grob (smob);
Grob *tie = unsmob_grob (me->get_object ("tie"));
- if (tie && !tie->original ()
- && !to_boolean (me->get_property ("forced")))
- {
- me->suicide ();
- }
-
+ if (tie && !tie->original ())
+ me->suicide ();
return SCM_UNSPECIFIED;
}
"avoid-slur "
"cautionary "
"cautionary-style "
- "forced "
"style "
"tie "
);
#include "hara-kiri-group-spanner.hh"
#include "grob-array.hh"
#include "international.hh"
-#include "warn.hh"
/*
TODO: for vertical spacing, should also include a rod & spring
vector<Grob*> elems (elem_source); // writable..
- Real where = 0;
+ Real where_f = 0;
Interval v;
v.set_empty ();
for (vsize j = 0; j < elems.size (); j++)
{
- where += stacking_dir * dy;
- translates.push_back (where);
- v.unite (Interval (where, where));
+ where_f += stacking_dir * dy;
+ translates.push_back (where_f);
+ v.unite (Interval (where_f, where_f));
}
/*
align_to_fixed_distance ().
*/
-vector<Real>
-Align_interface::get_extents_aligned_translates (Grob *me,
- vector<Grob*> const &all_grobs,
- Axis a,
- bool pure, int start, int end)
+void
+Align_interface::align_elements_to_extents (Grob *me, Axis a)
{
Spanner *me_spanner = dynamic_cast<Spanner *> (me);
{
line_break_details = me_spanner->get_bound (LEFT)->get_property ("line-break-system-details");
- if (!me->get_system () && !pure)
+ if (!me->get_system ())
me->warning (_ ("vertical alignment called before line-breaking.\n"
"Only do cross-staff spanners with PianoStaff."));
vector<Interval> dims;
vector<Grob*> elems;
+ extract_grob_set (me, "elements", all_grobs);
for (vsize i = 0; i < all_grobs.size (); i++)
{
- Interval y = all_grobs[i]->maybe_pure_extent (all_grobs[i], a, pure, start, end);
+ Interval y = all_grobs[i]->extent (me, a);
if (!y.is_empty ())
{
Grob *e = dynamic_cast<Grob *> (all_grobs[i]);
? scm_cdr (extra_space_handle)
: SCM_EOL,
extra_space);
-
- Real padding = robust_scm2double (me->get_property ("padding"),
- 0.0);
+
vector<Real> translates;
for (vsize j = 0; j < elems.size (); j++)
{
if (j)
dy = min (max (dy, threshold[SMALLER]), threshold[BIGGER]);
-
- where += stacking_dir * (dy + padding + extra_space / elems.size ());
+ where += stacking_dir * (dy + extra_space / elems.size ());
total.unite (dims[j] + where);
translates.push_back (where);
}
- SCM offsets_handle = scm_assq (ly_symbol2scm ("alignment-offsets"),
- line_break_details);
+ SCM offsets_handle = scm_assq (ly_symbol2scm ("alignment-offsets"), line_break_details);
if (scm_is_pair (offsets_handle))
{
vsize i = 0;
- for (SCM s = scm_cdr (offsets_handle);
- scm_is_pair (s) && i < translates.size (); s = scm_cdr (s), i++)
+ for (SCM s = scm_cdr (offsets_handle); scm_is_pair (s) && i < translates.size (); s = scm_cdr (s), i++)
{
if (scm_is_number (scm_car (s)))
translates[i] = scm_to_double (scm_car (s));
if (translates.size ())
{
Real w = translates[0];
-
- if (scm_is_number (align))
- center_offset = total.linear_combination (scm_to_double (align));
-
for (vsize i = 0, j = 0; j < all_grobs.size (); j++)
{
if (i < elems.size () && all_grobs[j] == elems[i])
w = translates[i++];
- all_translates.push_back (w - center_offset);
+ all_translates.push_back (w);
}
- }
- return all_translates;
-}
-void
-Align_interface::align_elements_to_extents (Grob *me, Axis a)
-{
- extract_grob_set (me, "elements", all_grobs);
+ /*
+ FIXME: uncommenting freaks out the Y-alignment of
+ line-of-score.
+ */
+ if (scm_is_number (align))
+ center_offset = total.linear_combination (scm_to_double (align));
- vector<Real> translates = get_extents_aligned_translates (me, all_grobs, a, false, 0, 0);
- if (translates.size ())
for (vsize j = 0; j < all_grobs.size (); j++)
- all_grobs[j]->translate_axis (translates[j], a);
-}
-
-Real
-Align_interface::get_pure_child_y_translation (Grob *me, Grob *ch, int start, int end)
-{
- extract_grob_set (me, "elements", all_grobs);
- SCM dy_scm = me->get_property ("forced-distance");
-
- if (scm_is_number (dy_scm))
- {
- Real dy = scm_to_double (dy_scm) * robust_scm2dir (me->get_property ("stacking-dir"), DOWN);
- Real pos = 0;
- for (vsize i = 0; i < all_grobs.size (); i++)
- {
- if (all_grobs[i] == ch)
- return pos;
- if (!Hara_kiri_group_spanner::has_interface (all_grobs[i])
- || !Hara_kiri_group_spanner::request_suicide (all_grobs[i], start, end))
- pos += dy;
- }
- }
- else
- {
- vector<Real> translates = get_extents_aligned_translates (me, all_grobs, Y_AXIS, true, start, end);
-
- if (translates.size ())
- {
- for (vsize i = 0; i < all_grobs.size (); i++)
- if (all_grobs[i] == ch)
- return translates[i];
- }
- else
- return 0;
+ all_grobs[j]->translate_axis (all_translates[j] - center_offset, a);
}
-
- programming_error (_ ("tried to get a translation for something that isn't my child"));
- return 0;
}
-
Axis
Align_interface::axis (Grob *me)
{
SCM sym = axis_offset_symbol (a);
SCM proc = axis_parent_positioning (a);
- element->set_property (sym, proc);
+ element->internal_set_property (sym, proc);
Axis_group_interface::add_element (me, element);
}
/*
properties
*/
- "align-dir "
- "axes "
- "elements "
"forced-distance "
- "padding "
- "positioning-done "
"stacking-dir "
+ "align-dir "
"threshold "
- );
+ "positioning-done "
+ "elements axes");
struct Foobar
{
#include "open-type-font.hh"
#include "pango-font.hh"
#include "scm-hash.hh"
+#include "tfm.hh"
#include "warn.hh"
static char const *default_font_str0_ = "cmr10";
All_font_metrics::All_font_metrics (string path)
{
+ tfm_dict_ = new Scheme_hash_table;
otf_dict_ = new Scheme_hash_table;
#if HAVE_PANGO_FT2
All_font_metrics::~All_font_metrics ()
{
+ tfm_dict_->unprotect ();
otf_dict_->unprotect ();
#if HAVE_PANGO_FT2
return dynamic_cast<Open_type_font *> (unsmob_metrics (val));
}
+Tex_font_metric *
+All_font_metrics::find_tfm (string name)
+{
+ SCM sname = ly_symbol2scm (name.c_str ());
+ SCM name_string = scm_makfrom0str (name.c_str ());
+ SCM val;
+ if (!tfm_dict_->try_retrieve (sname, &val))
+ {
+ string file_name;
+
+ if (file_name.empty ())
+ {
+ /* FIXME: should add "cork-" prefix to lm* fonts. How to do
+ that, cleanly? */
+ string p = kpathsea_find_file (name, "tfm");
+ if (p.length ())
+ file_name = p;
+ }
+
+ if (file_name.empty ())
+ file_name = search_path_.find (name + ".tfm");
+ if (file_name.empty ())
+ return 0;
+
+ if (be_verbose_global)
+ progress_indication ("[" + file_name);
+
+ val = Tex_font_metric::make_tfm (file_name);
+
+ if (be_verbose_global)
+ progress_indication ("]");
+
+ unsmob_metrics (val)->file_name_ = file_name;
+ unsmob_metrics (val)->description_ = scm_cons (name_string,
+ scm_from_double (1.0));
+ tfm_dict_->set (sname, val);
+ unsmob_metrics (val)->unprotect ();
+ }
+
+ return dynamic_cast<Tex_font_metric *> (unsmob_metrics (val));
+}
+
Font_metric *
All_font_metrics::find_font (string name)
{
Font_metric *f = find_otf (name);
+ if (!f)
+ {
+ f = find_tfm (name);
+ }
if (!f)
{
string def_name = default_font_str0_;
+ if (!f)
+ f = find_tfm (def_name);
+
if (!f)
{
error (_f ("can't find default font: `%s'", def_name.c_str ()));
#include "protected-scm.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "translator.icc"
void
Ambitus_engraver::acknowledge_note_head (Grob_info info)
{
- Stream_event *nr = info.event_cause ();
- if (nr && nr->in_event_class ("note-event"))
+ Music *nr = info.music_cause ();
+ if (nr && nr->is_mus_type ("note-event"))
{
Pitch pitch = *unsmob_pitch (nr->get_property ("pitch"));
pitch_interval_.add_point (pitch);
ADD_ACKNOWLEDGER (Ambitus_engraver, note_head);
ADD_TRANSLATOR (Ambitus_engraver,
/* doc */ "",
- /* create */
- "Ambitus "
- "AmbitusLine "
- "AmbitusNoteHead "
- "AmbitusAccidental",
-
+ /* create */ "Ambitus AmbitusLine AmbitusNoteHead AmbitusAccidental",
/* accept */ "",
/* read */ "",
/* write */ "");
#include "music.hh"
#include "simple-music-iterator.hh"
+/**
+ Iterate a property.
+*/
class Apply_context_iterator : public Simple_music_iterator
{
public:
#include "stem.hh"
#include "rhythmic-head.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
#include "note-column.hh"
#include "translator.icc"
protected:
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (arpeggio);
+ virtual bool try_music (Music *);
private:
Item *arpeggio_;
- Stream_event *arpeggio_event_;
+ Music *arpeggio_event_;
};
Arpeggio_engraver::Arpeggio_engraver ()
arpeggio_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Arpeggio_engraver, arpeggio);
-void Arpeggio_engraver::listen_arpeggio (Stream_event *ev)
+bool
+Arpeggio_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (arpeggio_event_, ev);
+ if (!arpeggio_event_)
+ arpeggio_event_ = m;
+ return true;
}
void
Arpeggio_engraver::process_music ()
{
if (arpeggio_event_)
- {
- arpeggio_ = make_item ("Arpeggio", arpeggio_event_->self_scm ());
- }
+ arpeggio_ = make_item ("Arpeggio", arpeggio_event_->self_scm ());
}
void
arpeggio_event_ = 0;
}
-ADD_ACKNOWLEDGER (Arpeggio_engraver, stem);
-ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column);
+ADD_ACKNOWLEDGER (Arpeggio_engraver, stem)
+ ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head)
+ ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column)
-ADD_TRANSLATOR (Arpeggio_engraver,
- /* doc */ "Generate an Arpeggio symbol",
- /* create */ "Arpeggio",
- /* accept */ "arpeggio-event",
- /* read */ "",
- /* write */ "");
+ ADD_TRANSLATOR (Arpeggio_engraver,
+ /* doc */ "Generate an Arpeggio symbol",
+ /* create */ "Arpeggio",
+ /* accept */ "arpeggio-event",
+ /* read */ "",
+ /* write */ "");
#include "translator-group.hh"
#include "context.hh"
-Audio_element_info::Audio_element_info (Audio_element *s, Stream_event *r)
+Audio_element_info::Audio_element_info (Audio_element *s, Music *r)
{
elem_ = s;
origin_trans_ = 0;
audio_column_ = 0;
}
-Audio_note::Audio_note (Pitch p, Moment m, bool tie_event, int transposing_i)
+Audio_note::Audio_note (Pitch p, Moment m, int transposing_i)
{
pitch_ = p;
length_mom_ = m;
tied_ = 0;
transposing_ = transposing_i;
- tie_event_ = tie_event;
}
void
}
void
-Audio_staff::output (Midi_stream &midi_stream, int channel)
+Audio_staff::output (Midi_stream &midi_stream, int track)
{
Midi_track midi_track;
- midi_track.number_ = channel;
+ midi_track.number_ = track;
+ midi_track.channel_ = channel_;
- for (Midi_walker i (this, &midi_track, channel); i.ok (); i++)
+ for (Midi_walker i (this, &midi_track); i.ok (); i++)
i.process ();
-
midi_stream << midi_track;
}
(c) 1999--2006 Jan Nieuwenhuizen <janneke@gnu.org>
*/
-#include "bar-line.hh"
+#include "engraver.hh"
#include "beaming-pattern.hh"
#include "beam.hh"
-#include "context.hh"
-#include "duration.hh"
-#include "engraver.hh"
-#include "item.hh"
-#include "rest.hh"
-#include "spanner.hh"
-#include "stream-event.hh"
#include "stem.hh"
#include "warn.hh"
+#include "bar-line.hh"
+#include "rest.hh"
+#include "item.hh"
+#include "spanner.hh"
+#include "context.hh"
+#include "duration.hh"
#include "translator.icc"
void stop_translation_timestep ();
void start_translation_timestep ();
void process_music ();
+ virtual bool try_music (Music *);
virtual void finalize ();
virtual void derived_mark () const;
DECLARE_ACKNOWLEDGER (beam);
DECLARE_ACKNOWLEDGER (bar_line);
DECLARE_ACKNOWLEDGER (stem);
- DECLARE_TRANSLATOR_LISTENER (beam_forbid);
void process_acknowledged ();
bool is_same_grace_state (Grob *e);
void typeset_beam ();
- Stream_event *forbid_;
+ Music *forbid_;
/*
shortest_mom is the shortest note in the beam.
*/
beam_settings_ = SCM_EOL;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Auto_beam_engraver, beam_forbid);
-void
-Auto_beam_engraver::listen_beam_forbid (Stream_event *ev)
+bool
+Auto_beam_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (forbid_, ev);
+ if (m->is_mus_type ("beam-forbid-event"))
+ {
+ forbid_ = m;
+ return true;
+ }
+
+ return false;
}
bool
{
check_bar_property ();
Item *stem = dynamic_cast<Item *> (info.grob ());
- Stream_event *ev = info.ultimate_event_cause ();
- if (!ev->in_event_class ("rhythmic-event"))
+ Music *m = info.ultimate_music_cause ();
+ if (!m->is_mus_type ("rhythmic-event"))
{
programming_error ("stem must have rhythmic structure");
return;
return;
}
- int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log ();
+ int durlog = unsmob_duration (m->get_property ("duration"))->duration_log ();
if (durlog <= 2)
{
if (bool (beam_start_location_.grace_part_) != bool (now.grace_part_))
return;
- Moment dur = unsmob_duration (ev->get_property ("duration"))->get_length ();
+ Moment dur = unsmob_duration (m->get_property ("duration"))->get_length ();
consider_end (dur);
consider_begin (dur);
durlog - 2);
stems_->push_back (stem);
last_add_mom_ = now;
- extend_mom_ = max (extend_mom_, now) + get_event_length (ev);
+ extend_mom_ = max (extend_mom_, now) + m->get_length ();
}
void
{
Context *dest
= it->get_outlet ()->find_create_context (to_type_sym, to_id, SCM_EOL);
-
- send_stream_event (last, "ChangeParent", get_music ()->origin (),
- ly_symbol2scm ("context"), dest->self_scm ());
+ current->remove_context (last);
+ dest->add_context (last);
}
else
{
Moment now = get_outlet ()->now_mom ();
Moment *splitm = 0;
- if (start_moment_.main_part_.is_infinity () && start_moment_ < 0)
- start_moment_ = now;
for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_))
{
/* create */ "VerticalAxisGroup",
/* accept */ "",
/* read */
- "currentCommandColumn ",
+ "verticalExtent "
+ "minimumVerticalExtent "
+ "extraVerticalExtent ",
/* write */ "");
#include "axis-group-interface.hh"
-#include "align-interface.hh"
#include "pointer-group-interface.hh"
#include "grob.hh"
-#include "grob-array.hh"
#include "hara-kiri-group-spanner.hh"
-#include "international.hh"
-#include "item.hh"
-#include "paper-column.hh"
-#include "paper-score.hh"
-#include "system.hh"
#include "warn.hh"
void
if (!scm_is_pair (axes))
programming_error ("axes should be nonempty");
- for (SCM ax = axes; scm_is_pair (ax); ax = scm_cdr (ax))
+ for (SCM ax = axes; ax != SCM_EOL; ax = scm_cdr (ax))
{
Axis a = (Axis) scm_to_int (scm_car (ax));
if (!e->get_parent (a))
e->set_parent (me, a);
- e->set_object ((a == X_AXIS)
- ? ly_symbol2scm ("axis-group-parent-X")
- : ly_symbol2scm ("axis-group-parent-Y"),
- me->self_scm ());
+ e->internal_set_object ((a == X_AXIS)
+ ? ly_symbol2scm ("axis-group-parent-X")
+ : ly_symbol2scm ("axis-group-parent-Y"),
+ me->self_scm ());
}
/* must be ordered, because Align_interface also uses
return r;
}
-Interval
-Axis_group_interface::cached_pure_height (Grob *me,
- vector<Grob*> const &elts,
- Grob *common,
- int start, int end)
-{
- Paper_score *ps = get_root_system (me)->paper_score ();
- vector<vsize> breaks = ps->get_break_indices ();
- vector<Grob*> cols = ps->get_columns ();
- vsize start_index = VPOS;
- vsize end_index = VPOS;
-
- for (vsize i = 0; i < breaks.size (); i++)
- {
- int r = Paper_column::get_rank (cols[breaks[i]]);
- if (start == r)
- start_index = i;
- if (end == r)
- end_index = i;
- }
-
- if (start_index == VPOS || end_index == VPOS)
- {
- programming_error (_ ("tried to calculate pure-height at a non-breakpoint"));
- return Interval (0, 0);
- }
-
- SCM extents = me->get_property ("cached-pure-extents");
- if (!scm_is_vector (extents))
- {
- extents = scm_c_make_vector (breaks.size () - 1, SCM_EOL);
- for (vsize i = 0; i < breaks.size () - 1; i++)
- {
- int st = Paper_column::get_rank (cols[breaks[i]]);
- int ed = Paper_column::get_rank (cols[breaks[i+1]]);
- Interval iv = relative_pure_height (me, elts, common, st, ed, false);
- scm_vector_set_x (extents, scm_from_int (i), ly_interval2scm (iv));
- }
- me->set_property ("cached-pure-extents", extents);
- }
-
- Interval ext (0, 0);
- for (vsize i = start_index; i < end_index; i++)
- ext.unite (ly_scm2interval (scm_c_vector_ref (extents, i)));
- return ext;
-}
-
-Interval
-Axis_group_interface::relative_pure_height (Grob *me,
- vector<Grob*> const &elts,
- Grob *common,
- int start, int end,
- bool use_cache)
-{
- /* It saves a _lot_ of time if we assume a VerticalAxisGroup is additive
- (ie. height (i, k) = height (i, j) + height (j, k) for all i <= j <= k).
- Unfortunately, it isn't always true, particularly if there is a
- VerticalAlignment somewhere in the descendants.
-
- Apart from PianoStaff, which has a fixed VerticalAlignment so it doesn't
- count, the only VerticalAlignment comes from Score. This makes it
- reasonably safe to assume that if our parent is a VerticalAlignment,
- we can assume additivity and cache things nicely. */
- Grob *p = me->get_parent (Y_AXIS);
- if (use_cache && p && Align_interface::has_interface (p))
- return Axis_group_interface::cached_pure_height (me, elts, common, start, end);
-
- Interval r;
-
- for (vsize i = 0; i < elts.size (); i++)
- {
- Interval_t<int> rank_span = elts[i]->spanned_rank_iv ();
- Item *it = dynamic_cast<Item*> (elts[i]);
- if (rank_span[LEFT] <= end && rank_span[RIGHT] >= start && (!it || it->pure_is_visible (start, end)))
- {
- Interval dims = elts[i]->pure_height (common, start, end);
- if (!dims.is_empty ())
- r.unite (dims);
- }
- }
- return r;
-}
-
MAKE_SCHEME_CALLBACK (Axis_group_interface, width, 1);
SCM
Axis_group_interface::width (SCM smob)
Grob *me = unsmob_grob (smob);
return generic_group_extent (me, Y_AXIS);
}
-
-MAKE_SCHEME_CALLBACK (Axis_group_interface, pure_height, 3);
-SCM
-Axis_group_interface::pure_height (SCM smob, SCM start_scm, SCM end_scm)
-{
- int start = robust_scm2int (start_scm, 0);
- int end = robust_scm2int (end_scm, INT_MAX);
- Grob *me = unsmob_grob (smob);
-
- return pure_group_height (me, start, end);
-}
SCM
Axis_group_interface::generic_group_extent (Grob *me, Axis a)
return ly_interval2scm (r - my_coord);
}
-SCM
-Axis_group_interface::pure_group_height (Grob *me, int start, int end)
-{
- Grob *common = unsmob_grob (me->get_object ("common-refpoint-of-elements"));
-
- if (!common)
- {
- extract_grob_set (me, "elements", elts);
-
- vector<Grob*> relevant_elts;
- SCM is_relevant = ly_lily_module_constant ("pure-relevant");
-
- for (vsize i = 0; i < elts.size (); i++)
- {
- if (to_boolean (scm_apply_1 (is_relevant, elts[i]->self_scm (), SCM_EOL)))
- relevant_elts.push_back (elts[i]);
-
- Item *it = dynamic_cast<Item*> (elts[i]);
- Direction d = LEFT;
- if (it)
- do
- {
- Item *piece = it->find_prebroken_piece (d);
- if (piece && to_boolean (scm_apply_1 (is_relevant, piece->self_scm (), SCM_EOL)))
- relevant_elts.push_back (piece);
- }
- while (flip (&d) != LEFT);
- }
-
- common = common_refpoint_of_array (relevant_elts, me, Y_AXIS);
- me->set_object ("common-refpoint-of-elements", common->self_scm ());
-
- SCM ga_scm = Grob_array::make_array ();
- Grob_array *ga = unsmob_grob_array (ga_scm);
- ga->set_array (relevant_elts);
- me->set_object ("pure-relevant-elements", ga_scm);
- }
-
- extract_grob_set (me, "pure-relevant-elements", elts);
- Real my_coord = me->relative_coordinate (common, Y_AXIS);
- Interval r (relative_pure_height (me, elts, common, start, end, true));
-
- return ly_interval2scm (r - my_coord);
-}
-
void
Axis_group_interface::get_children (Grob *me, vector<Grob*> *found)
{
/* properties */
"axes "
- "elements "
- "common-refpoint-of-elements "
- "pure-relevant-elements "
- "cached-pure-extents "
- );
+ "elements ");
#include "bar-line.hh"
#include "context.hh"
+#include "score-context.hh"
#include "score-engraver.hh"
#include "warn.hh"
#include "item.hh"
#include "output-def.hh"
#include "paper-column.hh"
#include "staff-symbol-referencer.hh"
-#include "line-interface.hh"
MAKE_SCHEME_CALLBACK (Bar_line, print, 1);
SCM
for (int i = 0; i < c - 1; i++)
{
- Real y = (- (c - 1.0) / 2 + 0.5 + i) * staff_space;
+ Real y = (- (c - 1.0) / 2 + 0.5 + i * staff_space);
Stencil d (dot);
d.translate_axis (y, Y_AXIS);
m.add_stencil (d);
}
}
- else if (str == "dashed")
- {
- m = dashed_bar_line (me, h, hair);
- }
else if (str == ".")
{
m = dot;
}
-Stencil
-Bar_line::dashed_bar_line (Grob *me, Real h, Real thick)
-{
- Real dash_size
- = 1.0 - robust_scm2double (me->get_property ("gap"), 0.3);
- /*
- this is a tad complex for what we want to achieve, but with a
- simple line, the round blotting interferes with staff line
- connections.
- */
- Real ss = Staff_symbol_referencer::staff_space (me);
- int count = Staff_symbol_referencer::line_count (me);
- Real line_thick = Staff_symbol_referencer::line_thickness (me);
-
- if (fabs (line_thick + (count -1) * ss - h) < 0.1) // ugh.
- {
- Real blot =
- me->layout ()->get_dimension (ly_symbol2scm ("blot-diameter"));
-
- Real half_space = ss/2;
- Stencil bar;
-
- for (int i = (count-1); i >= -(count-1); i -= 2)
- {
- Real top_y = min ((i + dash_size) * half_space,
- (count-1) * half_space + line_thick / 2);
- Real bot_y = max ((i - dash_size) * half_space,
- -(count-1) * half_space - line_thick/2);
-
- bar.add_stencil (Lookup::round_filled_box (Box (Interval (0,thick),
- Interval (bot_y, top_y)),
- blot));
- }
- return bar;
- }
- else
- {
- /*
- We have to scale the dashing so it starts and ends with half a
- dash exactly.
- */
- int dashes = int (rint (h / ss));
- Real total_dash_size = h / dashes;
- Real factor = (dash_size - thick) / ss;
-
- SCM at = scm_list_n (ly_symbol2scm ("dashed-line"),
- scm_from_double (thick),
- scm_from_double (factor * total_dash_size),
- scm_from_double ((1-factor) * total_dash_size),
- scm_from_double (0),
- scm_from_double (h),
- scm_from_double (factor * total_dash_size * 0.5),
- SCM_UNDEFINED);
-
- Box box;
- box.add_point (Offset (0, 0));
- box.add_point (Offset (0, h));
-
- Stencil s (box, at);
- s.translate (Offset (thick/2, -h/2));
- return s;
- }
- return Stencil();
-}
-
-
ADD_INTERFACE (Bar_line,
"bar-line-interface",
"\n"
"These produce, respectively, a right repeat, a left repeat, a double\n"
"repeat, a double bar, a start bar, an end bar, and a thick double bar.\n"
- "In addition, there is an option @code{||:} which is equivalent to\n"
- "@code{|:} except at line breaks, where it produces a double bar (@code{||})\n"
- "at the end of the line and a repeat sign (@code{|:}) at the beginning\n"
- "of the new line."
"If @var{bartype} is set to @code{empty} then nothing is printed,\n"
- "but a line break is allowed at that spot.\n"
- "\n\n"
- "@code{gap} is used for the gaps in dashed barlines."
+ "but a line break is allowed at that spot.\n",
- ,
-
- /* properties */
- "gap "
+ /* properties */
"kern "
"thin-kern "
"hair-thickness "
"glyph-name "
"bar-size "
);
-
-
#include "international.hh"
#include "item.hh"
#include "rest.hh"
+#include "score-context.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "stem.hh"
#include "warn.hh"
DECLARE_ACKNOWLEDGER (stem);
DECLARE_ACKNOWLEDGER (rest);
protected:
- Stream_event *start_ev_;
+ Music *start_ev_;
Spanner *finished_beam_;
Spanner *beam_;
- Stream_event *prev_start_ev_;
+ Music *prev_start_ev_;
- Stream_event *now_stop_ev_;
+ Music *now_stop_ev_;
Beaming_pattern *beam_info_;
Beaming_pattern *finished_beam_info_;
void start_translation_timestep ();
virtual void finalize ();
+ virtual bool try_music (Music *);
void process_music ();
virtual bool valid_start_point ();
virtual bool valid_end_point ();
- DECLARE_TRANSLATOR_LISTENER (beam);
public:
TRANSLATOR_DECLARATIONS (Beam_engraver);
};
prev_start_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Beam_engraver, beam);
-void
-Beam_engraver::listen_beam (Stream_event *ev)
+bool
+Beam_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
-
- if (d == START && valid_start_point ())
- ASSIGN_EVENT_ONCE (start_ev_, ev);
- else if (d == STOP && valid_end_point ())
- ASSIGN_EVENT_ONCE (now_stop_ev_, ev);
+ if (m->is_mus_type ("beam-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ if (d == START && !valid_start_point ())
+ return false;
+ if (d == STOP && !valid_end_point ())
+ return false;
+
+ if (d == START)
+ start_ev_ = m;
+ else if (d == STOP)
+ now_stop_ev_ = m;
+ return true;
+ }
+ return false;
}
void
- Stream_event *ev = info.ultimate_event_cause ();
- if (!ev->in_event_class ("rhythmic-event"))
+ Music *m = info.ultimate_music_cause ();
+ if (!m->is_mus_type ("rhythmic-event"))
{
- info.grob ()->warning (_ ("stem must have Rhythmic structure"));
+ string s = _ ("stem must have Rhythmic structure");
+ if (info.music_cause ())
+ info.music_cause ()->origin ()->warning (s);
+ else
+ ::warning (s);
+
return;
}
last_stem_added_at_ = now;
- int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log ();
+ int durlog = unsmob_duration (m->get_property ("duration"))->duration_log ();
if (durlog <= 2)
{
- ev->origin ()->warning (_ ("stem doesn't fit in beam"));
+ m->origin ()->warning (_ ("stem doesn't fit in beam"));
prev_start_ev_->origin ()->warning (_ ("beam was started here"));
/*
don't return, since
public:
TRANSLATOR_DECLARATIONS (Grace_beam_engraver);
- DECLARE_TRANSLATOR_LISTENER (beam);
-
protected:
virtual bool valid_start_point ();
virtual bool valid_end_point ();
return beam_ && valid_start_point ();
}
-/*
- Ugh, C&P code.
- */
-IMPLEMENT_TRANSLATOR_LISTENER (Grace_beam_engraver, beam);
-void
-Grace_beam_engraver::listen_beam (Stream_event *ev)
-{
- Direction d = to_dir (ev->get_property ("span-direction"));
-
- if (d == START && valid_start_point ())
- start_ev_ = ev;
- else if (d == STOP && valid_end_point ())
- now_stop_ev_ = ev;
-}
-
-
ADD_ACKNOWLEDGER (Grace_beam_engraver, stem);
ADD_ACKNOWLEDGER (Grace_beam_engraver, rest);
#include "audio-item.hh"
#include "audio-column.hh"
#include "global-context.hh"
-#include "stream-event.hh"
#include "warn.hh"
+#include "music.hh"
#include "translator.icc"
TRANSLATOR_DECLARATIONS (Beam_performer);
protected:
+ virtual bool try_music (Music *ev);
void start_translation_timestep ();
void process_music ();
void set_melisma (bool);
- DECLARE_TRANSLATOR_LISTENER (beam);
private:
- Stream_event *start_ev_;
- Stream_event *now_stop_ev_;
+ Music *start_ev_;
+ Music *now_stop_ev_;
bool beam_;
};
now_stop_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Beam_performer, beam);
-void
-Beam_performer::listen_beam (Stream_event *ev)
+bool
+Beam_performer::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
+ if (m->is_mus_type ("beam-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
- if (d == START)
- start_ev_ = ev;
- else if (d == STOP)
- now_stop_ev_ = ev;
+ if (d == START)
+ start_ev_ = m;
+ else if (d == STOP)
+ now_stop_ev_ = m;
+ return true;
+ }
+ return false;
}
ADD_TRANSLATOR (Beam_performer, "", "",
i != stem_segments.end (); i++)
{
vector<Beam_stem_segment> segs = (*i).second;
- vector_sort (segs, less<Beam_stem_segment> ());
+ vector_sort (segs, default_compare);
Beam_segment current;
for (vsize i = 0; i < stems.size (); i++)
{
Grob *s = stems[i];
+ if (Stem::is_invisible (s))
+ continue;
bool french = to_boolean (s->get_property ("french-beaming"));
Real stem_y = calc_stem_y (me, s, common,
Make the stems go up to the end of the beam. This doesn't matter
for normal beams, but for tremolo beams it looks silly otherwise.
*/
- if (gap
- && !Stem::is_invisible (s))
+ if (gap)
stem_y += thick * 0.5 * get_grob_direction (s);
- /*
- Do set_stemend for invisible stems too, so tuplet brackets
- have a reference point for sloping
- */
Stem::set_stemend (s, 2 * stem_y / staff_space);
}
rest -> stem -> beam -> interpolate_y_position ()
*/
-MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Beam, rest_collision_callback, 2, 1);
+MAKE_SCHEME_CALLBACK (Beam, rest_collision_callback, 2);
SCM
Beam::rest_collision_callback (SCM smob, SCM prev_offset)
{
beam_count_drul_[RIGHT] = i;
}
-
-void
-Beam_rhythmic_element::de_grace ()
-{
- if (start_moment_.grace_part_)
- {
- start_moment_.main_part_ =
- start_moment_.grace_part_;
- start_moment_.grace_part_ = 0;
- }
-}
-
-int
-count_factor_twos (int x)
-{
- int c = 0;
- while (x && x % 2 == 0)
- {
- x /= 2;
- c ++;
- }
-
- return c;
-}
-
int
Beaming_pattern::best_splitpoint_index (bool *at_boundary) const
{
*at_boundary = false;
- int min_den = INT_MAX;
+ int min_denominator = INT_MAX;
int min_index = -1;
Moment beat_pos;
for (vsize i = 1; i < infos_.size (); i++)
{
- Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_;
-
- /*
- This is a kludge, for the most common case of 16th, 32nds
- etc. What should really happen is that \times x/y should
- locally introduce a voice-specific beat duration. (or
- perhaps: a list of beat durations for nested tuplets.)
-
- */
-
- dt /= infos_[i].beat_length_;
-
- if (dt.den () < min_den)
+ Moment dt = infos_[i].start_moment_ - infos_[i].beat_start_;
+ if (dt.den () < min_denominator)
{
- min_den = dt.den ();
+ min_denominator = dt.den ();
min_index = i;
}
}
return min (thisbeam.beam_count_drul_[-d], next.beam_count_drul_[d]);
}
-void
-Beaming_pattern::de_grace ()
-{
- for (vsize i = 0; i < infos_.size (); i ++)
- {
- infos_[i].de_grace ();
- }
-}
-
void
Beaming_pattern::beamify (Context *context)
{
if (infos_.size () <= 1)
return;
-
- if (infos_[0].start_moment_.grace_part_)
- de_grace ();
bool subdivide_beams = to_boolean (context->get_property ("subdivideBeams"));
Moment beat_length = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4));
- Moment measure_length = robust_scm2moment (context->get_property ("measureLength"), Moment (1, 4));
+ Moment measure_length = robust_scm2moment (context->get_property ("beatLength"), Moment (1, 4));
if (infos_[0].start_moment_ < Moment (0))
for (vsize i = 0; i < infos_.size(); i++)
vsize k = 0;
for (vsize i = 0; i < infos_.size(); i++)
{
- while (j < group_starts.size() - 1
+ while (j < group_starts.size()-1
&& group_starts[j+1] <= infos_[i].start_moment_)
j++;
infos_[i].group_start_ = group_starts[j];
- infos_[i].beat_length_ = beat_length;
- while (k < beat_starts.size() - 1
+
+ while (k < beat_starts.size()-1
&& beat_starts[k+1] <= infos_[i].start_moment_)
k++;
--- /dev/null
+/*
+ binary-source-file.cc -- implement Binary_source_file
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997--2006 Jan Nieuwenhuizen
+*/
+
+#include <climits> // INT_MAX
+using namespace std;
+
+#include "binary-source-file.hh"
+#include "string-convert.hh"
+
+Binary_source_file::Binary_source_file (string &file_name_string)
+ : Source_file (file_name_string)
+{
+}
+
+Binary_source_file::~Binary_source_file ()
+{
+}
+
+string
+Binary_source_file::quote_input (char const *pos_str0) const
+{
+ assert (this);
+ if (!contains (pos_str0))
+ return "";
+
+ char const *begin_str0 = max (pos_str0 - 8, c_str ());
+ char const *end_str0 = min (pos_str0 + 7, c_str () + length ());
+
+ string pre_string (begin_str0, pos_str0 - begin_str0);
+ pre_string = String_convert::bin2hex (pre_string);
+ for (ssize i = 2; i < pre_string.length (); i += 3)
+ pre_string = pre_string.substr (0, i)
+ + " " + pre_string.substr (i, NPOS);
+ string post_string (pos_str0, end_str0 - pos_str0);
+ post_string = String_convert::bin2hex (post_string);
+ for (ssize i = 2; i < post_string.length (); i += 3)
+ post_string = post_string.substr (0, i)
+ + " " + post_string.substr (i, NPOS);
+
+ string str = pre_string
+ + to_string ('\n')
+ + to_string (' ', pre_string.length () + 1)
+ + post_string;
+ return str;
+}
+
+int
+Binary_source_file::get_line (char const *pos_str0) const
+{
+ if (!contains (pos_str0))
+ return 0;
+
+ return pos_str0 - c_str ();
+}
+
+U8
+Binary_source_file::get_U8 ()
+{
+ return *(U8 *)forward_str0 (1);
+}
+
+U16
+Binary_source_file::get_U16 ()
+{
+ U16 b;
+
+ b = get_U8 () << 8;
+ b |= get_U8 ();
+
+ return b;
+}
+
+/*
+ naming is wrong. This is a UNIX-endian-32 (as opposed to xinu or ixun)
+*/
+
+U32
+Binary_source_file::get_U32 ()
+{
+ U32 b;
+
+ b = get_U8 () << 24;
+ b |= get_U8 () << 16;
+ b |= get_U8 () << 8;
+ b |= get_U8 ();
+
+ return b;
+}
+
using namespace std;
#include "lilypond-key.hh"
+#include "global-context.hh"
#include "main.hh"
+#include "music-iterator.hh"
#include "music-output.hh"
#include "music.hh"
#include "output-def.hh"
#include "stencil.hh"
#include "text-interface.hh"
#include "warn.hh"
+
#include "performance.hh"
#include "paper-score.hh"
#include "ly-smobs.icc"
Book::Book ()
+ : Input ()
{
paper_ = 0;
header_ = SCM_EOL;
scores_ = SCM_EOL;
- input_location_ = SCM_EOL;
smobify_self ();
-
- input_location_ = make_input (Input ());
}
-Book::Book (Book const &s)
+Book*
+Book::clone () const
{
- paper_ = 0;
- header_ = SCM_EOL;
- scores_ = SCM_EOL;
- input_location_ = SCM_EOL;
- smobify_self ();
-
- if (s.paper_)
- paper_ = s.paper_->clone ();
-
- input_location_ = make_input (*s.origin ());
- header_ = ly_make_anonymous_module (false);
- if (ly_is_module (s.header_))
- ly_module_copy (header_, s.header_);
-
- SCM *t = &scores_;
- for (SCM p = s.scores_; scm_is_pair (p); p = scm_cdr (p))
- {
- Score *newscore = unsmob_score (scm_car (p))->clone ();
-
- *t = scm_cons (newscore->self_scm (), SCM_EOL);
- t = SCM_CDRLOC(*t);
- newscore->unprotect ();
- }
-}
-
-Input *
-Book::origin () const
-{
- return unsmob_input (input_location_);
+ return new Book (*this);
}
Book::~Book ()
if (book->paper_)
scm_gc_mark (book->paper_->self_scm ());
scm_gc_mark (book->scores_);
- scm_gc_mark (book->input_location_);
-
+
return book->header_;
}
Book::process (Output_def *default_paper,
Output_def *default_layout)
{
- for (SCM s = scores_; scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = scores_; s != SCM_EOL; s = scm_cdr (s))
if (Score *score = unsmob_score (scm_car (s)))
if (score->error_found_)
return 0;
paper_book->header_ = header_;
/* Render in order of parsing. */
- for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = scm_reverse (scores_); s != SCM_EOL; s = scm_cdr (s))
{
if (Score *score = unsmob_score (scm_car (s)))
{
(c) 1996--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
+#include "ly-smobs.icc"
+
#include "box.hh"
+#include "std-vector.hh"
void
Box::translate (Offset o)
interval_a_[i].unite (b[i]);
}
+/**
+ Initialize to empty.
+*/
Box::Box ()
{
}
interval_a_[Y_AXIS].widen (y);
}
-/****************************************************************/
-
-#include "ly-smobs.icc"
-
IMPLEMENT_SIMPLE_SMOBS (Box);
IMPLEMENT_TYPE_P (Box, "ly:box?");
IMPLEMENT_DEFAULT_EQUAL_P (Box);
--- /dev/null
+/*
+ break.cc -- implement Break_algorithm
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1996--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "break-algorithm.hh"
+#include "paper-column.hh"
+#include "output-def.hh"
+#include "system.hh"
+#include "paper-score.hh"
+#include "paper-column.hh"
+#include "cpu-timer.hh"
+#include "simple-spacer.hh"
+
+Break_algorithm::Break_algorithm ()
+{
+ pscore_ = 0;
+ linewidth_ = 0;
+}
+
+void
+Break_algorithm::set_pscore (Paper_score *s)
+{
+ pscore_ = s;
+ linewidth_ = s->layout ()->get_dimension (ly_symbol2scm ("line-width"));
+}
+
+vector<Column_x_positions>
+Break_algorithm::solve ()
+{
+ vector<Column_x_positions> h;
+ return h;
+}
+
+Break_algorithm::~Break_algorithm ()
+{
+}
/*
Make left edge appear to come from same context as clef/bar-line etc.
*/
- left_edge_ = random_source->make_item ("LeftEdge", SCM_EOL);
+ left_edge_ = make_item_from_properties (random_source,
+ ly_symbol2scm ("LeftEdge"),
+ SCM_EOL,
+ "LeftEdge");
add_to_group (left_edge_->get_property ("break-align-symbol"),
left_edge_);
}
int last_idx_found = -1;
vsize i = 0;
- for (SCM s = order; scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = order; scm_is_pair (order); s = scm_cdr (s))
{
if (i < elements.size ()
&& elements[i]->get_property ("break-align-symbol") == scm_car (s))
if (!unsmob_grob_array (newval))
{
newval = Grob_array::make_array ();
- sc->set_object (sym, newval);
+ sc->internal_set_object (sym, newval);
}
Grob_array *new_array = unsmob_grob_array (newval);
if (!unsmob_grob_array (newval))
{
newval = Grob_array::make_array ();
- sc->set_object (sym, newval);
+ sc->internal_set_object (sym, newval);
}
substitute_grob_array (grob_array, unsmob_grob_array (newval));
}
else
{
SCM newval = do_break_substitution (val);
- sc->set_object (sym, newval);
+ sc->internal_set_object (sym, newval);
}
}
}
. Spacing is not yet completely pretty
*/
+#include "staff-symbol-referencer.hh"
#include "breathing-sign.hh"
-#include "engraver.hh"
+#include "engraver-group.hh"
#include "item.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
class Breathing_sign_engraver : public Engraver
{
TRANSLATOR_DECLARATIONS (Breathing_sign_engraver);
protected:
- void process_music ();
+ virtual bool try_music (Music *event);
+ void process_acknowledged ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (breathing);
private:
- Stream_event *breathing_sign_event_;
+ Music *breathing_sign_event_;
Grob *breathing_sign_;
};
breathing_sign_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Breathing_sign_engraver, breathing);
-void
-Breathing_sign_engraver::listen_breathing (Stream_event *ev)
+bool
+Breathing_sign_engraver::try_music (Music *r)
{
- ASSIGN_EVENT_ONCE (breathing_sign_event_, ev);
+ breathing_sign_event_ = r;
+ return true;
}
void
-Breathing_sign_engraver::process_music ()
+Breathing_sign_engraver::process_acknowledged ()
{
- if (breathing_sign_event_)
+ if (breathing_sign_event_ && ! breathing_sign_)
{
breathing_sign_ = make_item ("BreathingSign", breathing_sign_event_->self_scm ());
+ breathing_sign_event_ = 0;
}
}
breathing_sign_event_ = 0;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Breathing_sign_engraver,
/* doc */ "",
/* create */ "BreathingSign",
set_grob_direction (me, d);
}
- Real inter = Staff_symbol_referencer::staff_space (me) / 2;
+ Real inter_f = Staff_symbol_referencer::staff_space (me) / 2;
int sz = Staff_symbol_referencer::line_count (me) - 1;
- return scm_from_double (inter * sz * d);
+ return scm_from_double (inter_f * sz * d);
}
ADD_INTERFACE (Breathing_sign, "breathing-sign-interface",
"A breathing sign.",
-
- "direction "
-
- );
+ "direction");
if (dest)
{
- send_stream_event (last, "ChangeParent", get_music ()->origin (),
- ly_symbol2scm ("context"), dest->self_scm ());
+ current->remove_context (last);
+ dest->add_context (last);
}
else
/* FIXME: constant error message. */
(c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
*/
-#include "chord-name.hh"
-#include "context.hh"
-#include "dimensions.hh"
#include "engraver.hh"
+#include "chord-name.hh"
+#include "output-def.hh"
#include "font-interface.hh"
-#include "item.hh"
#include "output-def.hh"
-#include "pitch.hh"
+#include "dimensions.hh"
+#include "item.hh"
#include "protected-scm.hh"
-#include "stream-event.hh"
+#include "context.hh"
#include "warn.hh"
-
-#include "translator.icc"
+#include "pitch.hh"
class Chord_name_engraver : public Engraver
{
protected:
void stop_translation_timestep ();
void process_music ();
+ virtual bool try_music (Music *);
virtual void finalize ();
virtual void derived_mark () const;
- DECLARE_TRANSLATOR_LISTENER (note);
private:
+ void add_note (Music *);
+
Item *chord_name_;
- vector<Stream_event*> notes_;
+ vector<Music*> notes_;
SCM last_chord_;
};
last_chord_ = SCM_EOL;
}
+void
+Chord_name_engraver::add_note (Music *n)
+{
+ notes_.push_back (n);
+}
+
void
Chord_name_engraver::process_music ()
{
SCM inversion = SCM_EOL;
SCM pitches = SCM_EOL;
- Stream_event *inversion_event = 0;
+ Music *inversion_event = 0;
for (vsize i = 0; i < notes_.size (); i++)
{
- Stream_event *n = notes_[i];
+ Music *n = notes_[i];
SCM p = n->get_property ("pitch");
if (!unsmob_pitch (p))
continue;
last_chord_ = chord_as_scm;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note);
-void
-Chord_name_engraver::listen_note (Stream_event *ev)
+bool
+Chord_name_engraver::try_music (Music *m)
{
- notes_.push_back (ev);
+ /*
+ hmm. Should check?
+ */
+ if (m->is_mus_type ("note-event"))
+ {
+ add_note (m);
+ return true;
+ }
+ return false;
}
void
The READs description is not strictly accurate:
which properties are read depend on the chord naming function active.
*/
+#include "translator.icc"
+
ADD_TRANSLATOR (Chord_name_engraver,
/* doc */ "Catch note-events "
"and generate the appropriate chordname.",
Erik Sandberg <mandolaerik@gmail.com>
*/
+#include "math.h" // ceil
+
#include "beam.hh"
#include "engraver-group.hh"
#include "international.hh"
#include "item.hh"
-#include "math.h" // ceil
#include "misc.hh"
#include "repeated-music.hh"
#include "rhythmic-head.hh"
#include "spanner.hh"
#include "stem-tremolo.hh"
#include "stem.hh"
-#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
{
TRANSLATOR_DECLARATIONS (Chord_tremolo_engraver);
protected:
- Stream_event *repeat_;
+ Music *repeat_;
int flags_;
// number of beams for short tremolos
Spanner *beam_;
protected:
virtual void finalize ();
+ virtual bool try_music (Music *);
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (tremolo_span);
DECLARE_ACKNOWLEDGER (stem);
};
beam_dir_ = CENTER;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Chord_tremolo_engraver, tremolo_span);
-void
-Chord_tremolo_engraver::listen_tremolo_span (Stream_event *ev)
+bool
+Chord_tremolo_engraver::try_music (Music *m)
{
- Direction span_dir = to_dir (ev->get_property ("span-direction"));
- if (span_dir == START)
+ if (m->is_mus_type ("tremolo-span-event"))
{
- if (ASSIGN_EVENT_ONCE (repeat_, ev))
+ Direction span_dir = to_dir (m->get_property ("span-direction"));
+ if (span_dir == START)
{
- int type = scm_to_int (ev->get_property ("tremolo-type"));
+ repeat_ = m;
+ int type = scm_to_int (m->get_property ("tremolo-type"));
/* e.g. 1 for type 8, 2 for type 16 */
flags_ = intlog2 (type) - 2;
- expected_beam_count_ = scm_to_int (ev->get_property ("expected-beam-count"));
+ expected_beam_count_ = scm_to_int (m->get_property ("expected-beam-count"));
beam_dir_ = RIGHT;
}
+ if (span_dir == STOP)
+ {
+ repeat_ = 0;
+ beam_ = 0;
+ expected_beam_count_ = 0;
+ beam_dir_ = CENTER;
+ }
+ return true;
}
- else if (span_dir == STOP)
- {
- if (!repeat_)
- ev->origin ()->warning (_ ("No tremolo to end"));
- repeat_ = 0;
- beam_ = 0;
- expected_beam_count_ = 0;
- beam_dir_ = CENTER;
- }
+ return false;
}
void
if (beam_dir_ == RIGHT)
beam_dir_ = LEFT;
- if (info.ultimate_event_cause ()->in_event_class ("rhythmic-event"))
+ if (info.ultimate_music_cause ()->is_mus_type ("rhythmic-event"))
Beam::add_stem (beam_, s);
else
{
string s = _ ("stem must have Rhythmic structure");
- if (info.event_cause ())
- info.event_cause ()->origin ()->warning (s);
+ if (info.music_cause ())
+ info.music_cause ()->origin ()->warning (s);
else
::warning (s);
}
#include "note-column.hh"
#include "pointer-group-interface.hh"
#include "pitch.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
class Cluster_spanner_engraver : public Engraver
{
protected:
TRANSLATOR_DECLARATIONS (Cluster_spanner_engraver);
- DECLARE_TRANSLATOR_LISTENER (cluster_note);
+ virtual bool try_music (Music *);
+ void process_music ();
DECLARE_ACKNOWLEDGER (note_column);
void stop_translation_timestep ();
- virtual void process_music ();
virtual void finalize ();
private:
- vector<Stream_event*> cluster_notes_;
+ vector<Music*> cluster_notes_;
Item *beacon_;
void typeset_grobs ();
beacon_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Cluster_spanner_engraver, cluster_note);
-void
-Cluster_spanner_engraver::listen_cluster_note (Stream_event *ev)
+bool
+Cluster_spanner_engraver::try_music (Music *m)
{
- cluster_notes_.push_back (ev);
+ if (m->is_mus_type ("cluster-note-event"))
+ {
+ cluster_notes_.push_back (m);
+ return true;
+ }
+ else if (m->is_mus_type ("busy-playing-event"))
+ return cluster_notes_.size ();
+
+ return false;
}
void
}
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Cluster_spanner_engraver, note_column);
ADD_TRANSLATOR (Cluster_spanner_engraver,
/* doc */ "Engraves a cluster using Spanner notation ",
/* create */ "ClusterSpanner ClusterSpannerBeacon",
- /* accept */ "cluster-note-event",
+ /* accept */ "cluster-note-event busy-playing-event",
/* read */ "",
/* write */ "");
#include "coherent-ligature-engraver.hh"
#include "warn.hh"
+#include "staff-symbol-referencer.hh"
+#include "spanner.hh"
#include "paper-column.hh"
#include "pitch.hh"
#include "pointer-group-interface.hh"
-#include "spanner.hh"
-#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
/*
* This abstract class serves as common superclass for all ligature
* example, Ligature_bracket_engraver does not share any of this code.
*/
+/*
+ * TODO: Let superflous space after each ligature collapse. The
+ * following code should help in doing so (though it does not yet
+ * fully work). Just put the following code into
+ * Spacing_spanner::do_measure (). I put it temporarily here as memo
+ * until it really works and I also get Han-Wen's/Jan's permission to
+ * add it to the spacing spanner code.
+ */
+#if 0 /* experimental code to collapse spacing after ligature */
+SCM incr_scm = lc->get_property ("forced-spacing");
+if (incr_scm != SCM_EOL) /* (Paper_column::is_musical (l)) */
+ {
+ me->warning (_f ("gotcha: ptr=%ul", lc));//debug
+ ly_display_scm (lc->self_scm ());
+ Real distance;
+ if (incr_scm != SCM_EOL)
+ distance = scm_to_double (incr_scm);
+ else
+ {
+ me->warning (_ ("distance undefined, assuming 0.1"));
+ distance = 0.1;
+ }
+ me->warning (_f ("distance=%f", distance));//debug
+ Real inverse_strength = 1.0;
+ Spaceable_grob::add_spring (lc, rc, distance, inverse_strength);
+ if (Item *rb = r->find_prebroken_piece (LEFT))
+ Spaceable_grob::add_spring (lc, rb, distance, inverse_strength);
+
+ continue;
+ }
+#endif
/*
* TODO: move this function to class Item?
for (vsize i = 0; i < primitives.size (); i++)
{
primitive = dynamic_cast<Item *> (primitives[i].grob ());
- Stream_event *cause = primitives[i].event_cause ();
+ Music *music_cause = primitives[i].music_cause ();
int pitch
- = unsmob_pitch (cause->get_property ("pitch"))->steps ();
+ = unsmob_pitch (music_cause->get_property ("pitch"))->steps ();
if (prev_primitive)
{
delta_pitch = pitch - prev_pitch;
- prev_primitive->set_property ("delta-position",
+ prev_primitive->set_property ("delta-pitch",
scm_from_int (delta_pitch));
}
prev_pitch = pitch;
prev_primitive = primitive;
}
- primitive->set_property ("delta-position", scm_from_int (0));
+ primitive->set_property ("delta-pitch", scm_from_int (0));
}
void
#include <cctype>
using namespace std;
-#include "dot-column.hh"
+#include "rhythmic-head.hh"
+#include "output-def.hh"
+#include "music.hh"
#include "dots.hh"
-#include "duration.hh"
-#include "global-context.hh"
+#include "dot-column.hh"
+#include "staff-symbol-referencer.hh"
#include "item.hh"
-#include "output-def.hh"
-#include "pitch.hh"
-#include "rhythmic-head.hh"
#include "score-engraver.hh"
+#include "warn.hh"
#include "spanner.hh"
-#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "tie.hh"
-#include "warn.hh"
-
-#include "translator.icc"
+#include "global-context.hh"
+#include "duration.hh"
+#include "pitch.hh"
/*
TODO: make matching rest engraver.
vector<Grob*> ties_;
vector<Item*> dots_;
- vector<Stream_event*> note_events_;
- vector<Stream_event*> scratch_note_events_;
+ vector<Music*> note_events_;
+ vector<Music*> scratch_note_events_;
Moment note_end_mom_;
bool is_first_;
protected:
virtual void initialize ();
void start_translation_timestep ();
+ virtual bool try_music (Music *event);
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (note);
};
void
is_first_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Completion_heads_engraver, note);
-void
-Completion_heads_engraver::listen_note (Stream_event *ev)
+bool
+Completion_heads_engraver::try_music (Music *m)
{
- note_events_.push_back (ev);
-
- is_first_ = true;
- Moment musiclen = get_event_length (ev);
- Moment now = now_mom ();
-
- if (now_mom ().grace_part_)
+ if (m->is_mus_type ("note-event"))
{
- musiclen.grace_part_ = musiclen.main_part_;
- musiclen.main_part_ = Rational (0, 1);
+ note_events_.push_back (m);
+
+ is_first_ = true;
+ Moment musiclen = m->get_length ();
+ Moment now = now_mom ();
+
+ if (now_mom ().grace_part_)
+ {
+ musiclen.grace_part_ = musiclen.main_part_;
+ musiclen.main_part_ = Rational (0, 1);
+ }
+ note_end_mom_ = max (note_end_mom_, (now + musiclen));
+ do_nothing_until_ = Rational (0, 0);
+
+ return true;
}
+ else if (m->is_mus_type ("busy-playing-event"))
+ return note_events_.size () && is_first_;
- note_end_mom_ = max (note_end_mom_, (now + musiclen));
- do_nothing_until_ = Rational (0, 0);
+ return false;
}
/*
if (!scratch_note_events_.size ())
for (vsize i = 0; i < note_events_.size (); i++)
{
- Stream_event *m = note_events_[i]->clone ();
+ Music *m = note_events_[i]->clone ();
scratch_note_events_.push_back (m);
}
}
for (vsize i = 0; left_to_do_ && i < note_events_.size (); i++)
{
- Stream_event *event = note_events_[i];
+ Music *event = note_events_[i];
if (scratch_note_events_.size ())
{
event = scratch_note_events_[i];
Item *d = make_item ("Dots", SCM_EOL);
Rhythmic_head::set_dots (note, d);
- d->set_property ("dot-count", scm_from_int (dots));
+ /*
+ measly attempt to save an eeny-weenie bit of memory.
+ */
+ if (dots != scm_to_int (d->get_property ("dot-count")))
+ d->set_property ("dot-count", scm_from_int (dots));
d->set_parent (note, Y_AXIS);
dots_.push_back (d);
{
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Completion_heads_engraver,
/* doc */ "This engraver replaces "
"@code{Note_heads_engraver}. It plays some trickery to "
"break long notes and automatically tie them into the next measure.",
- /* create */
- "NoteHead "
- "Dots "
- "Tie",
-
- /* accept */ "note-event",
- /* read */
- "middleCPosition "
- "measurePosition "
- "measureLength",
-
+ /* create */ "NoteHead Dots Tie",
+ /* accept */ "busy-playing-event note-event",
+ /* read */ "middleCPosition measurePosition measureLength",
/* write */ "");
source file of the GNU LilyPond music typesetter
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
+ (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#include "constrained-breaking.hh"
start_.size () different solution arrays. state_[i] is the array for the
solution starting at column number start_[i].
- The indices "start" and "end" refer to the index in the start_ array of the
+ The indicies "start" and "end" refer to the index in the start_ array of the
desired starting and ending columns.
each solution array looks like
bool found_something = false;
vsize start_col = starting_breakpoints_[start];
- Matrix<Constrained_break_node> &st = state_[start];
+ vector<Constrained_break_node> &st = state_[start];
+ vsize rank = breaks_.size () - start_col;
vsize max_index = brk - start_col;
- for (vsize j=max_index; j-- > sys;)
+ for (vsize j=sys; j < max_index; j++)
{
if (0 == sys && j > 0)
- continue; /* the first line cannot have its first break after the beginning */
-
- Line_details const &cur = lines_.at (brk, j + start_col);
- if (isinf (cur.force_))
- break;
+ break; /* the first line cannot have its first break after the beginning */
+ Line_details const &cur = lines_[(j + start_col)*lines_rank_ + brk];
Real prev_f = 0;
Real prev_dem = 0;
if (sys > 0)
{
- prev_f = st.at (j, sys-1).details_.force_;
- prev_dem = st.at (j, sys-1).demerits_;
+ prev_f = st[(sys-1) * rank + j].details_.force_;
+ prev_dem = st[(sys-1) * rank + j].demerits_;
}
if (isinf (prev_dem))
- continue;
+ break;
Real dem = combine_demerits (cur.force_, prev_f) + prev_dem + cur.break_penalty_;
- Constrained_break_node &n = st.at (max_index, sys);
- if (dem < n.demerits_)
+ if (isinf (dem))
+ continue;
+
+ int k = sys*rank + max_index;
+ if (isinf (st[k].demerits_) || dem < st[k].demerits_)
{
found_something = true;
- n.demerits_ = dem;
- n.details_ = cur;
- n.prev_ = j;
+ st[k].demerits_ = dem;
+ st[k].details_ = cur;
+ st[k].prev_ = j;
}
}
return found_something;
Constrained_breaking::solve ()
{
if (!systems_)
- return get_best_solution (0, VPOS);
+ {
+ programming_error (_f ("no system number set in constrained-breaking"));
+ systems_ = breaks_.size () / 4;
+ }
resize (systems_);
return get_solution(0, VPOS, systems_);
{
systems_ = systems;
+ if (!breaks_.size () && pscore_)
+ {
+ Output_def *l = pscore_->layout ();
+ Real extent = scm_to_double (l->c_variable ("system-height"));
+ Real padding = scm_to_double (l->c_variable ("between-system-padding"));
+ Real space = scm_to_double (l->c_variable ("between-system-space"));
+ bool ragged_right = to_boolean (pscore_->layout ()->c_variable ("ragged-right"));
+ bool ragged_last = to_boolean (pscore_->layout ()->c_variable ("ragged-last"));
+
+ Interval first_line = line_dimensions_int (pscore_->layout (), 0);
+ Interval other_lines = line_dimensions_int (pscore_->layout (), 1);
+ /* do all the rod/spring problems */
+ breaks_ = pscore_->find_break_indices ();
+ lines_rank_ = breaks_.size ();
+ all_ = pscore_->root_system ()->columns ();
+ lines_.resize (breaks_.size () * breaks_.size ());
+ vector<Real> forces = get_line_forces (all_,
+ breaks_,
+ other_lines.length (),
+ other_lines.length () - first_line.length (),
+ ragged_right);
+ for (vsize i = 0; i < breaks_.size () - 1; i++)
+ {
+ for (vsize j = i + 1; j < breaks_.size (); j++)
+ {
+ bool last = j == breaks_.size () - 1;
+ bool ragged = ragged_right || (last && ragged_last);
+ int k = i*lines_rank_ + j;
+ SCM pen = all_[breaks_[j]]->get_property ("line-break-penalty");
+ if (scm_is_number (pen))
+ lines_[k].break_penalty_ = scm_to_double (pen);
+
+ lines_[k].force_ = forces[k];
+ lines_[k].extent_ = extent;
+ lines_[k].padding_ = padding;
+ lines_[k].space_ = space;
+ lines_[k].inverse_hooke_ = 3; // FIXME: somewhat arbitrary
+ if (ragged && lines_[k].force_ < 0)
+ lines_[k].force_ = infinity_f;
+ if (isinf (lines_[k].force_))
+ break;
+ }
+ }
+
+ /* work out all the starting indices */
+ for (vsize i = 0; i < start_.size (); i++)
+ {
+ vsize j;
+ for (j = 0; j < breaks_.size () - 1 && breaks_[j] < start_[i]; j++)
+ ;
+ starting_breakpoints_.push_back (j);
+ start_[i] = breaks_[j];
+ }
+ state_.resize (start_.size ());
+ }
+
if (pscore_ && systems_ > valid_systems_)
{
for (vsize i = 0; i < state_.size (); i++)
- state_[i].resize (breaks_.size () - starting_breakpoints_[i], systems_, Constrained_break_node ());
+ state_[i].resize((breaks_.size () - starting_breakpoints_[i]) * systems_);
/* fill out the matrices */
for (vsize i = 0; i < state_.size (); i++)
vector<Column_x_positions>
Constrained_breaking::get_solution (vsize start, vsize end, vsize sys_count)
{
+ vsize rank;
+ vsize end_brk;
vsize start_brk = starting_breakpoints_[start];
- vsize end_brk = prepare_solution (start, end, sys_count);
+ prepare_solution (start, end, sys_count, &rank, &end_brk);
- Matrix<Constrained_break_node> const &st = state_[start];
+ vector<Constrained_break_node> const &st = state_[start];
vector<Column_x_positions> ret;
/* find the first solution that satisfies constraints */
{
for (vsize brk = end_brk; brk != VPOS; brk--)
{
- if (!isinf (st.at (brk, sys).details_.force_))
+ if (!isinf (st[sys*rank + brk].details_.force_))
{
if (brk != end_brk)
{
- warning (_ ("couldn't find line breaking that satisfies constraints" ));
+ warning ( _("couldn't find line breaking that satisfies constraints" ));
ret.push_back (space_line (brk, end_brk));
}
/* build up the good solution */
for (vsize cur_sys = sys; cur_sys != VPOS; cur_sys--)
{
- vsize prev_brk = st.at (brk, cur_sys).prev_;
+ vsize prev_brk = st[cur_sys*rank + brk].prev_;
assert (brk != VPOS);
ret.push_back (space_line (prev_brk + start_brk, brk + start_brk));
brk = prev_brk;
}
}
/* if we get to here, just put everything on one line */
- warning (_ ("couldn't find line breaking that satisfies constraints" ));
+ warning ( _("couldn't find line breaking that satisfies constraints" ));
ret.push_back (space_line (0, end_brk));
return ret;
}
-vector<Column_x_positions>
-Constrained_breaking::get_best_solution (vsize start, vsize end)
-{
- vsize min_systems = get_min_systems (start, end);
- vsize max_systems = get_max_systems (start, end);
- Real best_demerits = infinity_f;
- vector<Column_x_positions> best_so_far;
-
- for (vsize i = min_systems; i <= max_systems; i++)
- {
- vsize brk = prepare_solution (start, end, i);
- Real dem = state_[start].at (brk, i-1).demerits_;
-
- if (dem < best_demerits)
- {
- best_demerits = dem;
- best_so_far = get_solution (start, end, i);
- }
- else
- {
- vector<Column_x_positions> cur = get_solution (start, end, i);
- bool too_many_lines = true;
-
- for (vsize j = 0; j < cur.size (); j++)
- if (cur[j].force_ < 0)
- {
- too_many_lines = false;
- break;
- }
- if (too_many_lines)
- return best_so_far;
- }
- }
- if (best_so_far.size ())
- return best_so_far;
- return get_solution (start, end, max_systems);
-}
-
std::vector<Line_details>
Constrained_breaking::get_details (vsize start, vsize end, vsize sys_count)
{
- vsize brk = prepare_solution (start, end, sys_count);
- Matrix<Constrained_break_node> const &st = state_[start];
+ vsize rank;
+ vsize brk;
+ prepare_solution (start, end, sys_count, &rank, &brk);
+ vector<Constrained_break_node> const &st = state_[start];
vector<Line_details> ret;
for (int sys = sys_count-1; sys >= 0 && brk != VPOS; sys--)
{
- ret.push_back (st.at (brk, sys).details_);
- brk = st.at (brk, sys).prev_;
+ ret.push_back (st[sys*rank + brk].details_);
+ brk = st[sys*rank + brk].prev_;
}
- reverse (ret);
return ret;
}
int
Constrained_breaking::get_min_systems (vsize start, vsize end)
{
+ vsize rank;
+ vsize brk;
vsize sys_count;
- vsize brk = prepare_solution (start, end, 1);
- vsize rank = breaks_.size () - starting_breakpoints_[start];
- Matrix<Constrained_break_node> const &st = state_[start];
+
+ prepare_solution (start, end, 1, &rank, &brk);
+ vector<Constrained_break_node> const &st = state_[start];
/* sys_count < rank : rank is the # of breakpoints, we can't have more systems */
for (sys_count = 0; sys_count < rank; sys_count++)
{
resize (sys_count + 3);
}
- if (!isinf (st.at (brk, sys_count).details_.force_))
+ if (!isinf (st[sys_count*rank + brk].details_.force_))
return sys_count + 1;
}
/* no possible breaks satisfy constraints */
return brk - starting_breakpoints_[start];
}
-vsize
-Constrained_breaking::prepare_solution (vsize start, vsize end, vsize sys_count)
+void
+Constrained_breaking::prepare_solution (vsize start, vsize end, vsize sys_count, vsize *rank, vsize *brk)
{
assert (start < start_.size () && (end == VPOS || end <= start_.size ()));
assert (start < end);
if (end == start_.size ())
end = VPOS;
- vsize brk;
- brk = end == VPOS ? breaks_.size () - 1 : starting_breakpoints_[end];
- brk -= starting_breakpoints_[start];
- return brk;
+ *rank = breaks_.size () - starting_breakpoints_[start];
+ *brk = end == VPOS ? breaks_.size () - 1 : starting_breakpoints_[end];
+ *brk -= starting_breakpoints_[start];
}
-Constrained_breaking::Constrained_breaking (Paper_score *ps)
+Constrained_breaking::Constrained_breaking ()
{
valid_systems_ = systems_ = 0;
start_.push_back (0);
- pscore_ = ps;
- initialize ();
}
-Constrained_breaking::Constrained_breaking (Paper_score *ps, vector<vsize> const &start)
+Constrained_breaking::Constrained_breaking (vector<vsize> const &start)
: start_ (start)
{
valid_systems_ = systems_ = 0;
- pscore_ = ps;
- initialize ();
-}
-
-/* find the forces for all possible lines and cache ragged_ and ragged_right_ */
-void
-Constrained_breaking::initialize ()
-{
- if (!pscore_)
- return;
-
- ragged_right_ = to_boolean (pscore_->layout ()->c_variable ("ragged-right"));
- ragged_last_ = to_boolean (pscore_->layout ()->c_variable ("ragged-last"));
-
- Output_def *l = pscore_->layout ();
- System *sys = pscore_->root_system ();
- Real padding = robust_scm2double (l->c_variable ("between-system-padding"), 0);
- Real space = robust_scm2double (l->c_variable ("ideal-system-space"), 0);
-
- Interval first_line = line_dimensions_int (pscore_->layout (), 0);
- Interval other_lines = line_dimensions_int (pscore_->layout (), 1);
- /* do all the rod/spring problems */
- breaks_ = pscore_->find_break_indices ();
- all_ = pscore_->root_system ()->columns ();
- lines_.resize (breaks_.size (), breaks_.size (), Line_details ());
- vector<Real> forces = get_line_forces (all_,
- other_lines.length (),
- other_lines.length () - first_line.length (),
- ragged_right_);
- for (vsize i = 0; i < breaks_.size () - 1; i++)
- {
- Real max_ext = 0;
- for (vsize j = i + 1; j < breaks_.size (); j++)
- {
- int start = Paper_column::get_rank (all_[breaks_[i]]);
- int end = Paper_column::get_rank (all_[breaks_[j]]);
- Interval extent = sys->pure_height (sys, start, end);
- bool last = j == breaks_.size () - 1;
- bool ragged = ragged_right_ || (last && ragged_last_);
- Line_details &line = lines_.at (j, i);
-
- line.force_ = forces[i*breaks_.size () + j];
- if (ragged && last && !isinf (line.force_))
- line.force_ = 0;
- if (isinf (line.force_))
- break;
-
- Grob *c = all_[breaks_[j]];
- line.break_penalty_ = robust_scm2double (c->get_property ("line-break-penalty"), 0);
- line.page_penalty_ = robust_scm2double (c->get_property ("page-break-penalty"), 0);
- line.turn_penalty_ = robust_scm2double (c->get_property ("page-turn-penalty"), 0);
- line.break_permission_ = c->get_property ("line-break-permission");
- line.page_permission_ = c->get_property ("page-break-permission");
- line.turn_permission_ = c->get_property ("page-turn-permission");
-
- max_ext = max (max_ext, extent.length ());
- line.extent_ = extent;
- line.padding_ = padding;
- line.space_ = space;
- line.inverse_hooke_ = 1;
- }
- }
-
- /* work out all the starting indices */
- for (vsize i = 0; i < start_.size (); i++)
- {
- vsize j;
- for (j = 0; j < breaks_.size () - 1 && breaks_[j] < start_[i]; j++)
- ;
- starting_breakpoints_.push_back (j);
- start_[i] = breaks_[j];
- }
- state_.resize (start_.size ());
}
Real
Constrained_breaking::combine_demerits (Real force, Real prev_force)
{
- if (ragged_right_)
- return force * force;
-
- return force * force + (prev_force - force) * (prev_force - force);
+ return force * force + fabs (prev_force - force);
}
#include "context-def.hh"
-#include "context.hh"
+#include "engraver-group.hh"
+#include "engraver.hh"
#include "international.hh"
#include "output-def.hh"
-#include "translator.hh"
+#include "performer-group.hh"
+#include "performer.hh"
+#include "score-context.hh"
+#include "translator-group.hh"
#include "warn.hh"
Context_def::Context_def ()
context_name_ = SCM_EOL;
default_child_ = SCM_EOL;
description_ = SCM_EOL;
- input_location_ = SCM_EOL;
smobify_self ();
- input_location_ = make_input (Input ());
context_name_ = ly_symbol2scm ("");
}
-Input *
-Context_def::origin () const
-{
- return unsmob_input (input_location_);
-}
-
Context_def::Context_def (Context_def const &s)
+ : Input (s)
{
context_aliases_ = SCM_EOL;
translator_group_type_ = SCM_EOL;
context_name_ = SCM_EOL;
description_ = SCM_EOL;
default_child_ = SCM_EOL;
- input_location_ = SCM_EOL;
- smobify_self ();
+ smobify_self ();
description_ = s.description_;
- input_location_ = make_input (*s.origin ());
+
default_child_ = s.default_child_;
accept_mods_ = s.accept_mods_;
property_ops_ = s.property_ops_;
scm_gc_mark (me->property_ops_);
scm_gc_mark (me->translator_group_type_);
scm_gc_mark (me->default_child_);
- scm_gc_mark (me->input_location_);
return me->context_name_;
}
programming_error ("unknown context mod tag");
}
+SCM
+Context_def::get_context_name () const
+{
+ return context_name_;
+}
+
SCM
Context_def::get_accepted (SCM user_mod) const
{
return l1;
}
+SCM
+filter_performers (SCM ell)
+{
+ SCM *tail = ℓ
+ for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
+ {
+ if (dynamic_cast<Performer *> (unsmob_translator (scm_car (*tail))))
+ *tail = scm_cdr (*tail);
+ else
+ tail = SCM_CDRLOC (*tail);
+ }
+ return ell;
+}
+
+SCM
+filter_engravers (SCM ell)
+{
+ SCM *tail = ℓ
+ for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
+ {
+ if (dynamic_cast<Engraver *> (unsmob_translator (scm_car (*tail))))
+ *tail = scm_cdr (*tail);
+ else
+ tail = SCM_CDRLOC (*tail);
+ }
+ return ell;
+}
+
Context *
Context_def::instantiate (SCM ops, Object_key const *key)
{
- Context *context = new Context (key);
+ Context *context = 0;
+
+ if (context_name_ == ly_symbol2scm ("Score"))
+ context = new Score_context (key);
+ else
+ context = new Context (key);
context->definition_ = self_scm ();
context->definition_mods_ = ops;
+
+ SCM trans_names = get_translator_names (ops);
+
+ Translator_group *g = get_translator_group (translator_group_type_);
+ SCM trans_list = SCM_EOL;
+
+ for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s))
+ {
+ Translator *t = get_translator (scm_car (s));
+ if (!t)
+ warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
+ else
+ {
+ Translator *tr = t->clone ();
+ SCM str = tr->self_scm ();
+
+ if (tr->must_be_last ())
+ {
+ SCM cons = scm_cons (str, SCM_EOL);
+ if (scm_is_pair (trans_list))
+ scm_set_cdr_x (scm_last_pair (trans_list), cons);
+ else
+ trans_list = cons;
+ }
+ else
+ trans_list = scm_cons (str, trans_list);
+
+ tr->daddy_context_ = context;
+ tr->unprotect ();
+ }
+ }
+
+ /*
+ Ugh, todo: should just make a private
+ copy of Context_def with the user mods.
+ */
+
+ g->simple_trans_list_ = trans_list;
+
+ context->implementation_ = g;
+ if (dynamic_cast<Engraver_group *> (g))
+ g->simple_trans_list_ = filter_performers (g->simple_trans_list_);
+ else if (dynamic_cast<Performer_group *> (g))
+ g->simple_trans_list_ = filter_engravers (g->simple_trans_list_);
+
context->aliases_ = context_aliases_;
+ g->connect_to_context (context);
+ g->unprotect ();
+
context->accepts_list_ = get_accepted (ops);
return context;
}
+SCM
+Context_def::clone_scm () const
+{
+ Context_def *t = new Context_def (*this);
+ return t->unprotect ();
+}
+
SCM
Context_def::make_scm ()
{
outlet_ = 0;
}
+bool
+Context_handle::try_music (Music *m)
+{
+ return outlet_->try_music (m);
+}
+
void
Context_handle::operator = (Context_handle const &s)
{
{
SCM base = updated_grob_properties (context, context_property);
current_context_val = scm_cons (base, base);
- context->set_property (context_property, current_context_val);
+ context->internal_set_property (context_property, current_context_val);
}
if (!scm_is_pair (current_context_val))
if (new_alist == daddy)
context->unset_property (context_property);
else
- context->set_property (context_property, scm_cons (new_alist, daddy));
+ context->internal_set_property (context_property, scm_cons (new_alist, daddy));
}
}
execute_general_pushpop_property (tg, context_prop, grob_prop_path, val);
}
else if (type == ly_symbol2scm ("assign"))
- tg->set_property (scm_car (entry), scm_cadr (entry));
+ tg->internal_set_property (scm_car (entry), scm_cadr (entry));
}
}
return copy;
}
}
+
+Grob *
+make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name)
+{
+ Context *context = tr->context ();
+
+ SCM props = updated_grob_properties (context, symbol);
+
+ Object_key const *key = context->get_grob_key (name);
+ Grob *grob = 0;
+
+ SCM handle = scm_sloppy_assq (ly_symbol2scm ("meta"), props);
+ SCM klass = scm_cdr (scm_sloppy_assq (ly_symbol2scm ("class"), scm_cdr (handle)));
+
+ if (klass == ly_symbol2scm ("Item"))
+ grob = new Item (props, key);
+ else if (klass == ly_symbol2scm ("Spanner"))
+ grob = new Spanner (props, key);
+ else if (klass == ly_symbol2scm ("Paper_column"))
+ grob = new Paper_column (props, key);
+
+ assert (grob);
+ dynamic_cast<Engraver *> (tr)->announce_grob (grob, cause);
+
+ return grob;
+}
+
+Item *
+make_item_from_properties (Engraver *tr, SCM x, SCM cause, char const *name)
+{
+ Item *it = dynamic_cast<Item *> (make_grob_from_properties (tr, x, cause, name));
+ assert (it);
+ return it;
+}
+
+Paper_column *
+make_paper_column_from_properties (Engraver *tr, SCM x, char const *name)
+{
+ return dynamic_cast<Paper_column *> (make_grob_from_properties (tr, x, SCM_EOL, name));
+}
+
+Spanner *
+make_spanner_from_properties (Engraver *tr, SCM x, SCM cause, char const *name)
+{
+ Spanner *sp = dynamic_cast<Spanner *> (make_grob_from_properties (tr, x, cause, name));
+ assert (sp);
+ return sp;
+}
SCM_ASSERT_TYPE (tr, context, SCM_ARG1, __FUNCTION__, "Context");
SCM_ASSERT_TYPE (scm_is_symbol (name), name, SCM_ARG2, __FUNCTION__, "symbol");
- tr->set_property (name, val);
+ tr->internal_set_property (name, val);
return SCM_UNSPECIFIED;
}
#include "context-def.hh"
#include "dispatcher.hh"
-#include "global-context.hh"
#include "international.hh"
#include "ly-smobs.icc"
#include "main.hh"
#include "profile.hh"
#include "program-option.hh"
#include "scm-hash.hh"
+#include "score-context.hh"
#include "translator-group.hh"
#include "warn.hh"
{
for (SCM p = context_list_; scm_is_pair (p); p = scm_cdr (p))
{
- Context *ctx = unsmob_context (scm_car (p));
+ Context *trg = unsmob_context (scm_car (p));
- ctx->check_removal ();
- if (ctx->is_removable ())
+ trg->check_removal ();
+ if (trg->is_removable ())
{
- recurse_over_translators (ctx, &Translator::finalize,
+ recurse_over_translators (trg, &Translator::finalize,
&Translator_group::finalize,
UP);
- send_stream_event (ctx, "RemoveContext", 0, 0);
+ remove_context (trg);
}
}
}
}
void
-Context::add_context (Context *child)
+Context::add_context (Context *t)
{
+ SCM ts = t->self_scm ();
context_list_ = ly_append2 (context_list_,
- scm_cons (child->self_scm (), SCM_EOL));
+ scm_cons (ts, SCM_EOL));
+
+ t->daddy_context_ = this;
+ if (!t->init_)
+ {
+ t->init_ = true;
- child->daddy_context_ = this;
- this->events_below_->register_as_listener (child->events_below_);
+ t->unprotect ();
+ Context_def *td = unsmob_context_def (t->definition_);
+
+ /* This cannot move before add_context (), because \override
+ operations require that we are in the hierarchy. */
+ td->apply_default_property_operations (t);
+
+ recurse_over_translators (t,
+ &Translator::initialize,
+ &Translator_group::initialize,
+ DOWN);
+ }
}
: key_manager_ (key)
{
daddy_context_ = 0;
+ init_ = false;
aliases_ = SCM_EOL;
iterator_count_ = 0;
implementation_ = 0;
context_list_ = SCM_EOL;
definition_ = SCM_EOL;
definition_mods_ = SCM_EOL;
+ unique_ = -1;
event_source_ = 0;
events_below_ = 0;
}
/*
- Don't go up to Global_context, because global goes down to the
- Score context
+ Don't go up to Global_context, because global goes down to
+ Score_context
*/
Context *ret = 0;
if (daddy_context_ && !dynamic_cast<Global_context *> (daddy_context_))
}
/*
- Don't go up to Global_context, because global goes down to the
- Score context
+ Don't go up to Global_context, because global goes down to
+ Score_context
*/
Context *ret = 0;
if (daddy_context_ && !dynamic_cast<Global_context *> (daddy_context_))
return ret;
}
-IMPLEMENT_LISTENER (Context, acknowledge_infant);
-void
-Context::acknowledge_infant (SCM sev)
-{
- infant_event_ = unsmob_stream_event (sev);
-}
-
-IMPLEMENT_LISTENER (Context, set_property_from_event);
-void
-Context::set_property_from_event (SCM sev)
+Context *
+Context::create_context (Context_def *cdef,
+ string id,
+ SCM ops)
{
- Stream_event *ev = unsmob_stream_event (sev);
-
- SCM sym = ev->get_property ("symbol");
- if (scm_is_symbol (sym))
- {
- SCM val = ev->get_property ("value");
- bool ok = true;
- if (val != SCM_EOL)
- ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"));
- if (ok)
- set_property (sym, val);
- }
-}
+ int unique = get_global_context()->new_unique();
-IMPLEMENT_LISTENER (Context, unset_property_from_event);
-void
-Context::unset_property_from_event (SCM sev)
-{
- Stream_event *ev = unsmob_stream_event (sev);
-
- SCM sym = ev->get_property ("symbol");
- type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
- unset_property (sym);
-}
-
-/*
- Creates a new context from a CreateContext event, and sends an
- AnnounceNewContext event to this context.
-*/
-IMPLEMENT_LISTENER (Context, create_context_from_event);
-void
-Context::create_context_from_event (SCM sev)
-{
- Stream_event *ev = unsmob_stream_event (sev);
-
- string id = ly_scm2string (ev->get_property ("id"));
- SCM ops = ev->get_property ("ops");
- SCM type_scm = ev->get_property ("type");
- string type = ly_symbol2string (type_scm);
+ // TODO: The following should be carried out by a listener.
+ string type = ly_symbol2string (cdef->get_context_name ());
Object_key const *key = key_manager_.get_context_key (now_mom(), type, id);
-
- vector<Context_def*> path
- = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ());
- if (path.size () != 1)
- {
- programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
- return;
- }
- Context_def *cdef = path[0];
-
- Context *new_context = cdef->instantiate (ops, key);
+ Context *new_context
+ = cdef->instantiate (ops, key);
new_context->id_string_ = id;
+ new_context->unique_ = unique;
- /* Register various listeners:
- - Make the new context hear events that universally affect contexts
- - connect events_below etc. properly */
- /* We want to be the first ones to hear our own events. Therefore, wait
- before registering events_below_ */
- new_context->event_source ()->
- add_listener (GET_LISTENER (new_context->create_context_from_event),
- ly_symbol2scm ("CreateContext"));
- new_context->event_source ()->
- add_listener (GET_LISTENER (new_context->remove_context),
- ly_symbol2scm ("RemoveContext"));
- new_context->event_source ()->
- add_listener (GET_LISTENER (new_context->change_parent),
- ly_symbol2scm ("ChangeParent"));
- new_context->event_source ()->
- add_listener (GET_LISTENER (new_context->set_property_from_event),
- ly_symbol2scm ("SetProperty"));
- new_context->event_source ()->
- add_listener (GET_LISTENER (new_context->unset_property_from_event),
- ly_symbol2scm ("UnsetProperty"));
-
new_context->events_below_->register_as_listener (new_context->event_source_);
- this->add_context (new_context);
-
- new_context->unprotect ();
-
- Context_def *td = unsmob_context_def (new_context->definition_);
-
- /* This cannot move before add_context (), because \override
- operations require that we are in the hierarchy. */
- td->apply_default_property_operations (new_context);
+
+ add_context (new_context);
apply_property_operations (new_context, ops);
+ events_below_->register_as_listener (new_context->events_below_);
- send_stream_event (this, "AnnounceNewContext", 0,
- ly_symbol2scm ("context"), new_context->self_scm (),
- ly_symbol2scm ("creator"), sev);
-}
-
-Context *
-Context::create_context (Context_def *cdef,
- string id,
- SCM ops)
-{
- infant_event_ = 0;
- /* TODO: This is fairly misplaced. We can fix this when we have taken out all
- iterator specific stuff from the Context class */
- event_source_->
- add_listener (GET_LISTENER (acknowledge_infant),
- ly_symbol2scm ("AnnounceNewContext"));
- /* The CreateContext creates a new context, and sends an announcement of the
- new context through another event. That event will be stored in
- infant_event_ to create a return value. */
- send_stream_event (this, "CreateContext", 0,
+ // TODO: The above operations should be performed by a listener to the following event.
+ send_stream_event (this, "CreateContext",
+ ly_symbol2scm ("unique"), scm_int2num (unique),
ly_symbol2scm ("ops"), ops,
ly_symbol2scm ("type"), cdef->get_context_name (),
ly_symbol2scm ("id"), scm_makfrom0str (id.c_str ()));
- event_source_->
- remove_listener (GET_LISTENER (acknowledge_infant),
- ly_symbol2scm ("AnnounceNewContext"));
-
- assert (infant_event_);
- SCM infant_scm = infant_event_->get_property ("context");
- Context *infant = unsmob_context (infant_scm);
-
- if (!infant || infant->get_parent_context () != this)
- {
- programming_error ("create_context: can't locate newly created context");
- return 0;
- }
- return infant;
+ return new_context;
}
/*
be called from any other place than the send_stream_event macro.
*/
void
-Context::internal_send_stream_event (SCM type, Input *origin, SCM props[])
+Context::internal_send_stream_event (SCM type, SCM props[])
{
- Stream_event *e = new Stream_event (type, origin);
+ Stream_event *e = new Stream_event (this, type);
for (int i = 0; props[i]; i += 2)
{
- e->set_property (props[i], props[i+1]);
+ e->internal_set_property (props[i], props[i+1]);
}
event_source_->broadcast (e);
e->unprotect ();
}
void
-Context::internal_set_property (SCM sym, SCM val
-#ifndef NDEBUG
- , char const *file, int line, char const *fun
-#endif
- )
+Context::internal_set_property (SCM sym, SCM val)
{
+#ifndef NDEBUG
if (do_internal_type_checking_global)
assert (type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")));
+#endif
properties_dict ()->set (sym, val);
}
properties_dict ()->remove (sym);
}
-IMPLEMENT_LISTENER (Context, change_parent);
-void
-Context::change_parent (SCM sev)
+/**
+ Remove a context from the hierarchy.
+*/
+Context *
+Context::remove_context (Context *trans)
{
- Stream_event *ev = unsmob_stream_event (sev);
- Context *to = unsmob_context (ev->get_property ("context"));
+ assert (trans);
- disconnect_from_parent ();
- to->add_context (this);
+ context_list_ = scm_delq_x (trans->self_scm (), context_list_);
+ trans->daddy_context_ = 0;
+ return trans;
}
-/*
- Die. The next GC sweep should take care of the actual death.
- */
-IMPLEMENT_LISTENER (Context, remove_context);
-void
-Context::remove_context (SCM)
-{
- /* ugh, the translator group should listen to RemoveContext events by itself */
- implementation ()->disconnect_from_context ();
- disconnect_from_parent ();
-}
-
-void
-Context::disconnect_from_parent ()
-{
- daddy_context_->events_below_->unregister_as_listener (this->events_below_);
- daddy_context_->context_list_ = scm_delq_x (this->self_scm (), daddy_context_->context_list_);
- daddy_context_ = 0;
-}
/*
ID == "" means accept any ID.
return found;
}
+Context *
+find_context_below (Context *where,
+ int unique)
+{
+ if (where->get_unique () == unique)
+ return where;
+
+ Context *found = 0;
+ for (SCM s = where->children_contexts ();
+ !found && scm_is_pair (s); s = scm_cdr (s))
+ {
+ Context *tr = unsmob_context (scm_car (s));
+
+ found = find_context_below (tr, unique);
+ }
+
+ return found;
+}
+
SCM
Context::properties_as_alist () const
{
return ly_symbol2string (context_name_symbol ());
}
-Context *
+Score_context *
Context::get_score_context () const
{
- if (daddy_context_)
+ if (Score_context *sc = dynamic_cast<Score_context *> ((Context *) this))
+ return sc;
+ else if (daddy_context_)
return daddy_context_->get_score_context ();
else
return 0;
IMPLEMENT_DEFAULT_EQUAL_P (Context);
IMPLEMENT_TYPE_P (Context, "ly:context?");
+bool
+Context::try_music (Music *m)
+{
+ Translator_group *t = implementation ();
+ if (!t)
+ return false;
+
+ bool b = t->try_music (m);
+ if (!b && daddy_context_)
+ b = daddy_context_->try_music (m);
+
+ return b;
+}
+
Global_context *
Context::get_global_context () const
{
void
set_context_property_on_children (Context *trans, SCM sym, SCM val)
{
- trans->set_property (sym, ly_deep_copy (val));
+ trans->internal_set_property (sym, ly_deep_copy (val));
for (SCM p = trans->children_contexts (); scm_is_pair (p); p = scm_cdr (p))
{
Context *trg = unsmob_context (scm_car (p));
+++ /dev/null
-
-
-#include "warn.hh"
-#include "audio-item.hh"
-#include "audio-staff.hh"
-#include "performer.hh"
-#include "string-convert.hh"
-#include "lily-version.hh"
-
-#include "translator.icc"
-
-class Control_track_performer : public Performer
-{
- Audio_staff *control_track_;
- vector<Audio_item*> texts_;
-
- void add_text (Audio_text::Type, string);
- TRANSLATOR_DECLARATIONS(Control_track_performer);
-protected:
-
- virtual void initialize ();
- virtual void acknowledge_audio_element (Audio_element_info info);
-};
-
-
-Control_track_performer::Control_track_performer ()
-{
- control_track_ = 0;
-}
-
-void
-Control_track_performer::acknowledge_audio_element (Audio_element_info info)
-{
- if (Audio_tempo *tempo = dynamic_cast<Audio_tempo*> (info.elem_))
- {
- control_track_->add_audio_item (tempo);
- }
- if (Audio_time_signature * sig = dynamic_cast<Audio_time_signature *> (info.elem_))
- {
- control_track_->add_audio_item (sig);
- }
-}
-
-void
-Control_track_performer::add_text (Audio_text::Type text_type, string str)
-{
- Audio_item *text = new Audio_text (text_type, str);
- control_track_->add_audio_item (text);
- texts_.push_back (text);
-
- announce_element (Audio_element_info (text, 0));
-
-}
-
-void
-Control_track_performer::initialize ()
-{
- control_track_ = new Audio_staff;
- announce_element (Audio_element_info (control_track_, 0));
-
- string id_string = String_convert::pad_to (gnu_lilypond_version_string (), 30);
-
- add_text (Audio_text::TRACK_NAME, "control track");
- add_text (Audio_text::TEXT, "creator: ");
- add_text (Audio_text::TEXT, id_string);
-}
-
-ADD_TRANSLATOR (Control_track_performer, "", "",
- "",
- "", "");
#include "bar-line.hh"
#include "item.hh"
#include "note-head.hh"
-#include "pitch.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "warn.hh"
+#include "pitch.hh"
#include "translator.icc"
void
Custos_engraver::acknowledge_note_head (Grob_info info)
{
- Stream_event *ev = info.event_cause ();
- if (ev && ev->in_event_class ("note-event"))
+ Music *m = info.music_cause ();
+ if (m && m->is_mus_type ("note-event"))
{
/*
don't look at the staff-position, since we can't be sure
whether Clef_engraver already applied a vertical shift.
*/
- pitches_.push_back (*unsmob_pitch (ev->get_property ("pitch")));
+ pitches_.push_back (*unsmob_pitch (m->get_property ("pitch")));
}
}
SCM_ASSERT_TYPE (l, list, SCM_ARG1, __FUNCTION__, "listener");
SCM_ASSERT_TYPE (d, disp, SCM_ARG2, __FUNCTION__, "dispatcher");
- for (int arg=SCM_ARG3; scm_is_pair (cl); cl = scm_cdr (cl), arg++)
+ for (int arg=SCM_ARG3; cl != SCM_EOL; cl = scm_cdr (cl), arg++)
{
SCM_ASSERT_TYPE (scm_symbol_p (cl), cl, arg, __FUNCTION__, "symbol");
d->add_listener (*l, scm_car (cl));
*/
#include "dispatcher.hh"
-#include "input.hh"
#include "international.hh"
#include "ly-smobs.icc"
#include "stream-event.hh"
#include "warn.hh"
+// ES todo: move to lily-guile.hh
+SCM appendable_list ();
+void appendable_list_append (SCM l, SCM elt);
+
IMPLEMENT_SMOBS (Dispatcher);
IMPLEMENT_TYPE_P (Dispatcher, "dispatcher");
IMPLEMENT_DEFAULT_EQUAL_P (Dispatcher);
SCM class_symbol = ev->get_property ("class");
if (!scm_symbol_p (class_symbol))
{
- warning (_f ("Event class should be a symbol"));
+ warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ()));
return;
}
SCM class_list = scm_call_1 (ly_lily_module_constant ("ly:make-event-class"), class_symbol);
- if (!scm_is_pair (class_list))
- {
- ev->origin ()->warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ()));
- return;
- }
bool sent = false;
int num_classes = scm_ilength (class_list);
Dispatcher::internal_add_listener (Listener l, SCM ev_class, int priority)
{
SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL);
- if (!scm_is_pair (list))
+ if (list == SCM_EOL)
{
- /* Tell all dispatchers that we listen to, that we want to hear ev_class
- events */
+ /* Register with all dispatchers. */
for (SCM disp = dispatchers_; scm_is_pair(disp); disp = scm_cdr (disp))
{
int priority = scm_to_int (scm_cdar (disp));
listen_classes_ = scm_cons (ev_class, listen_classes_);
}
SCM entry = scm_cons (scm_int2num (priority), l.smobbed_copy ());
- list = scm_merge (list, scm_list_1 (entry), ly_lily_module_constant ("car<"));
+ list = scm_merge_x (list, scm_list_1 (entry), ly_lily_module_constant ("car<"));
scm_hashq_set_x (listeners_, ev_class, list);
}
else
e = scm_cdr (e);
list = scm_cdr (dummy);
- scm_hashq_set_x (listeners_, ev_class, list);
if (first)
warning ("Attempting to remove nonexisting listener.");
- else if (!scm_is_pair (list))
+ else if (list == SCM_EOL)
{
/* Unregister with all dispatchers. */
- for (SCM disp = dispatchers_; scm_is_pair (disp); disp = scm_cdr (disp))
+ for (SCM disp = dispatchers_; disp != SCM_EOL; disp = scm_cdr (disp))
{
Dispatcher *d = unsmob_dispatcher (scm_caar (disp));
d->remove_listener (GET_LISTENER (dispatch), ev_class);
dispatchers_ = scm_acons (disp->self_scm (), scm_int2num (priority), dispatchers_);
Listener list = GET_LISTENER (dispatch);
- for (SCM cl = listen_classes_; scm_is_pair (cl); cl = scm_cdr (cl))
+ for (SCM cl = listen_classes_; cl != SCM_EOL; cl = scm_cdr (cl))
{
disp->internal_add_listener (list, scm_car (cl), priority);
}
{
dispatchers_ = scm_assq_remove_x (dispatchers_, disp->self_scm ());
- Listener listener = GET_LISTENER (dispatch);
- for (SCM cl = listen_classes_; scm_is_pair (cl); cl = scm_cdr (cl))
+ Listener list = GET_LISTENER (dispatch);
+ for (SCM cl = listen_classes_; cl != SCM_EOL; cl = scm_cdr (cl))
{
- disp->remove_listener (listener, scm_car (cl));
+ disp->remove_listener (list, scm_car (cl));
}
}
}
}
- return Side_position_interface::x_aligned_side (smob, SCM_EOL);
+ return Side_position_interface::x_aligned_side (smob);
}
struct Dot_position
}
}
- vector_sort (dots, position_less);
+ vector_sort (dots, &compare_position);
for (vsize i = dots.size (); i--;)
if (!dots[i]->is_live ())
dots.erase (dots.begin () + i);
+++ /dev/null
-/*
- dots-engraver.cc -- implement Dots_engraver
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
-
-*/
-
-#include "engraver.hh"
-#include "duration.hh"
-#include "item.hh"
-#include "rhythmic-head.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
-
-
-class Dots_engraver : public Engraver
-{
- DECLARE_ACKNOWLEDGER(rhythmic_head);
- TRANSLATOR_DECLARATIONS(Dots_engraver);
-};
-
-Dots_engraver::Dots_engraver ()
-{
-}
-
-void
-Dots_engraver::acknowledge_rhythmic_head (Grob_info gi)
-{
- Stream_event *cause = gi.event_cause ();
- if (!cause)
- return;
-
- Grob *note = gi.grob ();
- if (unsmob_grob (note->get_object ("dot")))
- return;
-
- Duration dur = *unsmob_duration (cause->get_property ("duration"));
- if (dur.dot_count ())
- {
- Item *d = make_item ("Dots", note->self_scm ());
- Rhythmic_head::set_dots (note, d);
- d->set_parent (note, Y_AXIS);
- }
-}
-
-
-ADD_ACKNOWLEDGER(Dots_engraver, rhythmic_head);
-
-ADD_TRANSLATOR(Dots_engraver,
- "Create @ref{Dots} objects for @ref{rhythmic-head-interface}s.",
-
- /* create */
- "Dots ",
-
- /*acc*/
- "",
-
- /*r*/
- "" ,
-
- /*w*/
- "");
#include <cctype>
using namespace std;
-#include "duration.hh"
-#include "engraver.hh"
-#include "note-column.hh"
#include "rhythmic-head.hh"
+#include "engraver.hh"
+#include "warn.hh"
#include "side-position-interface.hh"
#include "script-interface.hh"
#include "stem.hh"
-#include "stream-event.hh"
-#include "warn.hh"
-
-#include "translator.icc"
+#include "note-column.hh"
+#include "duration.hh"
class Drum_notes_engraver : public Engraver
{
vector<Item*> notes_;
+ vector<Item*> dots_;
vector<Item*> scripts_;
- vector<Stream_event*> events_;
+ vector<Music*> events_;
public:
TRANSLATOR_DECLARATIONS (Drum_notes_engraver);
protected:
+ virtual bool try_music (Music *ev);
void process_music ();
DECLARE_ACKNOWLEDGER (stem);
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (note);
void stop_translation_timestep ();
};
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Drum_notes_engraver, note);
-void
-Drum_notes_engraver::listen_note (Stream_event *ev)
+bool
+Drum_notes_engraver::try_music (Music *m)
{
- events_.push_back (ev);
+ if (m->is_mus_type ("note-event"))
+ {
+ events_.push_back (m);
+ return true;
+ }
+ else if (m->is_mus_type ("busy-playing-event"))
+ return events_.size ();
+
+ return false;
}
void
if (!tab)
tab = get_property ("drumStyleTable");
- Stream_event *ev = events_[i];
+ Music *ev = events_[i];
Item *note = make_item ("NoteHead", ev->self_scm ());
+ Duration dur = *unsmob_duration (ev->get_property ("duration"));
+
+ note->set_property ("duration-log", scm_from_int (dur.duration_log ()));
+
+ if (dur.dot_count ())
+ {
+ Item *d = make_item ("Dots", ev->self_scm ());
+ Rhythmic_head::set_dots (note, d);
+
+ if (dur.dot_count ()
+ != robust_scm2int (d->get_property ("dot-count"), 0))
+ d->set_property ("dot-count", scm_from_int (dur.dot_count ()));
+
+ d->set_parent (note, Y_AXIS);
+
+ dots_.push_back (d);
+ }
+
SCM drum_type = ev->get_property ("drum-type");
SCM defn = SCM_EOL;
Drum_notes_engraver::stop_translation_timestep ()
{
notes_.clear ();
+ dots_.clear ();
scripts_.clear ();
events_.clear ();
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Drum_notes_engraver, stem);
ADD_ACKNOWLEDGER (Drum_notes_engraver, note_column);
ADD_TRANSLATOR (Drum_notes_engraver,
/* doc */ "Generate noteheads.",
- /* create */
- "NoteHead "
- "Script",
-
- /* accept */ "note-event",
+ /* create */ "NoteHead Dots Script",
+ /* accept */ "note-event busy-playing-event",
/* read */ "drumStyleTable",
/* write */ "");
#include "audio-item.hh"
#include "audio-column.hh"
#include "global-context.hh"
-#include "pitch.hh"
-#include "stream-event.hh"
-#include "translator.icc"
#include "warn.hh"
+#include "pitch.hh"
+#include "music.hh"
class Drum_note_performer : public Performer
{
TRANSLATOR_DECLARATIONS (Drum_note_performer);
protected:
+ virtual bool try_music (Music *ev);
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (note);
+
private:
- vector<Stream_event*> note_evs_;
+ vector<Music*> note_evs_;
vector<Audio_note*> notes_;
};
while (note_evs_.size ())
{
- Stream_event *n = note_evs_.back ();
+ Music *n = note_evs_.back ();
note_evs_.pop_back ();
SCM sym = n->get_property ("drum-type");
SCM defn = SCM_EOL;
if (Pitch *pit = unsmob_pitch (defn))
{
- SCM articulations = n->get_property ("articulations");
- Stream_event *tie_event = 0;
- for (SCM s = articulations;
- !tie_event && scm_is_pair (s);
- s = scm_cdr (s))
- {
- Stream_event *ev = unsmob_stream_event (scm_car (s));
- if (!ev)
- continue;
-
- if (ev->in_event_class ("tie-event"))
- tie_event = ev;
- }
-
- Audio_note *p = new Audio_note (*pit, get_event_length (n),
- tie_event, 0);
+ Audio_note *p = new Audio_note (*pit, n->get_length (), 0);
Audio_element_info info (p, n);
announce_element (info);
notes_.push_back (p);
void
Drum_note_performer::stop_translation_timestep ()
{
+ // why don't grace notes show up here?
+ // --> grace notes effectively do not get delayed
+ Moment now = now_mom ();
+ for (vsize i = 0; i < notes_.size (); i++)
+ play_element (notes_[i]);
notes_.clear ();
note_evs_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Drum_note_performer, note);
-void
-Drum_note_performer::listen_note (Stream_event *ev)
+bool
+Drum_note_performer::try_music (Music *ev)
{
- note_evs_.push_back (ev);
+ if (ev->is_mus_type ("note-event"))
+ {
+ note_evs_.push_back (ev);
+ return true;
+ }
+ else if (ev->is_mus_type ("busy-playing-event"))
+ return note_evs_.size ();
+
+ return false;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Drum_note_performer,
"Play drum notes.", "",
- "note-event", "", "");
+ "note-event busy-playing-event", "", "");
return scm_from_int (log);
}
-LY_DEFINE (ly_duration_length, "ly:duration-length",
- 1, 0, 0, (SCM dur),
- "The length of the duration as a Moment.")
-{
- SCM_ASSERT_TYPE (unsmob_duration (dur), dur, SCM_ARG1, __FUNCTION__, "duration");
- return Moment (unsmob_duration (dur)->get_length ()).smobbed_copy ();
-}
-
LY_DEFINE (ly_duration_factor, "ly:duration-factor",
1, 0, 0, (SCM dur),
"Extract the compression factor from @var{dur}. Return as a pair.")
#include "self-alignment-interface.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
Spanner *finished_line_spanner_;
Spanner *finished_cresc_;
- Stream_event *script_ev_;
- Stream_event *current_cresc_ev_;
+ Music *script_ev_;
+ Music *current_cresc_ev_;
- Drul_array<Stream_event *> accepted_spanevents_drul_;
+ Drul_array<Music *> accepted_spanevents_drul_;
vector<Note_column*> pending_columns_;
vector<Grob*> pending_elements_;
DECLARE_ACKNOWLEDGER (stem_tremolo);
DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (slur);
- DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
- DECLARE_TRANSLATOR_LISTENER (span_dynamic);
protected:
virtual void finalize ();
+ virtual bool try_music (Music *event);
void stop_translation_timestep ();
void process_music ();
};
accepted_spanevents_drul_[STOP] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, absolute_dynamic);
-void
-Dynamic_engraver::listen_absolute_dynamic (Stream_event *ev)
+bool
+Dynamic_engraver::try_music (Music *m)
{
- /*
- TODO: probably broken.
- */
- ASSIGN_EVENT_ONCE (script_ev_, ev);
-}
+ if (m->is_mus_type ("absolute-dynamic-event"))
+ {
+ /*
+ TODO: probably broken.
+ */
+ script_ev_ = m;
+ return true;
+ }
+ else if (m->is_mus_type ("decrescendo-event")
+ || m->is_mus_type ("crescendo-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, span_dynamic);
-void
-Dynamic_engraver::listen_span_dynamic (Stream_event *ev)
-{
- Direction d = to_dir (ev->get_property ("span-direction"));
-
- if (d == START)
- ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[START], ev);
-
- /* Cancel any ongoing crescendo, either explicitly by \! or
- implicitly by a new crescendo. Also avoid warning if cresc is
- cancelled both implicitly and explicitly. */
- if ((d == STOP || current_cresc_ev_) && !accepted_spanevents_drul_[STOP])
- ASSIGN_EVENT_ONCE (accepted_spanevents_drul_[STOP], ev);
+ accepted_spanevents_drul_[d] = m;
+ if (current_cresc_ev_ && d == START)
+ accepted_spanevents_drul_[STOP] = m;
+ return true;
+ }
+ return false;
}
void
{
if (!line_spanner_)
{
- Stream_event *rq = accepted_spanevents_drul_[START];
+ Music *rq = accepted_spanevents_drul_[START];
line_spanner_ = make_spanner ("DynamicLineSpanner", rq ? rq->self_scm () : SCM_EOL);
if (script_ev_)
rq = script_ev_;
Axis_group_interface::add_element (line_spanner_, script_);
}
- Stream_event *stop_ev = accepted_spanevents_drul_ [STOP]
+ Music *stop_ev = accepted_spanevents_drul_ [STOP]
? accepted_spanevents_drul_[STOP] : script_ev_;
if (accepted_spanevents_drul_[STOP] || script_ev_)
if (current_cresc_ev_)
{
string msg = _ ("already have a decrescendo");
- if (current_cresc_ev_->in_event_class ("crescendo-event"))
+ if (current_cresc_ev_->is_mus_type ("decrescendo-event"))
msg = _ ("already have a crescendo");
accepted_spanevents_drul_[START]->origin ()->warning (msg);
/*
TODO: Use symbols.
*/
+
+ string start_type
+ = ly_symbol2string (current_cresc_ev_->get_property ("name"));
- SCM start_sym = current_cresc_ev_->get_property ("class");
- string start_type;
-
- if (start_sym == ly_symbol2scm ("decrescendo-event"))
+ if (start_type == "DecrescendoEvent")
start_type = "decrescendo";
- else if (start_sym == ly_symbol2scm ("crescendo-event"))
+ else if (start_type == "CrescendoEvent")
start_type = "crescendo";
- else
- {
- programming_error ("unknown dynamic spanner type");
- return;
- }
+
+
/*
UGH. TODO: should read from original event, so appearance
ly_symbol2scm ("adjacent-hairpins"),
finished_cresc_);
}
+ cresc_->set_property ("grow-direction",
+ scm_from_int ((start_type == "crescendo")
+ ? BIGGER : SMALLER));
}
/*
#include "performer.hh"
#include "audio-item.hh"
-#include "stream-event.hh"
+#include "music.hh"
#include "translator.icc"
/*
public:
TRANSLATOR_DECLARATIONS (Dynamic_performer);
protected:
+ virtual bool try_music (Music *event);
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (absolute_dynamic);
private:
- Stream_event *script_event_;
+ Music *script_event_;
Audio_dynamic *audio_;
};
SCM s = get_property ("midiInstrument");
if (!scm_is_string (s))
- s = get_property ("instrumentName");
+ s = get_property ("instrument");
if (!scm_is_string (s))
s = scm_makfrom0str ("piano");
{
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_performer, absolute_dynamic);
-void
-Dynamic_performer::listen_absolute_dynamic (Stream_event *r)
+bool
+Dynamic_performer::try_music (Music *r)
{
if (!script_event_)
- script_event_ = r;
+ {
+ if (r->is_mus_type ("absolute-dynamic-event")) // fixme.
+ {
+ script_event_ = r;
+ return true;
+ }
+ }
+ return false;
}
ADD_TRANSLATOR (Dynamic_performer,
encl = -d;
}
- /*
- ugh - a special case.
- */
- if (d == RIGHT && me->get_property ("style") == ly_symbol2scm ("trill"))
- {
- pad = 2.0;
- encl = LEFT;
- }
-
Interval ext = b->extent (common, X_AXIS);
span_points[d] = -d * pad
+ robust_relative_extent (b, common, X_AXIS)
#include <cctype>
using namespace std;
-#include "font-interface.hh"
+#include "text-interface.hh"
#include "grob.hh"
-#include "music.hh"
#include "output-def.hh"
+#include "music.hh"
#include "pitch.hh"
+#include "font-interface.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
-#include "stream-event.hh"
-#include "text-interface.hh"
/*
int log = Note_head::get_balltype (me);
SCM cause = me->get_property ("cause");
- SCM spitch = unsmob_stream_event (cause)->get_property ("pitch");
+ SCM spitch = unsmob_music (cause)->get_property ("pitch");
Pitch *pit = unsmob_pitch (spitch);
SCM idx = scm_from_int (pit->get_notename ());
(c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "context.hh"
-#include "dispatcher.hh"
#include "engraver-group.hh"
-#include "grob.hh"
+
+#include "warn.hh"
#include "paper-score.hh"
-#include "stream-event.hh"
+#include "grob.hh"
+#include "context.hh"
#include "translator-dispatch-list.hh"
-#include "warn.hh"
-
-IMPLEMENT_LISTENER (Engraver_group, override);
-void
-Engraver_group::override (SCM sev)
-{
- Stream_event *ev = unsmob_stream_event (sev);
-
- execute_general_pushpop_property (context (),
- ev->get_property ("symbol"),
- ev->get_property ("property-path"),
- ev->get_property ("value"));
-}
-
-IMPLEMENT_LISTENER (Engraver_group, revert);
-void
-Engraver_group::revert (SCM sev)
-{
- Stream_event *ev = unsmob_stream_event (sev);
-
- execute_general_pushpop_property (context (),
- ev->get_property ("symbol"),
- ev->get_property ("property-path"),
- SCM_UNDEFINED);
-}
-
-void
-Engraver_group::connect_to_context (Context *c)
-{
- Translator_group::connect_to_context (c);
- c->event_source ()->add_listener (GET_LISTENER (override), ly_symbol2scm ("Override"));
- c->event_source ()->add_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert"));
-}
-
-void
-Engraver_group::disconnect_from_context ()
-{
- context ()->event_source ()->remove_listener (GET_LISTENER (override), ly_symbol2scm ("Override"));
- context ()->event_source ()->remove_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert"));
- Translator_group::disconnect_from_context ();
-}
void
Engraver_group::announce_grob (Grob_info info)
#include "engraver.hh"
-#include "context.hh"
-#include "international.hh"
-#include "item.hh"
-#include "lilypond-key.hh"
#include "music.hh"
-#include "paper-column.hh"
#include "score-engraver.hh"
-#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
+#include "spanner.hh"
+#include "item.hh"
+#include "context.hh"
+#include "score-context.hh"
+#include "lilypond-key.hh"
Engraver_group *
Engraver::get_daddy_engraver () const
}
/*
- CAUSE is the object (typically a Stream_event object) that
+ CAUSE is the object (typically a Music object) that
was the reason for making E.
*/
void
Engraver::announce_grob (Grob *e, SCM cause)
{
- /* TODO: Remove Music code when it's no longer needed */
- if (Music *m = unsmob_music (cause))
- {
- cause = m->to_event ()->unprotect ();
- }
- if (unsmob_stream_event (cause) || unsmob_grob (cause))
+ if (unsmob_music (cause) || unsmob_grob (cause))
e->set_property ("cause", cause);
Grob_info i (this, e);
void
Engraver::announce_end_grob (Grob *e, SCM cause)
{
- /* TODO: Remove Music code when it's no longer needed */
- if (Music *m = unsmob_music (cause))
- {
- cause = m->to_event ()->unprotect ();
- }
- if (unsmob_stream_event (cause) || unsmob_grob (cause))
+ if (unsmob_music (cause) || unsmob_grob (cause))
e->set_property ("cause", cause);
Grob_info i (this, e);
{
}
-#ifndef NDEBUG
-static SCM creation_callback = SCM_EOL;
-LY_DEFINE (ly_set_grob_creation_callback, "ly:set-grob-creation-callback",
- 1, 0, 0, (SCM cb),
- "Specify a procedure that will be called every time a new grob "
- "is created. The callback will receive as arguments the grob "
- "that was created, the name of the C++ source file that caused "
- "the grob to be created and the corresponding line number in the "
- "C++ source file.")
-{
- if (!ly_is_procedure (cb))
- warning (_ ("not setting creation callback: not a procedure"));
- else
- creation_callback = cb;
-
- return SCM_EOL;
-}
-#endif
-
-Grob *
-Engraver::internal_make_grob (SCM symbol, SCM cause, char const *name, char const *file, int line, char const *fun)
-{
- SCM props = updated_grob_properties (context (), symbol);
-
- Object_key const *key = context ()->get_grob_key (name);
- Grob *grob = 0;
-
- SCM handle = scm_sloppy_assq (ly_symbol2scm ("meta"), props);
- SCM klass = scm_cdr (scm_sloppy_assq (ly_symbol2scm ("class"), scm_cdr (handle)));
-
- if (klass == ly_symbol2scm ("Item"))
- grob = new Item (props, key);
- else if (klass == ly_symbol2scm ("Spanner"))
- grob = new Spanner (props, key);
- else if (klass == ly_symbol2scm ("Paper_column"))
- grob = new Paper_column (props, key);
-
- assert (grob);
- announce_grob (grob, cause);
-
-#ifndef NDEBUG
- if (ly_is_procedure (creation_callback))
- scm_apply_0 (creation_callback,
- scm_list_n (grob->self_scm (), scm_makfrom0str (file),
- scm_from_int (line), scm_makfrom0str (fun), SCM_UNDEFINED));
-#endif
-
- return grob;
-}
-
-Item *
-Engraver::internal_make_item (SCM x, SCM cause, char const *name, char const *file, int line, char const *fun)
-{
- Item *it = dynamic_cast<Item *> (internal_make_grob (x, cause, name, file, line, fun));
- assert (it);
- return it;
-}
-
-Paper_column *
-Engraver::internal_make_column (SCM x, char const *name, char const *file, int line, char const *fun)
-{
- return dynamic_cast<Paper_column *> (internal_make_grob (x, SCM_EOL, name, file, line, fun));
-}
-
-Spanner *
-Engraver::internal_make_spanner (SCM x, SCM cause, char const *name, char const *file, int line, char const *fun)
-{
- Spanner *sp = dynamic_cast<Spanner *> (internal_make_grob (x, cause, name, file, line, fun));
- assert (sp);
- return sp;
-}
-
#include "translator.icc"
ADD_TRANSLATOR (Engraver,
#include "event-chord-iterator.hh"
#include "context.hh"
-#include "dispatcher.hh"
#include "duration.hh"
#include "input.hh"
#include "international.hh"
#include "music.hh"
#include "pitch.hh"
-#include "stream-event.hh"
#include "warn.hh"
Event_chord_iterator::Event_chord_iterator ()
Music *mus = unsmob_music (scm_car (s));
report_event (mus);
}
- for (SCM s = get_music ()->get_property ("events");
- scm_is_pair (s); s = scm_cdr (s))
- {
- Stream_event *ev = unsmob_stream_event (scm_car (s));
- get_outlet ()->event_source ()->broadcast (ev);
- }
}
Simple_music_iterator::process (m);
}
#include "lyric-extender.hh"
#include "note-head.hh"
#include "pointer-group-interface.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
void completize_extender (Spanner *sp);
class Extender_engraver : public Engraver
{
- Stream_event *ev_;
+ Music *ev_;
Spanner *extender_;
Spanner *pending_extender_;
TRANSLATOR_DECLARATIONS (Extender_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (extender);
DECLARE_ACKNOWLEDGER (lyric_syllable);
virtual void finalize ();
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
};
ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver, extender);
-void
-Extender_engraver::listen_extender (Stream_event *ev)
+bool
+Extender_engraver::try_music (Music *r)
{
- ASSIGN_EVENT_ONCE (ev_, ev);
+ if (!ev_)
+ {
+ ev_ = r;
+ return true;
+ }
+ return false;
}
void
}
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable);
ADD_TRANSLATOR (Extender_engraver,
/* doc */ "Create lyric extenders",
+++ /dev/null
-/*
- fall-engraver.cc -- implement Bend_after_engraver
-
- (c) 2006 Han-Wen Nienhuys
-
-
-*/
-
-#include "engraver.hh"
-#include "item.hh"
-#include "moment.hh"
-#include "spanner.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
-
-class Bend_after_engraver : public Engraver
-{
-public:
- TRANSLATOR_DECLARATIONS (Bend_after_engraver);
- DECLARE_ACKNOWLEDGER (note_head);
-
-protected:
- DECLARE_TRANSLATOR_LISTENER (bend_after);
- void process_music ();
- void stop_translation_timestep ();
- void start_translation_timestep ();
- void stop_fall ();
-
-private:
- Moment stop_moment_;
- Stream_event *fall_event_;
- Spanner *fall_;
- Grob *note_head_;
-};
-
-void
-Bend_after_engraver::stop_fall ()
-{
- bool bar = scm_is_string (get_property ("whichBar"));
-
-
- fall_->set_bound (RIGHT, unsmob_grob (bar
- ? get_property ("currentCommandColumn")
- : get_property ("currentMusicalColumn")));
- fall_ = 0;
- note_head_ = 0;
- fall_event_ = 0;
-}
-
-void
-Bend_after_engraver::stop_translation_timestep ()
-{
- if (fall_ && !fall_->get_bound (LEFT))
- {
- fall_->set_bound (LEFT, note_head_);
- fall_->set_parent (note_head_, Y_AXIS);
- }
-}
-
-void
-Bend_after_engraver::start_translation_timestep ()
-{
- if (fall_ && now_mom ().main_part_ >= stop_moment_.main_part_)
- {
- stop_fall ();
- }
-}
-
-void
-Bend_after_engraver::acknowledge_note_head (Grob_info info)
-{
- if (!fall_event_)
- return;
-
- if (note_head_ && fall_)
- {
- stop_fall ();
- }
-
- note_head_ = info.grob ();
- stop_moment_ = now_mom () + get_event_length (info.event_cause ());
-}
-
-Bend_after_engraver::Bend_after_engraver ()
-{
- fall_ = 0;
- note_head_ = 0;
- fall_event_ = 0;
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Bend_after_engraver, bend_after);
-void
-Bend_after_engraver::listen_bend_after (Stream_event *ev)
-{
- ASSIGN_EVENT_ONCE (fall_event_, ev);
-}
-
-void
-Bend_after_engraver::process_music ()
-{
- if (fall_event_ && !fall_)
- {
- fall_ = make_spanner ("BendAfter", fall_event_->self_scm ());
- fall_->set_property ("delta-position",
- scm_from_double (robust_scm2double (fall_event_->get_property ("delta-step"), 0)));
- }
-}
-
-ADD_ACKNOWLEDGER (Bend_after_engraver, note_head);
-
-ADD_TRANSLATOR (Bend_after_engraver,
- /* doc */ "Create fall spanners.",
- /* create */ "BendAfter",
- /* accept */ "bend-after-event",
- /* read */ "",
- /* write */ "");
#include "engraver.hh"
-#include "align-interface.hh"
-#include "axis-group-interface.hh"
#include "context.hh"
-#include "grob-array.hh"
+#include "music.hh"
#include "item.hh"
-#include "pointer-group-interface.hh"
#include "spanner.hh"
-#include "stream-event.hh"
+#include "axis-group-interface.hh"
+#include "align-interface.hh"
+#include "pointer-group-interface.hh"
#include "text-interface.hh"
+#include "grob-array.hh"
+
#include "translator.icc"
SCM alteration_;
Item *figure_item_;
- Stream_event *current_event_;
+ Music *current_music_;
bool force_no_continuation_;
Figure_group ()
number_ = SCM_EOL;
alteration_ = SCM_EOL;
group_ = 0;
- current_event_ = 0;
+ current_music_ = 0;
}
bool is_continuation () const
{
return
- current_event_
+ current_music_
&& !force_no_continuation_
&& ly_is_equal (number_,
- current_event_->get_property ("figure"))
+ current_music_->get_property ("figure"))
&& ly_is_equal (alteration_,
- current_event_->get_property ("alteration"));
+ current_music_->get_property ("alteration"));
}
};
protected:
vector<Figure_group> groups_;
Spanner *alignment_;
- vector<Stream_event *> new_events_;
+ vector<Music*> new_musics_;
bool continuation_;
- bool new_event_found_;
+ bool new_music_found_;
Moment stop_moment_;
- Stream_event *rest_event_;
-
- DECLARE_TRANSLATOR_LISTENER (rest);
- DECLARE_TRANSLATOR_LISTENER (bass_figure);
-
+ Music *rest_event_;
+
+ virtual bool try_music (Music *);
virtual void derived_mark () const;
void start_translation_timestep ();
bool found = false;
for (vsize i = 0; !found && i < groups_.size (); i++)
- found = found || groups_[i].current_event_;
+ found = found || groups_[i].current_music_;
if (!found)
clear_spanners ();
alignment_ = 0;
continuation_ = false;
rest_event_ = 0;
- new_event_found_ = false;
+ new_music_found_ = false;
}
void
return ;
rest_event_ = 0;
- new_events_.clear ();
+ new_musics_.clear ();
for (vsize i = 0; i < groups_.size (); i++)
- groups_[i].current_event_ = 0;
-
+ groups_[i].current_music_ = 0;
continuation_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, rest);
-void
-Figured_bass_engraver::listen_rest (Stream_event *ev)
+bool
+Figured_bass_engraver::try_music (Music *m)
{
- if (to_boolean (get_property ("ignoreFiguredBassRest")))
+ new_music_found_ = true;
+ if (m->is_mus_type ("rest-event"))
{
- new_event_found_ = true;
- ASSIGN_EVENT_ONCE (rest_event_, ev);
+ rest_event_ = m;
+ return true;
}
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, bass_figure);
-void
-Figured_bass_engraver::listen_bass_figure (Stream_event *ev)
-{
- new_event_found_ = true;
- Moment stop = now_mom () + get_event_length (ev);
- stop_moment_ = max (stop_moment_, stop);
-
- SCM fig = ev->get_property ("figure");
- for (vsize i = 0; i < groups_.size (); i++)
+ else
{
- if (!groups_[i].current_event_
- && ly_is_equal (groups_[i].number_, fig))
+ stop_moment_ = now_mom () + m->get_length ();
+
+ SCM fig = m->get_property ("figure");
+ for (vsize i = 0; i < groups_.size (); i++)
{
- groups_[i].current_event_ = ev;
- groups_[i].force_no_continuation_
- = to_boolean (ev->get_property ("no-continuation"));
- continuation_ = true;
- return;
+ if (!groups_[i].current_music_
+ && ly_is_equal (groups_[i].number_, fig))
+ {
+ groups_[i].current_music_ = m;
+ groups_[i].force_no_continuation_
+ = to_boolean (m->get_property ("no-continuation"));
+ continuation_ = true;
+ return true;
+ }
}
+
+ new_musics_.push_back (m);
+
+ return true;
}
-
- new_events_.push_back (ev);
}
void
bool inside = false;
for (vsize i = 0; i < groups_.size (); i ++)
{
- if (!groups_[i].current_event_)
+ if (!groups_[i].current_music_)
continue;
- if (to_boolean (groups_[i].current_event_->get_property ("bracket-start")))
+ if (to_boolean (groups_[i].current_music_->get_property ("bracket-start")))
inside = true;
if (inside && groups_[i].figure_item_)
encompass.push_back (groups_[i].figure_item_);
- if (to_boolean (groups_[i].current_event_->get_property ("bracket-stop")))
+ if (to_boolean (groups_[i].current_music_->get_property ("bracket-stop")))
{
inside = false;
- Item * brack = make_item ("BassFigureBracket", groups_[i].current_event_->self_scm ());
+ Item * brack = make_item ("BassFigureBracket", groups_[i].current_music_->self_scm ());
for (vsize j = 0; j < encompass.size (); j++)
{
Pointer_group_interface::add_grob (brack,
}
if (!continuation_
- && new_events_.empty ())
+ && new_musics_.empty ())
{
clear_spanners ();
groups_.clear ();
return;
}
- if (!new_event_found_)
+ if (!new_music_found_)
return;
- new_event_found_ = false;
+ new_music_found_ = false;
/*
Don't need to sync alignments, if we're not using extenders.
}
vsize k = 0;
- for (vsize i = 0; i < new_events_.size (); i++)
+ for (vsize i = 0; i < new_musics_.size (); i++)
{
while (k < groups_.size ()
- && groups_[k].current_event_)
+ && groups_[k].current_music_)
k++;
if (k >= groups_.size ())
groups_.push_back (group);
}
- groups_[k].current_event_ = new_events_[i];
+ groups_[k].current_music_ = new_musics_[i];
groups_[k].figure_item_ = 0;
k++;
}
{
Figure_group &group = groups_[i];
- if (group.current_event_)
+ if (group.current_music_)
{
Item *item
= make_item ("BassFigure",
- group.current_event_->self_scm ());
+ group.current_music_->self_scm ());
- SCM fig = group.current_event_->get_property ("figure");
+ SCM fig = group.current_music_->get_property ("figure");
if (!group.group_)
{
group.group_ = make_spanner ("BassFigureLine", SCM_EOL);
}
group.number_ = fig;
- group.alteration_ = group.current_event_->get_property ("alteration");
+ group.alteration_ = group.current_music_->get_property ("alteration");
- SCM text = group.current_event_->get_property ("text");
+ SCM text = group.current_music_->get_property ("text");
if (!Text_interface::is_markup (text)
&& ly_is_procedure (proc))
{
- text = scm_call_3 (proc, fig, group.current_event_->self_scm (),
+ text = scm_call_3 (proc, fig, group.current_music_->self_scm (),
context ()->self_scm ());
}
"BassFigureLine "
,
/* accept */
- "bass-figure-event "
- "rest-event",
+ "bass-figure-event rest-event",
/* read */
"figuredBassAlterationDirection "
"figuredBassFormatter "
"implicitBassFigures "
"useBassFigureExtenders "
- "ignoreFiguredBassRest "
,
/* write */
#include "engraver.hh"
#include "context.hh"
+#include "music.hh"
#include "spanner.hh"
#include "side-position-interface.hh"
#include "translator.icc"
Spanner *bass_figure_alignment_;
Spanner *positioner_;
- vector<Grob*> support_;
- vector<Grob*> span_support_;
+ vector<Grob*> note_columns_;
+
protected:
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_ACKNOWLEDGER (slur);
- DECLARE_END_ACKNOWLEDGER (slur);
- DECLARE_ACKNOWLEDGER (tie);
DECLARE_ACKNOWLEDGER (bass_figure_alignment);
DECLARE_END_ACKNOWLEDGER (bass_figure_alignment);
void
Figured_bass_position_engraver::acknowledge_note_column (Grob_info info)
{
- support_.push_back (info.grob ());
-}
-
-void
-Figured_bass_position_engraver::acknowledge_end_slur (Grob_info info)
-{
- vector<Grob*>::iterator i = find (span_support_.begin (), span_support_.end (),
- info.grob ());
-
- if (i < span_support_.end ())
- span_support_.erase (i);
-}
-
-void
-Figured_bass_position_engraver::acknowledge_slur (Grob_info info)
-{
- span_support_.push_back (info.grob ());
-}
-
-void
-Figured_bass_position_engraver::acknowledge_tie (Grob_info info)
-{
- support_.push_back (info.grob ());
+ note_columns_.push_back (info.grob ());
}
void
{
if (positioner_)
{
- for (vsize i = 0; i < span_support_.size (); i++)
- Side_position_interface::add_support (positioner_, span_support_[i]);
- for (vsize i = 0; i < support_.size (); i++)
- Side_position_interface::add_support (positioner_, support_[i]);
+ for (vsize i = 0; i < note_columns_.size (); i++)
+ Side_position_interface::add_support (positioner_, note_columns_[i]);
}
- support_.clear ();
+ note_columns_.clear ();
}
void
ADD_ACKNOWLEDGER(Figured_bass_position_engraver,note_column);
-ADD_ACKNOWLEDGER(Figured_bass_position_engraver,slur);
-ADD_END_ACKNOWLEDGER(Figured_bass_position_engraver,slur);
-
-ADD_ACKNOWLEDGER(Figured_bass_position_engraver,tie);
ADD_ACKNOWLEDGER(Figured_bass_position_engraver,bass_figure_alignment);
ADD_END_ACKNOWLEDGER(Figured_bass_position_engraver,bass_figure_alignment);
*/
#include "engraver.hh"
-#include "pitch.hh"
-#include "rhythmic-head.hh"
-#include "self-alignment-interface.hh"
#include "side-position-interface.hh"
#include "stem.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
+#include "rhythmic-head.hh"
+#include "self-alignment-interface.hh"
+#include "pitch.hh"
class Fingering_engraver : public Engraver
{
- vector<Stream_event*> events_;
+ vector<Music*> events_;
vector<Item*> fingerings_;
public:
TRANSLATOR_DECLARATIONS (Fingering_engraver);
protected:
+ virtual bool try_music (Music *m);
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (fingering);
DECLARE_ACKNOWLEDGER (rhythmic_head);
DECLARE_ACKNOWLEDGER (stem);
private:
- void make_script (Direction, Stream_event *, int);
+ void make_script (Direction, Music *, int);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Fingering_engraver, fingering);
-void
-Fingering_engraver::listen_fingering (Stream_event *ev)
+bool
+Fingering_engraver::try_music (Music *m)
{
- events_.push_back (ev);
+ if (m->is_mus_type ("fingering-event"))
+ {
+ events_.push_back (m);
+ return true;
+ }
+ return false;
}
void
}
void
-Fingering_engraver::make_script (Direction d, Stream_event *r, int i)
+Fingering_engraver::make_script (Direction d, Music *r, int i)
{
Item *fingering = make_item ("Fingering", r->self_scm ());
fingering->set_property ("direction", scm_from_int (RIGHT));
}
+ SCM dig = r->get_property ("digit");
+ fingering->set_property ("text", scm_number_to_string (dig, scm_from_int (10)));
+
fingerings_.push_back (fingering);
}
{
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head);
ADD_ACKNOWLEDGER (Fingering_engraver, stem);
ADD_TRANSLATOR (Fingering_engraver,
*/
Simultaneous_music_iterator *s = new Simultaneous_music_iterator;
s->create_separate_contexts_ = true;
- s->init_context (mus, get_outlet ());
+ s->init_translator (mus, get_outlet ());
alternative_iter_ = s;
alternative_iter_->construct_children ();
font_config_global = FcInitLoadConfig ();
FcChar8 *cache_file = FcConfigGetCache (font_config_global);
-#if 0
- // always returns 0 for FC 2.4
- if (!cache_file)
- programming_error ("Cannot find file for FontConfig cache.");
-#endif
/*
This is a terrible kludge, but there is apparently no way for
FontConfig to signal whether it needs to rescan directories.
*/
- if (cache_file
- && !is_file ((char const *)cache_file))
- message (_f ("Rebuilding FontConfig cache %s, this may take a while...", cache_file));
+ if (!is_file ((char*)cache_file))
+ message (_f ("Rebuilding FontConfig cache %s. this may take a while...", cache_file));
vector<string> dirs;
{
string dir = dirs[i];
if (!FcConfigAppFontAddDir (font_config_global, (FcChar8 *)dir.c_str ()))
- error (_f ("failed adding font directory: %s", dir.c_str ()));
+ error (_f ("adding font directory: %s", dir.c_str ()));
else if (be_verbose_global)
message (_f ("adding font directory: %s", dir.c_str ()));
}
if (be_verbose_global)
progress_indication ("\n");
- if (cache_file
- && !is_file ((char*)cache_file))
+ if (!is_file ((char*)cache_file))
{
/* inhibit future messages. */
FILE *f = fopen ((char*)cache_file, "w");
(c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "warn.hh"
#include "stencil.hh"
#include "font-metric.hh"
#include "modified-font-metric.hh"
Font_metric *fm = unsmob_metrics (font);
SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG2, __FUNCTION__, "string");
-
+#if 1
return scm_from_unsigned_integer (fm->index_to_charcode (fm->name_to_index (ly_scm2string (name))));
+#else
+ return scm_from_unsigned_integer (fm->glyph_name_to_charcode (ly_scm2string (name)));
+#endif
}
LY_DEFINE (ly_text_dimension, "ly:text-dimension",
ly_interval2scm (stc.extent (Y_AXIS)));
}
-
-/*
- TODO: when are non string retvals allowed?
- */
LY_DEFINE (ly_font_file_name, "ly:font-file-name",
1, 0, 0,
(SCM font),
{
Font_metric *fm = unsmob_metrics (font);
SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
- SCM name = fm->font_file_name ();
-
- return name;
+ return fm->font_file_name ();
}
LY_DEFINE (ly_font_name, "ly:font-name",
return SCM_EOL;
}
-Stencil
-Font_metric::word_stencil (string str) const
-{
- return text_stencil (str);
-}
-
Stencil
Font_metric::text_stencil (string str) const
{
(c) 2002--_2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "context.hh"
#include "duration.hh"
-#include "engraver.hh"
#include "grob.hh"
+#include "engraver.hh"
#include "input.hh"
#include "moment.hh"
#include "pitch.hh"
#include "rhythmic-head.hh"
+#include "score-context.hh"
#include "translator.icc"
freopen (ly_scm2newstr (file_name, 0), m, stderr);
return SCM_UNSPECIFIED;
}
-
-static SCM
-accumulate_symbol (void *closure, SCM key, SCM val, SCM result)
-{
- (void) closure;
- (void) val;
- return scm_cons (key, result);
-}
-
-LY_DEFINE(ly_hash_table_keys, "ly:hash-table-keys",
- 1,0,0, (SCM tab),
- "return a list of keys in @var{tab}")
-{
- return scm_internal_hash_fold ((Hash_closure_function) & accumulate_symbol,
- NULL, SCM_EOL, tab);
-}
#include "international.hh"
#include "rhythmic-head.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
/**
Create line-spanner grobs for glissandi lines that connect note
heads.
TRANSLATOR_DECLARATIONS (Glissando_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (glissando);
DECLARE_ACKNOWLEDGER (rhythmic_head);
virtual void finalize ();
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
private:
Spanner *line_;
Spanner *last_line_;
- Stream_event *event_;
+ Music *event_;
};
Glissando_engraver::Glissando_engraver ()
event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Glissando_engraver, glissando);
-void
-Glissando_engraver::listen_glissando (Stream_event *ev)
+bool
+Glissando_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ if (!event_)
+ {
+ event_ = m;
+ return true;
+ }
+ return false;
}
void
}
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Glissando_engraver, rhythmic_head);
ADD_TRANSLATOR (Glissando_engraver,
/* doc */ "Engrave a glissandi",
(c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
+
#include "cpu-timer.hh"
#include "global-context.hh"
#include "international.hh"
#include "music.hh"
#include "object-key.hh"
#include "output-def.hh"
-#include "translator-group.hh"
#include "warn.hh"
LY_DEFINE (ly_format_output, "ly:format-output",
SCM output = g->get_output ();
progress_indication ("\n");
-
- if (Music_output *od = unsmob_music_output (output))
- od->process ();
-
+ unsmob_music_output (output)->process ();
return output;
}
-LY_DEFINE (ly_make_global_translator, "ly:make-global-translator",
- 1, 0, 0, (SCM global),
- "Create a translator group and connect it to the global context\n"
- "@var{global}. The translator group is returned.")
-{
- Global_context *g = dynamic_cast<Global_context *> (unsmob_context (global));
- SCM_ASSERT_TYPE (g, global, SCM_ARG1, __FUNCTION__, "Global context");
-
- Translator_group *tg = new Translator_group ();
- tg->connect_to_context (g);
- g->implementation_ = tg;
-
- return tg->unprotect ();
-}
-
-LY_DEFINE (ly_make_global_context, "ly:make-global-context",
- 1, 1, 0, (SCM output_def, SCM key),
- "Set up a global interpretation context, using the output\n"
- "block @var{output_def}.\n"
- "The context is returned.\n"
-
- "\n\nOptionally, this routine takes an Object-key to\n"
+LY_DEFINE (ly_run_translator, "ly:run-translator",
+ 2, 1, 0, (SCM mus, SCM output_def, SCM key),
+ "Process @var{mus} according to @var{output_def}. \n"
+ "An interpretation context is set up,\n"
+ "and @var{mus} is interpreted with it. \n"
+ "The context is returned in its final state.\n"
+ "\n\n"
+ "Optionally, this routine takes an Object-key to\n"
"to uniquely identify the Score block containing it.\n")
{
Output_def *odef = unsmob_output_def (output_def);
-
- SCM_ASSERT_TYPE (odef, output_def, SCM_ARG1, __FUNCTION__,
- "Output definition");
-
- Global_context *glob = new Global_context (odef, unsmob_key (key));
-
- if (!glob)
- {
- programming_error ("no toplevel translator");
- return SCM_BOOL_F;
- }
-
- return glob->unprotect ();
-}
-
-LY_DEFINE (ly_interpret_music_expression, "ly:interpret-music-expression",
- 2, 0, 0, (SCM mus, SCM ctx),
- "Interpret the music expression @var{mus} in the\n"
- "global context @var{ctx}. The context is returned in its\n"
- "final state.\n")
-{
Music *music = unsmob_music (mus);
- Global_context *g = dynamic_cast<Global_context *> (unsmob_context (ctx));
- SCM_ASSERT_TYPE (music, mus, SCM_ARG1, __FUNCTION__, "Music");
- SCM_ASSERT_TYPE (g, ctx, SCM_ARG2, __FUNCTION__, "Global context");
if (!music
|| !music->get_length ().to_bool ())
return SCM_BOOL_F;
}
+ SCM_ASSERT_TYPE (music, mus, SCM_ARG1, __FUNCTION__, "Music");
+ SCM_ASSERT_TYPE (odef, output_def, SCM_ARG2, __FUNCTION__,
+ "Output definition");
+
Cpu_timer timer;
+ Global_context *trans = new Global_context (odef, music->get_length (),
+ unsmob_key (key));
+ if (!trans)
+ {
+ programming_error ("no toplevel translator");
+ return SCM_BOOL_F;
+ }
+
message (_ ("Interpreting music... "));
SCM protected_iter = Music_iterator::get_static_get_iterator (music);
Music_iterator *iter = unsmob_iterator (protected_iter);
-
- iter->init_context (music, g);
+ iter->init_translator (music, trans);
iter->construct_children ();
if (!iter->ok ())
return SCM_BOOL_F;
}
- g->run_iterator_on_me (iter);
-
+ trans->run_iterator_on_me (iter);
iter->quit ();
scm_remember_upto_here_1 (protected_iter);
-
- send_stream_event (g, "Finish", 0, 0);
+ trans->finish ();
if (be_verbose_global)
message (_f ("elapsed time: %.2f seconds", timer.read ()));
- return ctx;
-}
-
-LY_DEFINE (ly_run_translator, "ly:run-translator",
- 2, 1, 0, (SCM mus, SCM output_def, SCM key),
- "Process @var{mus} according to @var{output_def}. \n"
- "An interpretation context is set up,\n"
- "and @var{mus} is interpreted with it. \n"
- "The context is returned in its final state.\n"
- "\n\n"
- "Optionally, this routine takes an Object-key to\n"
- "to uniquely identify the Score block containing it.\n")
-{
- SCM glob = ly_make_global_context (output_def, key);
- ly_make_global_translator (glob);
- ly_interpret_music_expression (mus, glob);
- return glob;
+ return trans->unprotect ();
}
using namespace std;
#include "context-def.hh"
-#include "dispatcher.hh"
#include "international.hh"
#include "lilypond-key.hh"
#include "music-iterator.hh"
#include "music.hh"
#include "output-def.hh"
-#include "stream-event.hh"
+#include "score-context.hh"
#include "warn.hh"
-Global_context::Global_context (Output_def *o, Object_key *key)
+Global_context::Global_context (Output_def *o, Moment final, Object_key *key)
: Context (new Lilypond_context_key (key,
Moment (0),
"Global", "", 0))
{
output_def_ = o;
+ final_mom_ = final;
definition_ = find_context_def (o, ly_symbol2scm ("Global"));
-
- now_mom_.set_infinite (-1);
- prev_mom_.set_infinite (-1);
-
- /* We only need the most basic stuff to bootstrap the context tree */
- event_source ()->add_listener (GET_LISTENER (create_context_from_event),
- ly_symbol2scm ("CreateContext"));
- event_source ()->add_listener (GET_LISTENER (prepare),
- ly_symbol2scm ("Prepare"));
- events_below ()->register_as_listener (event_source_);
+ unique_count_ = 0;
+ unique_ = 0;
Context_def *globaldef = unsmob_context_def (definition_);
if (!globaldef)
void
Global_context::add_moment_to_process (Moment m)
{
+ if (m > final_mom_)
+ return;
+
if (m < now_mom_)
programming_error ("trying to freeze in time");
return extra_mom_pq_.size ();
}
-IMPLEMENT_LISTENER (Global_context, prepare);
void
-Global_context::prepare (SCM sev)
+Global_context::prepare (Moment m)
{
- Stream_event *ev = unsmob_stream_event (sev);
- Moment *mom = unsmob_moment (ev->get_property ("moment"));
-
- assert (mom);
+ prev_mom_ = now_mom_;
+ now_mom_ = m;
- if (prev_mom_.main_part_.is_infinity () && prev_mom_ < 0)
- prev_mom_ = *mom;
- else
- prev_mom_ = now_mom_;
- now_mom_ = *mom;
-
clear_key_disambiguations ();
+ if (get_score_context ())
+ get_score_context ()->prepare (m);
}
Moment
return now_mom_;
}
-Context *
+Score_context *
Global_context::get_score_context () const
{
return (scm_is_pair (context_list_))
- ? unsmob_context (scm_car (context_list_))
+ ? dynamic_cast<Score_context *> (unsmob_context (scm_car (context_list_)))
: 0;
}
SCM
Global_context::get_output ()
{
- Context * c = get_score_context ();
- if (c)
- return c->get_property ("output");
- else
- return SCM_EOL;
+ return get_score_context ()->get_output ();
+}
+
+void
+Global_context::one_time_step ()
+{
+ get_score_context ()->one_time_step ();
+ apply_finalizations ();
+ check_removal ();
+}
+
+void
+Global_context::finish ()
+{
+ if (get_score_context ())
+ get_score_context ()->finish ();
}
void
Global_context::run_iterator_on_me (Music_iterator *iter)
{
- prev_mom_.set_infinite (-1);
- now_mom_.set_infinite (-1);
- Moment final_mom = iter->get_music ()->get_length ();
+ if (iter->ok ())
+ prev_mom_ = now_mom_ = iter->pending_moment ();
bool first = true;
while (iter->ok () || get_moments_left ())
w = iter->pending_moment ();
w = sneaky_insert_extra_moment (w);
- if (w.main_part_.is_infinity () || w > final_mom)
+ if (w.main_part_.is_infinity ())
break;
- if (w == prev_mom_)
- {
- programming_error ("Moment is not increasing. Aborting interpretation.");
- break ;
- }
-
-
if (first)
{
/*
set_property ("measurePosition", w.smobbed_copy ());
}
- send_stream_event (this, "Prepare", 0,
- ly_symbol2scm ("moment"), w.smobbed_copy ());
+ prepare (w);
if (iter->ok ())
iter->process (w);
- send_stream_event (this, "OneTimeStep", 0, 0);
- apply_finalizations ();
- check_removal ();
+ if (!get_score_context ())
+ {
+ SCM sym = ly_symbol2scm ("Score");
+ Context_def *t = unsmob_context_def (find_context_def (get_output_def (),
+ sym));
+ if (!t)
+ error (_f ("can't find `%s' context", "Score"));
+
+ Object_key const *key = get_context_key ("Score", "");
+ Context *c = t->instantiate (SCM_EOL, key);
+ add_context (c);
+
+ Score_context *sc = dynamic_cast<Score_context *> (c);
+ sc->prepare (w);
+ }
+
+ one_time_step ();
}
}
else
return Context::get_default_interpreter ();
}
+
+int
+Global_context::new_unique ()
+{
+ return ++unique_count_;
+}
--- /dev/null
+/*
+ gourlay-breaking.cc -- implement Gourlay_breaking
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "gourlay-breaking.hh"
+
+#include <cmath> // rint
+#include <cstdio>
+using namespace std;
+
+#include "international.hh"
+#include "main.hh"
+#include "output-def.hh"
+#include "paper-column.hh"
+#include "paper-score.hh"
+#include "simple-spacer.hh"
+#include "system.hh"
+#include "warn.hh"
+
+/// How often to print operator pacification marks?
+const int HAPPY_DOTS = 3;
+
+/**
+ Helper to trace back an optimal path
+*/
+struct Break_node
+{
+ /** this was the previous. If negative, this break should not be
+ considered: this path has infinite energy
+
+ */
+ int prev_break_;
+ /**
+ Which system number so far?
+ */
+ int line_;
+
+ Real demerits_;
+ Column_x_positions line_config_;
+
+ Break_node ()
+ {
+ prev_break_ = -1;
+ line_ = 0;
+ demerits_ = 0;
+ }
+
+ void print () const
+ {
+ printf ("prev break %d, line %d, demerits %f\n",
+ prev_break_, line_, demerits_);
+ }
+};
+
+void
+print_break_nodes (vector<Break_node> const &arr)
+{
+ for (vsize i = 0; i < arr.size (); i++)
+ {
+ printf ("node %d: ", i);
+ arr[i].print ();
+ }
+}
+
+/**
+ This algorithms is adapted from the OSU Tech report on breaking lines.
+
+ this function is longish, but not very complicated.
+
+ TODO: should rewrite. See the function in scm/page-layout.scm for
+ inspiration.
+*/
+vector<Column_x_positions>
+Gourlay_breaking::solve ()
+{
+ vector<Break_node> optimal_paths;
+ vector<Grob*> all
+ = pscore_->root_system ()->columns ();
+
+ vector<vsize> breaks = pscore_->find_break_indices ();
+
+ Break_node first_node;
+ optimal_paths.push_back (first_node);
+
+ bool ragged_right = to_boolean (pscore_->layout ()->c_variable ("ragged-right"));
+ bool ragged_last = to_boolean (pscore_->layout ()->c_variable ("ragged-last"));
+
+ Real worst_force = 0.0;
+ for (vsize break_idx = 1; break_idx < breaks.size (); break_idx++)
+ {
+ /*
+ start with a short line, add measures. At some point
+ the line becomes infeasible. Then we don't try to add more
+ */
+ int minimal_start_idx = -1;
+ Column_x_positions minimal_sol;
+ Column_x_positions backup_sol;
+
+ Real minimal_demerits = infinity_f;
+
+ for (vsize start_idx = break_idx; start_idx--;)
+ {
+ vector<Grob*> line (all.begin () + breaks[start_idx],
+ all.begin () + breaks[break_idx] + 1);
+
+ Interval line_dims
+ = line_dimensions_int (pscore_->layout (), optimal_paths[start_idx].line_);
+ bool last_line = break_idx == breaks.size () - 1;
+ bool ragged = ragged_right || (last_line && ragged_last);
+
+ Column_x_positions cp = get_line_configuration (line, line_dims[RIGHT] - line_dims[LEFT],
+ line_dims[LEFT], ragged);
+ if (ragged && last_line)
+ cp.force_ = 0.0;
+
+ if (fabs (cp.force_) > worst_force)
+ worst_force = fabs (cp.force_);
+
+ /*
+ We remember this solution as a "should always work
+ solution", in case everything fucks up. */
+ if (start_idx == break_idx - 1)
+ backup_sol = cp;
+
+ Real this_demerits;
+
+ if (optimal_paths[start_idx].demerits_ >= infinity_f)
+ this_demerits = infinity_f;
+ else
+ this_demerits = combine_demerits (optimal_paths[start_idx].line_config_, cp)
+ + optimal_paths[start_idx].demerits_;
+
+ if (this_demerits < minimal_demerits)
+ {
+ minimal_start_idx = start_idx;
+ minimal_sol = cp;
+ minimal_demerits = this_demerits;
+ }
+
+ /*
+ we couldn't satisfy the constraints, this won't get better
+ if we add more columns, so we get on with the next one
+ */
+ if (!cp.satisfies_constraints_)
+ break;
+ }
+
+ Break_node bnod;
+ if (minimal_start_idx < 0)
+ {
+ bnod.demerits_ = infinity_f;
+ bnod.line_config_ = backup_sol;
+ bnod.prev_break_ = break_idx - 1;
+ }
+ else
+ {
+ bnod.prev_break_ = minimal_start_idx;
+ bnod.demerits_ = minimal_demerits;
+ bnod.line_config_ = minimal_sol;
+ }
+ bnod.line_ = optimal_paths[bnod.prev_break_].line_ + 1;
+ optimal_paths.push_back (bnod);
+
+ if (! (break_idx % HAPPY_DOTS))
+ progress_indication (string ("[") + to_string (break_idx) + "]");
+ }
+
+ /* do the last one */
+ if (breaks.size () % HAPPY_DOTS)
+ progress_indication (string ("[") + to_string (breaks.size ()) + "]");
+
+ progress_indication ("\n");
+
+ vector<int> final_breaks;
+ vector<Column_x_positions> lines;
+
+ /* skip 0-th element, since it is a "dummy" elt*/
+ for (vsize i = optimal_paths.size () - 1; i > 0;)
+ {
+ final_breaks.push_back (i);
+ vsize prev = optimal_paths[i].prev_break_;
+ assert (i > prev);
+ i = prev;
+ }
+
+ if (be_verbose_global)
+ {
+ message (_f ("Optimal demerits: %f",
+ optimal_paths.back ().demerits_) + "\n");
+ }
+
+ if (optimal_paths.back ().demerits_ >= infinity_f)
+ warning (_ ("no feasible line breaking found"));
+
+ for (vsize i = final_breaks.size (); i--;)
+ {
+ Column_x_positions cp (optimal_paths[final_breaks[i]].line_config_);
+
+ lines.push_back (cp);
+ if (!cp.satisfies_constraints_)
+ warning (_ ("can't find line breaking that satisfies constraints"));
+ }
+ return lines;
+}
+
+Gourlay_breaking::Gourlay_breaking ()
+{
+}
+
+/*
+ TODO: uniformity parameter to control rel. importance of spacing differences.
+
+ TODO:
+
+ mixing break penalties and constraint-failing solutions is confusing.
+*/
+Real
+Gourlay_breaking::combine_demerits (Column_x_positions const &prev,
+ Column_x_positions const &this_one) const
+{
+ Real break_penalties = 0.0;
+ Grob *pc = this_one.cols_.back ();
+ if (pc->original ())
+ {
+ SCM pen = pc->get_property ("line-break-penalty");
+ if (scm_is_number (pen) && fabs (scm_to_double (pen)) < 10000)
+ break_penalties += scm_to_double (pen);
+ }
+
+ /*
+ Q: do we want globally non-cramped lines, or locally equally
+ cramped lines?
+
+ There used to be an example file input/test/uniform-breaking to
+ demonstrate problems with this approach. When music is gradually
+ becoming denser, the uniformity requirement makes lines go from
+ cramped to even more cramped (because going from cramped
+ 3meas/line to relatively loose 2meas/line is such a big step.
+
+ */
+
+ Real demerit = abs (this_one.force_) + abs (prev.force_ - this_one.force_)
+ + break_penalties;
+
+ if (!this_one.satisfies_constraints_)
+ {
+ /*
+ If it doesn't satisfy constraints, we make this one
+ really unattractive.
+
+ add 20000 to the demerits, so that a break penalty
+ of -10000 won't change the result */
+ demerit = max ((demerit + 20000), 2000.0);
+
+ demerit *= 10;
+ }
+
+ return demerit;
+}
+
+++ /dev/null
-/*
- grace-spacing-engraver.cc -- implement Grace_spacing_engraver
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Han-Wen <hanwen@lilypond.org>
-
-*/
-
-#include "engraver.hh"
-#include "moment.hh"
-#include "pointer-group-interface.hh"
-#include "spanner.hh"
-
-#include "translator.icc"
-
-class Grace_spacing_engraver : public Engraver
-{
- TRANSLATOR_DECLARATIONS (Grace_spacing_engraver);
-
-protected:
-
- Moment last_moment_;
- Spanner *grace_spacing_;
-
- void process_music ();
- void stop_translation_timestep ();
-};
-
-
-Grace_spacing_engraver::Grace_spacing_engraver ()
-{
- grace_spacing_ = 0;
-}
-
-void
-Grace_spacing_engraver::process_music ()
-{
- Moment now = now_mom ();
- if (!last_moment_.grace_part_ and now.grace_part_)
- {
- grace_spacing_ = make_spanner ("GraceSpacing", SCM_EOL);
- }
-
-
- if (grace_spacing_ && (now.grace_part_ || last_moment_.grace_part_))
- {
- Grob *column = unsmob_grob (get_property ("currentMusicalColumn"));
- Pointer_group_interface::add_grob (grace_spacing_,
- ly_symbol2scm ("columns"),
- column);
-
- column->set_object ("grace-spacing", grace_spacing_->self_scm ());
- }
-}
-
-void
-Grace_spacing_engraver::stop_translation_timestep ()
-{
- last_moment_ = now_mom ();
-
- if (!last_moment_.grace_part_)
- grace_spacing_ = 0;
-}
-
-
-ADD_TRANSLATOR (Grace_spacing_engraver,
- "Bookkeeping of shortest starting and playing notes in grace note runs.",
-
- /* create */
- "GraceSpacing ",
-
- /* accept */
- "",
-
- /* read */
- "currentMusicalColumn ",
-
- /* write */ "");
#include "pitch.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "warn.hh"
-/* ASSIGN_EVENT_ONCE */
-#include "translator.icc"
-
/*
* This abstract class is the common superclass for all ligature
* engravers for Gregorian chant notation. It cares for the musical
pes_or_flexa_req_ = 0;
}
-void
-Gregorian_ligature_engraver::listen_pes_or_flexa (Stream_event *ev)
+bool
+Gregorian_ligature_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (pes_or_flexa_req_, ev);
+ if (m->is_mus_type ("pes-or-flexa-event"))
+ {
+ pes_or_flexa_req_ = m;
+ return true;
+ }
+ else
+ return Ligature_engraver::try_music (m);
}
void fix_prefix (char *name, int mask,
for (vsize i = 0; i < primitives.size (); i++)
{
Grob *primitive = primitives[i].grob ();
- Stream_event *event_cause = primitives[i].event_cause ();
+ Music *music_cause = primitives[i].music_cause ();
int context_info = 0;
- int pitch = unsmob_pitch (event_cause->get_property ("pitch"))->steps ();
+ int pitch = unsmob_pitch (music_cause->get_property ("pitch"))->steps ();
int prefix_set = scm_to_int (primitive->get_property ("prefix-set"));
if (prefix_set & PES_OR_FLEXA)
{
assert (!ordered_);
- vector_sort (grobs_, less<Grob*> ());
+ vector_sort (grobs_, default_compare);
::uniq (grobs_);
}
&& !ly_is_procedure (data)
&& !is_simple_closure (data))
{
- g->set_property (axis_offset_symbol (a), proc);
+ g->internal_set_property (axis_offset_symbol (a),
+ proc);
return ;
}
proc = ly_make_simple_closure (scm_list_1 (proc));
SCM expr = scm_list_3 (plus, proc, data);
- g->set_property (axis_offset_symbol (a), ly_make_simple_closure (expr));
+ g->internal_set_property (axis_offset_symbol (a),
+ ly_make_simple_closure (expr));
}
data = ly_make_simple_closure (scm_list_1 (data));
else if (is_simple_closure (data))
data = simple_closure_expression (data);
- else
- /*
- Data may be nonnumber. In that case, it is assumed to be
- undefined.
- */
-
- data = SCM_UNDEFINED;
-
+ else if (!scm_is_number (data))
+ data = scm_from_int (0);
+
SCM expr = scm_list_2 (proc, data);
- g->set_property (axis_offset_symbol (a),
-
- // twice: one as a wrapper for grob property routines,
- // once for the actual delayed binding.
- ly_make_simple_closure (ly_make_simple_closure (expr)));
+ g->internal_set_property (axis_offset_symbol (a),
+
+ // twice: one as a wrapper for grob property routines,
+ // once for the actual delayed binding.
+ ly_make_simple_closure (ly_make_simple_closure (expr)));
}
(c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "context.hh"
#include "grob-info.hh"
#include "grob.hh"
-#include "item.hh"
#include "music.hh"
-#include "spanner.hh"
-#include "stream-event.hh"
#include "translator-group.hh"
+#include "context.hh"
+#include "spanner.hh"
+#include "item.hh"
Grob_info::Grob_info (Translator *t, Grob *g)
{
origin_trans_ = 0;
}
-Stream_event *
-Grob_info::event_cause () const
+Music *
+Grob_info::music_cause () const
{
SCM cause = grob_->get_property ("cause");
- return unsmob_stream_event (cause);
+ return unsmob_music (cause);
}
vector<Context*>
return dynamic_cast<Item *> (grob_);
}
-Stream_event *
-Grob_info::ultimate_event_cause () const
+Music *
+Grob_info::ultimate_music_cause () const
{
SCM cause = grob_->self_scm ();
while (unsmob_grob (cause))
{
cause = unsmob_grob (cause)->get_property ("cause");
}
- return unsmob_stream_event (cause);
+
+ return unsmob_music (cause);
}
+
{
Grob *grob_;
Moment end_;
+ static int compare (Grob_pq_entry const &a,
+ Grob_pq_entry const &b)
+ {
+ return Moment::compare (a.end_, b.end_);
+ }
};
-bool
-operator< (Grob_pq_entry const &a, Grob_pq_entry const &b)
-{
- return a.end_ < b.end_;
-}
-
class Grob_pq_engraver : public Engraver
{
public:
void
Grob_pq_engraver::acknowledge_grob (Grob_info gi)
{
- Stream_event *ev = gi.event_cause ();
+ Music *m = gi.music_cause ();
- if (ev
+ if (m
&& !gi.grob ()->internal_has_interface (ly_symbol2scm ("multi-measure-interface")))
{
Moment n = now_mom ();
- Moment l = get_event_length (ev);
+ Moment l = m->get_length ();
if (!l.to_bool ())
return;
while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) == now)
busy = scm_cdr (busy);
- vector_sort (started_now_, less<Grob_pq_entry> ());
+ vector_sort (started_now_, Grob_pq_entry::compare);
SCM lst = SCM_EOL;
SCM *tail = &lst;
for (vsize i = 0; i < started_now_.size (); i++)
#include <cstring>
#include "main.hh"
-#include "input.hh"
+#include "input-smob.hh"
#include "pointer-group-interface.hh"
#include "misc.hh"
#include "paper-score.hh"
#include "output-def.hh"
#include "spanner.hh"
-#include "international.hh"
#include "item.hh"
#include "misc.hh"
#include "item.hh"
#include "program-option.hh"
#include "profile.hh"
#include "simple-closure.hh"
-#include "warn.hh"
-
-#ifndef NDEBUG
-static SCM modification_callback = SCM_EOL;
-
-LY_DEFINE (ly_set_grob_modification_callback, "ly:set-grob-modification-callback",
- 1, 0, 0, (SCM cb),
- "Specify a procedure that will be called every time lilypond modifies "
- "a grob property. The callback will receive as arguments "
- "the grob that is being modified, the name of the C++ file in which "
- "the modification was requested, the line number in the C++ file in "
- "which the modification was requested, the property to be changed and "
- "the new value for the property.")
-{
- if (!ly_is_procedure (cb))
- warning (_ ("not setting modification callback: not a procedure"));
- else
- modification_callback = cb;
- return SCM_EOL;
-}
-#endif
SCM
Grob::get_property_alist_chain (SCM def) const
extern void check_interfaces_for_property (Grob const *me, SCM sym);
void
-#ifndef NDEBUG
-Grob::internal_set_property (SCM sym, SCM v, char const *file, int line, char const *fun)
+Grob::internal_set_property (SCM sym, SCM v)
{
+#ifndef NDEBUG
SCM grob_p = ly_lily_module_constant ("ly:grob?");
SCM grob_list_p = ly_lily_module_constant ("grob-list?");
SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?"));
scm_display (scm_list_2 (sym, type), scm_current_output_port ());
assert (0);
}
-#else
-Grob::internal_set_property (SCM sym, SCM v)
-{
#endif
/* Perhaps we simply do the assq_set, but what the heck. */
check_interfaces_for_property (this, sym);
}
-#ifndef NDEBUG
- if (ly_is_procedure (modification_callback))
- scm_apply_0 (modification_callback,
- scm_list_n (self_scm (),
- scm_makfrom0str (file),
- scm_from_int (line),
- scm_makfrom0str (fun),
- sym, v, SCM_UNDEFINED));
-#endif
-
mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, v);
}
mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, marker);
}
else
- set_property (sym, value);
+ internal_set_property (sym, value);
return value;
}
}
void
-Grob::internal_del_property (SCM sym)
+Grob::del_property (SCM sym)
{
mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, sym);
}
bool
Grob::is_live () const
{
- return scm_is_pair (immutable_property_alist_);
+ return immutable_property_alist_ != SCM_EOL;
}
&& !type_check_assignment (sym, val, ly_symbol2scm ("backend-type?")))
error ("typecheck failed");
- sc->set_property (sym, val);
+ sc->internal_set_property (sym, val);
return SCM_UNSPECIFIED;
}
return ly_interval2scm (sc->extent (ref, a));
}
-LY_DEFINE (ly_grob_robust_relative_extent, "ly:grob-robust-relative-extent",
- 3, 0, 0, (SCM grob, SCM refp, SCM axis),
- "Get the extent in @var{axis} direction of @var{grob} relative to "
- "the grob @var{refp}, or (0,0) if empty")
-{
- Grob *sc = unsmob_grob (grob);
- Grob *ref = unsmob_grob (refp);
-
- SCM_ASSERT_TYPE (sc, grob, SCM_ARG1, __FUNCTION__, "grob");
- SCM_ASSERT_TYPE (ref, refp, SCM_ARG2, __FUNCTION__, "grob");
- SCM_ASSERT_TYPE (is_axis (axis), axis, SCM_ARG3, __FUNCTION__, "axis");
-
- Axis a = Axis (scm_to_int (axis));
-
- if (ref->common_refpoint (sc, a) != ref)
- {
- // ugh. should use other error message
- SCM_ASSERT_TYPE (false, refp, SCM_ARG2, __FUNCTION__, "common refpoint");
- }
-
- return ly_interval2scm (robust_relative_extent (sc, ref, a));
-}
LY_DEFINE (ly_grob_relative_coordinate, "ly:grob-relative-coordinate",
3, 0, 0, (SCM grob, SCM refp, SCM axis),
return Font_interface::get_default_font (gr)->self_scm ();
}
-
-/*
- TODO: consider swapping order, so we can do
-
- (grob-common-refpoint a b c d e)
- */
LY_DEFINE (ly_grob_common_refpoint, "ly:grob-common-refpoint",
3, 0, 0, (SCM grob, SCM other, SCM axis),
"Find the common refpoint of @var{grob} and @var{other} for @var{axis}."
#include <cstring>
-#include "align-interface.hh"
-#include "input.hh"
+#include "input-smob.hh"
#include "international.hh"
#include "item.hh"
#include "main.hh"
#include "output-def.hh"
#include "pointer-group-interface.hh"
#include "stencil.hh"
-#include "stream-event.hh"
#include "system.hh"
#include "warn.hh"
Object_key const *key)
{
key_ = key;
-
/* FIXME: default should be no callback. */
self_scm_ = SCM_EOL;
layout_ = 0;
retval = Stencil (m->extent_box (), expr);
}
-
SCM rot = get_property ("rotation");
if (scm_is_pair (rot))
{
/* color support... see interpret_stencil_expression () for more... */
SCM color = get_property ("color");
- if (scm_is_pair (color))
+ if (color != SCM_EOL)
{
+ m = unsmob_stencil (stil);
SCM expr = scm_list_3 (ly_symbol2scm ("color"),
color,
- retval.expr ());
+ m->expr ());
- retval = Stencil (retval.extent_box (), expr);
+ retval = Stencil (m->extent_box (), expr);
}
}
return off;
}
-Real
-Grob::pure_relative_y_coordinate (Grob const *refp, int start, int end)
-{
- if (refp == this)
- return 0.0;
-
- SCM pure_off = ly_lily_module_constant ("pure-Y-offset");
- Real off = 0;
-
- if (dim_cache_[Y_AXIS].offset_)
- off = *dim_cache_[Y_AXIS].offset_;
- else if (ly_is_procedure (pure_off))
- {
- dim_cache_[Y_AXIS].offset_ = new Real (0.0);
- off = scm_to_double (scm_apply_3 (pure_off, self_scm (),
- scm_from_int (start), scm_from_int (end),
- SCM_EOL));
- delete dim_cache_[Y_AXIS].offset_;
- dim_cache_[Y_AXIS].offset_ = 0;
- }
-
- /* we simulate positioning-done if we are the child of a VerticalAlignment,
- but only if we don't have a cached offset. If we do have a cached offset,
- it probably means that the Alignment was fixed and it has already been
- calculated.
- */
- Grob *p = get_parent (Y_AXIS);
- Real trans = 0;
- if (Align_interface::has_interface (p) && !dim_cache_[Y_AXIS].offset_)
- trans = Align_interface::get_pure_child_y_translation (p, this, start, end);
-
- return off + trans
- + dim_cache_[Y_AXIS].parent_->pure_relative_y_coordinate (refp, start, end);
-}
-
/* Invoke callbacks to get offset relative to parent. */
Real
Grob::get_offset (Axis a) const
return 0.0;
}
-Real
-Grob::maybe_pure_coordinate (Grob const *refp, Axis a, bool pure, int start, int end)
-{
- if (pure && a != Y_AXIS)
- programming_error ("tried to get pure X-offset");
- return (pure && a == Y_AXIS) ? pure_relative_y_coordinate (refp, start, end)
- : relative_coordinate (refp, a);
-}
/****************************************************************
extents
SCM min_ext = internal_get_property (min_ext_sym);
if (is_number_pair (min_ext))
real_ext.unite (ly_scm2interval (min_ext));
+ ((Grob*)this)->del_property (ext_sym);
((Grob*)this)->dim_cache_[a].extent_ = new Interval (real_ext);
}
return real_ext;
}
-Interval
-Grob::pure_height (Grob *refp, int start, int end)
-{
- SCM pure_height = ly_lily_module_constant ("pure-Y-extent");
- Interval iv (0, 0);
-
- if (ly_is_procedure (pure_height))
- iv = ly_scm2interval (scm_apply_3 (pure_height, self_scm (),
- scm_from_int (start), scm_from_int (end),
- SCM_EOL));
- Real offset = pure_relative_y_coordinate (refp, start, end);
-
- SCM min_ext = get_property ("minimum-Y-extent");
- if (is_number_pair (min_ext))
- iv.unite (ly_scm2interval (min_ext));
-
- iv.translate (offset);
- return iv;
-}
-
-Interval
-Grob::maybe_pure_extent (Grob *refp, Axis a, bool pure, int start, int end)
-{
- if (pure && a != Y_AXIS)
- programming_error ("tried to get pure width");
- return (pure && a == Y_AXIS) ? pure_height (refp, start, end) : extent (refp, a);
-}
-
-Interval_t<int>
-Grob::spanned_rank_iv ()
-{
- return Interval_t<int> (-1, 0);
-}
-
/****************************************************************
REFPOINTS
****************************************************************/
while (Grob *g = unsmob_grob (cause))
cause = g->get_property ("cause");
- /* ES TODO: cause can't be Music*/
if (Music *m = unsmob_music (cause))
m->origin ()->warning (s);
- else if (Stream_event *ev = unsmob_stream_event (cause))
- ev->origin ()->warning (s);
else
::warning (s);
}
s = _f ("programming error: %s", s);
- /* ES TODO: cause can't be Music*/
if (Music *m = unsmob_music (cause))
m->origin ()->message (s);
- else if (Stream_event *ev = unsmob_stream_event (cause))
- ev->origin ()->warning (s);
else
::message (s);
}
virtual Spanner *get_spanner ();
DECLARE_ACKNOWLEDGER (grob);
virtual void add_element (Grob *e);
- void process_music ();
+ void start_translation_timestep ();
virtual void derived_mark () const;
SCM interesting_;
public:
}
void
-Hara_kiri_engraver::process_music ()
+Hara_kiri_engraver::start_translation_timestep ()
{
- Axis_group_engraver::process_music ();
+ Axis_group_engraver::start_translation_timestep ();
interesting_ = get_property ("keepAliveInterfaces");
}
return Axis_group_interface::generic_group_extent (me, Y_AXIS);
}
-MAKE_SCHEME_CALLBACK (Hara_kiri_group_spanner, pure_height, 3);
-SCM
-Hara_kiri_group_spanner::pure_height (SCM smob, SCM start_scm, SCM end_scm)
-{
- Grob *me = unsmob_grob (smob);
- int start = robust_scm2int (start_scm, 0);
- int end = robust_scm2int (end_scm, INT_MAX);
-
- if (request_suicide (me, start, end))
- return ly_interval2scm (Interval ());
- return Axis_group_interface::pure_group_height (me, start, end);
-}
-
-/* there is probably a way that doesn't involve re-implementing a binary
- search (I would love some proper closures right now) */
-bool find_in_range (SCM vector, int low, int hi, int min, int max)
-{
- if (low >= hi)
- return false;
-
- int mid = low + (hi - low) / 2;
- int val = scm_to_int (scm_c_vector_ref (vector, mid));
- if (val >= min && val <= max)
- return true;
- else if (val < min)
- return find_in_range (vector, mid+1, hi, min, max);
- return find_in_range (vector, low, mid, min, max);
-}
-
-bool
-Hara_kiri_group_spanner::request_suicide (Grob *me, int start, int end)
+void
+Hara_kiri_group_spanner::consider_suicide (Grob *me)
{
+ Spanner *sp = dynamic_cast<Spanner *> (me);
if (!to_boolean (me->get_property ("remove-empty")))
- return false;
+ return ;
- bool remove_first = to_boolean (me->get_property ("remove-first"));
- if (!remove_first && start <= 0)
- return false;
-
- SCM important = me->get_property ("important-column-ranks");
- if (scm_is_vector (important))
- {
- int len = scm_c_vector_length (important);
- if (find_in_range (important, 0, len, start, end))
- return false;
- }
- else /* build the important-columns-cache */
- {
- extract_grob_set (me, "items-worth-living", worth);
- vector<int> ranks;
-
- for (vsize i = 0; i < worth.size (); i++)
- {
- Interval_t<int> iv = worth[i]->spanned_rank_iv ();
- for (int j = iv[LEFT]; j <= iv[RIGHT]; j++)
- ranks.push_back (j);
- }
- vector_sort (ranks, less<int> ());
- uniq (ranks);
-
- SCM scm_vec = scm_c_make_vector (ranks.size (), SCM_EOL);
- for (vsize i = 0; i < ranks.size (); i++)
- scm_vector_set_x (scm_vec, scm_from_int (i), scm_from_int (ranks[i]));
- me->set_property ("important-column-ranks", scm_vec);
-
- return request_suicide (me, start, end);
- }
-
- return true;
-}
+ extract_grob_set (me, "items-worth-living", worth);
+ if (worth.size ())
+ return;
-void
-Hara_kiri_group_spanner::consider_suicide (Grob *me)
-{
- Spanner *sp = dynamic_cast<Spanner*> (me);
- int left = sp->get_bound (LEFT)->get_column ()->get_rank ();
- int right = sp->get_bound (RIGHT)->get_column ()->get_rank ();
- if (!request_suicide (me, left, right))
+ bool remove_first = to_boolean (me->get_property ("remove-first"));
+ if (!remove_first
+ && ((sp->original () && broken_spanner_index (sp) == 0)
+ || Paper_column::get_rank (sp->get_bound (LEFT)->get_column ())
+ == 0))
return;
vector<Grob*> childs;
/* properties */
"items-worth-living "
- "important-column-ranks "
"remove-empty "
"remove-first "
);
#include "note-column.hh"
#include "pointer-group-interface.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
#include "translator.icc"
public:
TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver);
vector<Spanner*> bracket_stack_;
- vector<Stream_event*> events_;
+ vector<Music*> events_;
vsize pop_count_;
vsize push_count_;
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (note_grouping);
};
ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
push_count_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Horizontal_bracket_engraver, note_grouping);
-void
-Horizontal_bracket_engraver::listen_note_grouping (Stream_event *ev)
+bool
+Horizontal_bracket_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
-
- if (d == STOP)
+ if (m->is_mus_type ("note-grouping-event"))
{
- pop_count_++;
- if (pop_count_ > bracket_stack_.size ())
- ev->origin ()->warning (_ ("don't have that many brackets"));
+ Direction d = to_dir (m->get_property ("span-direction"));
+
+ if (d == STOP)
+ {
+ pop_count_++;
+ if (pop_count_ > bracket_stack_.size ())
+ m->origin ()->warning (_ ("don't have that many brackets"));
+ }
+ else
+ {
+ push_count_++;
+ events_.push_back (m);
+ }
+
+ if (pop_count_ && push_count_)
+ m->origin ()->warning (_ ("conflicting note group events"));
+
+ return true;
}
- else
- {
- push_count_++;
- events_.push_back (ev);
- }
-
- if (pop_count_ && push_count_)
- ev->origin ()->warning (_ ("conflicting note group events"));
+ return false;
}
void
#include "item.hh"
#include "pointer-group-interface.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
class Hyphen_engraver : public Engraver
{
- Stream_event *ev_;
- Stream_event *finished_ev_;
+ Music *ev_;
+ Music *finished_ev_;
Spanner *hyphen_;
Spanner *finished_hyphen_;
protected:
DECLARE_ACKNOWLEDGER (lyric_syllable);
- DECLARE_TRANSLATOR_LISTENER (hyphen);
virtual void finalize ();
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
finished_hyphen_->set_bound (RIGHT, item);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Hyphen_engraver, hyphen);
-void
-Hyphen_engraver::listen_hyphen (Stream_event *ev)
+bool
+Hyphen_engraver::try_music (Music *r)
{
- ASSIGN_EVENT_ONCE (ev_, ev);
+ if (ev_)
+ return false;
+
+ ev_ = r;
+ return true;
}
void
ev_ = 0;
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable);
ADD_TRANSLATOR (Hyphen_engraver,
+++ /dev/null
-# lily/include/Makefile
-
-depth = ../..
-STEPMAKE_TEMPLATES=c++
-
-include $(depth)/make/stepmake.make
-
-
#include "lily-proto.hh"
#include "lily-guile.hh"
-#include "std-vector.hh"
struct Align_interface
{
DECLARE_SCHEME_CALLBACK (stretch_after_break, (SCM element));
static void align_to_fixed_distance (Grob *, Axis a);
static void align_elements_to_extents (Grob *, Axis a);
- static vector<Real> get_extents_aligned_translates (Grob *, vector<Grob*> const&,
- Axis a,
- bool safe, int start, int end);
static void set_ordered (Grob *);
static Axis axis (Grob *);
static void add_element (Grob *, Grob *);
static int get_count (Grob *, Grob *);
static bool has_interface (Grob *);
-
- static Real get_pure_child_y_translation (Grob *, Grob *child, int start, int end);
};
Grob *find_fixed_alignment_parent (Grob *g);
*/
class All_font_metrics
{
+ Scheme_hash_table *tfm_dict_;
Scheme_hash_table *otf_dict_;
File_path search_path_;
Real scale);
#endif
+ Tex_font_metric *find_tfm (string);
Font_metric *find_font (string name);
Open_type_font *find_otf (string name);
SCM font_descriptions () const;
{
public:
Audio_element *elem_;
- Stream_event *event_;
+ Music *event_;
Translator *origin_trans_;
vector<Context*> origin_contexts (Translator *) const;
- Audio_element_info (Audio_element *, Stream_event *);
+ Audio_element_info (Audio_element *, Music *);
Audio_element_info ();
};
public:
Audio_element ();
virtual ~Audio_element ();
-
- VIRTUAL_COPY_CONSTRUCTOR(Audio_element, Audio_element);
+ VIRTUAL_COPY_CONSTRUCTOR(Audio_element,Audio_element);
virtual char const *name () const;
protected:
};
class Audio_note : public Audio_item
{
public:
- Audio_note (Pitch p, Moment m, bool tie_event, int transposing_i);
+ Audio_note (Pitch p, Moment m, int transposing_i = 0);
void tie_to (Audio_note *);
Moment length_mom_;
int transposing_;
Audio_note *tied_;
- bool tie_event_;
};
class Audio_piano_pedal : public Audio_item
struct Axis_group_interface
{
static SCM generic_group_extent (Grob *me, Axis a);
- static SCM pure_group_height (Grob *me, int start, int end);
DECLARE_SCHEME_CALLBACK (width, (SCM smob));
DECLARE_SCHEME_CALLBACK (height, (SCM smob));
- DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end));
static Interval relative_group_extent (vector<Grob*> const &list,
Grob *common, Axis);
- static Interval relative_pure_height (Grob *me, vector<Grob*> const &list,
- Grob *common, int start, int end,
- bool use_cache);
- static Interval cached_pure_height (Grob *me, vector<Grob*> const &list,
- Grob *common, int, int);
static void add_element (Grob *me, Grob *);
static void set_axes (Grob *, Axis, Axis);
public:
static bool has_interface (Grob *);
- static Stencil dashed_bar_line (Grob *me, Real h, Real thick);
static Stencil compound_barline (Grob *, string, Real height, bool rounded);
static Stencil simple_barline (Grob *, Real wid, Real height, bool rounded);
DECLARE_SCHEME_CALLBACK (calc_bar_size, (SCM));
Drul_array<int> beam_count_drul_;
Moment beat_start_;
- Moment beat_length_;
Moment group_start_;
Beam_rhythmic_element (Moment, int);
Beam_rhythmic_element ();
int count (Direction d);
- void de_grace ();
};
/*
Beaming_pattern ();
void beamify (Context*);
- void de_grace ();
void add_stem (Moment d, int beams);
int beamlet_count (int idx, Direction d) const;
--- /dev/null
+//
+// binary-source-file.hh -- declare Binary_source_file
+//
+// (c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+
+#ifndef BINARY_SOURCE_FILE_HH
+#define BINARY_SOURCE_FILE_HH
+
+#include "source-file.hh"
+
+class Binary_source_file : public Source_file
+{
+public:
+ Binary_source_file (string &file_name_string);
+ virtual ~Binary_source_file ();
+
+ U8 get_U8 ();
+ U16 get_U16 ();
+ U32 get_U32 ();
+ Byte get_Byte () {return get_U8 (); }
+ int get_int () { return get_U32 (); }
+
+ virtual string quote_input (char const *pos_str0) const;
+ virtual int get_line (char const *pos_str0) const;
+};
+
+#endif // BINARY_SOURCE_FILE_HH
public:
VIRTUAL_COPY_CONSTRUCTOR (Output_def, Output_def);
Output_def (Output_def const &);
+
Output_def ();
virtual void derived_mark ();
#include "object-key.hh"
#include "std-string.hh"
-class Book
+class Book : public Input
{
DECLARE_SMOBS (Book, foo);
SCM header_;
Output_def *paper_;
SCM scores_;
- SCM input_location_;
- Book (Book const &);
- Input *origin() const;
- VIRTUAL_COPY_CONSTRUCTOR(Book, Book);
+ Book *clone () const;
Book ();
void add_score (SCM);
Paper_book *process (Output_def *def_paper,
Offset center () const;
void translate (Offset o);
-
/// smallest box enclosing #b#
void set_empty ();
void add_point (Offset);
--- /dev/null
+/*
+ break-algorithm.hh -- declare Break_algorithm
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1996--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef BREAK_HH
+#define BREAK_HH
+
+#include "interval.hh"
+#include "column-x-positions.hh"
+
+/** Class representation of an algorithm which decides where to put
+ the column, and where to break lines.
+
+ JUNKME.
+*/
+class Break_algorithm
+{
+protected:
+ Paper_score *pscore_;
+ Real linewidth_;
+
+ void solve_line (Column_x_positions *) const;
+ bool feasible (vector<Grob*> const &) const;
+
+public:
+ virtual ~Break_algorithm ();
+ Simple_spacer *(*get_line_spacer) ();
+ Break_algorithm ();
+ void set_pscore (Paper_score *);
+ virtual vector<Column_x_positions> solve ();
+};
+
+#endif // BREAK_HH
+
source file of the GNU LilyPond music typesetter
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
+ (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
#ifndef CONSTRAINED_BREAKING_HH
#define CONSTRAINED_BREAKING_HH
+#include "break-algorithm.hh"
#include "lily-guile.hh"
-#include "matrix.hh"
-#include "prob.hh"
struct Line_details {
Real force_;
- Interval extent_; /* Y-extent of the system */
+ Real extent_; /* Y-extent of the system */
Real padding_; /* compulsory space after this system (if we're not last on a page) */
- Real bottom_padding_;
- Real space_; /* spring length */
+ Real space_; /* spring length (stretches over extent_ but not over padding_) */
Real inverse_hooke_;
SCM break_permission_;
Line_details ()
{
force_ = infinity_f;
+ extent_ = 0;
padding_ = 0;
- bottom_padding_ = 0;
space_ = 0;
inverse_hooke_ = 1;
break_permission_ = ly_symbol2scm ("allow");
page_penalty_ = 0;
turn_penalty_ = 0;
}
-
- Line_details (Prob *pb)
- {
- force_ = 0;
- extent_ = unsmob_stencil (pb->get_property ("stencil")) ->extent (Y_AXIS);
- padding_ = 0;
- space_ = 1.0;
- inverse_hooke_ = 1.0;
- break_permission_ = ly_symbol2scm ("allow");
- page_permission_ = pb->get_property ("page-break-permission");
- turn_permission_ = pb->get_property ("page-turn-permission");
- break_penalty_ = 0;
- page_penalty_ = robust_scm2double (pb->get_property ("page-break-penalty"), 0);
- turn_penalty_ = robust_scm2double (pb->get_property ("page-turn-penalty"), 0);
- }
};
/*
/*
A dynamic programming solution to breaking scores into lines
*/
-class Constrained_breaking
+class Constrained_breaking : public Break_algorithm
{
public:
vector<Column_x_positions> solve ();
- Constrained_breaking (Paper_score *ps);
- Constrained_breaking (Paper_score *ps, vector<vsize> const &start_col_posns);
+ Constrained_breaking ();
+ Constrained_breaking (vector<vsize> const &start_col_posns);
- vector<Column_x_positions> get_solution (vsize start, vsize end, vsize sys_count);
- vector<Column_x_positions> get_best_solution (vsize start, vsize end);
+ vector<Column_x_positions> get_solution(vsize start, vsize end, vsize sys_count);
vector<Line_details> get_details (vsize start, vsize end, vsize sys_count);
int get_max_systems (vsize start, vsize end);
int get_min_systems (vsize start, vsize end);
void resize (vsize systems);
private:
- Paper_score *pscore_;
vsize valid_systems_;
vsize systems_;
- bool ragged_right_;
- bool ragged_last_;
/* the (i,j)th entry is the configuration for breaking between
columns i and j */
- Matrix<Line_details> lines_;
+ vector<Line_details> lines_;
+ vsize lines_rank_;
/* the [i](j,k)th entry is the score for fitting the first k bars onto the
first j systems, starting at the i'th allowed starting column */
- vector<Matrix<Constrained_break_node> > state_;
+ vector<vector<Constrained_break_node> > state_;
vector<vsize> start_; /* the columns at which we might be asked to start breaking */
vector<vsize> starting_breakpoints_; /* the corresponding index in breaks_ */
vector<Grob*> all_;
vector<vsize> breaks_;
- void initialize ();
-
Column_x_positions space_line (vsize start_col, vsize end_col);
- vsize prepare_solution (vsize start, vsize end, vsize sys_count);
+ void prepare_solution (vsize start, vsize end, vsize sys_count, vsize *rank, vsize *brk);
Real combine_demerits (Real force, Real prev_force);
The definition of a interpretation context as given in the
input. The lists are stored in order of definition.
*/
-struct Context_def
+struct Context_def : public Input
{
private:
/*
SCM context_aliases_;
SCM translator_group_type_;
SCM default_child_;
- SCM input_location_;
+
public:
- Input *origin () const;
void add_context_mod (SCM);
SCM get_default_child (SCM user_mods) const;
- SCM get_context_name () const { return context_name_; }
+ SCM get_context_name () const;
SCM get_accepted (SCM user_mods) const;
SCM get_property_ops () const { return property_ops_; }
SCM get_translator_names (SCM) const;
- SCM get_translator_group_type () const { return translator_group_type_; }
void set_acceptor (SCM accepts, bool add);
- VIRTUAL_COPY_CONSTRUCTOR(Context_def, Context_def);
-
vector<Context_def*> path_to_acceptable_context (SCM type_string,
Output_def *) const;
Context *instantiate (SCM extra_ops, Object_key const *);
SCM to_alist () const;
static SCM make_scm ();
+ SCM clone_scm () const;
void apply_default_property_operations (Context *);
private:
Context_handle ();
void set_context (Context *);
+ bool try_music (Music *);
void operator = (Context_handle const &);
Context_handle (Context_handle const &);
Context *get_outlet () const;
#ifndef CONTEXT_HH
#define CONTEXT_HH
-#include "context-key-manager.hh"
-#include "lily-proto.hh"
-#include "listener.hh"
-#include "moment.hh"
+
#include "std-vector.hh"
+#include "moment.hh"
+#include "lily-proto.hh"
#include "virtual-methods.hh"
+#include "context-key-manager.hh"
class Context
{
private:
friend class Context_handle;
int iterator_count_;
-
- /* Used internally by create_context */
- Stream_event *infant_event_;
+ bool init_;
protected:
+ int unique_;
Context *daddy_context_;
/* The used Context_def */
SCM definition_;
children, are sent to this dispatcher. */
Dispatcher *events_below_;
- // Translator_group is allowed to set implementation_.
- friend class Translator_group;
- // Context_def::instantiate initialises some protected members.
friend class Context_def;
- // UGH! initialises implementation_
- friend SCM ly_make_global_translator (SCM);
void clear_key_disambiguations ();
- DECLARE_LISTENER (set_property_from_event);
- DECLARE_LISTENER (unset_property_from_event);
public:
Object_key const *get_grob_key (string name);
Object_key const *get_context_key (string name, string id);
+ Context *create_context (Context_def *, string, SCM);
string id_string () const { return id_string_; }
SCM children_contexts () const { return context_list_; }
SCM default_child_context_name () const;
+ int get_unique() { return unique_; }
Dispatcher *event_source () const { return event_source_; }
Dispatcher *events_below () const { return events_below_; }
- void internal_send_stream_event (SCM type, Input *origin, SCM props[]);
+ void internal_send_stream_event (SCM type, SCM props[]);
SCM get_definition () const { return definition_; }
SCM get_definition_mods () const { return definition_mods_; }
/* properties: */
SCM internal_get_property (SCM name_sym) const;
SCM properties_as_alist () const;
+ void internal_set_property (SCM var_sym, SCM value);
Context *where_defined (SCM name_sym, SCM *value) const;
void unset_property (SCM var_sym);
-#ifndef NDEBUG
- void internal_set_property (SCM var_sym, SCM value, char const *file, int line, char const *fun);
-#else
- void internal_set_property (SCM var_sym, SCM value);
-#endif
-
- Context *create_context (Context_def *, string, SCM);
- DECLARE_LISTENER (create_context_from_event);
- DECLARE_LISTENER (acknowledge_infant);
- DECLARE_LISTENER (remove_context);
- DECLARE_LISTENER (change_parent);
- void disconnect_from_parent ();
+ Context *remove_context (Context *trans);
void check_removal ();
string context_name () const;
SCM context_name_symbol () const;
Global_context *get_global_context () const;
- virtual Context *get_score_context () const;
+ virtual Score_context *get_score_context () const;
virtual Output_def *get_output_def () const;
virtual Moment now_mom () const;
virtual Context *get_default_interpreter ();
void add_context (Context *trans);
bool is_bottom_context () const;
bool is_removable () const;
+ bool try_music (Music *);
Context *find_create_context (SCM context_name,
string id, SCM ops);
void set_context_property_on_children (Context *trans, SCM sym, SCM val);
/* Shorthand for creating and broadcasting stream events. */
-#define send_stream_event(ctx, type, origin, ...) \
+#define send_stream_event(ctx, type, ...) \
{ \
SCM props[] = { __VA_ARGS__, 0 }; \
- ctx->internal_send_stream_event (ly_symbol2scm (type), origin, props); \
+ ctx->internal_send_stream_event (ly_symbol2scm (type), props); \
}
#endif /* CONTEXT_HH */
protected:
vector<Grob_info> announce_infos_;
Drul_array<SCM> acknowledge_hash_table_drul_;
- DECLARE_LISTENER (override);
- DECLARE_LISTENER (revert);
+
public:
VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Engraver_group);
-
Engraver_group ();
virtual void derived_mark () const;
void do_announces ();
- virtual void connect_to_context (Context *c);
- virtual void disconnect_from_context ();
virtual void announce_grob (Grob_info);
int pending_grob_count () const;
private:
#ifndef ENGRAVER_HH
#define ENGRAVER_HH
+#include "music.hh"
#include "grob-info.hh"
#include "translator.hh"
*/
class Engraver : public Translator
{
- Grob *internal_make_grob (SCM sym, SCM cause, char const *name,
- char const *f, int l, char const *fun);
friend class Engraver_group;
protected:
void announce_grob (Grob *, SCM cause);
void announce_end_grob (Grob *, SCM cause);
- Item *internal_make_item (SCM sym, SCM cause, char const *name,
- char const *f, int l, char const *fun);
- Spanner *internal_make_spanner (SCM sym, SCM cause, char const *name,
- char const *f, int l, char const *fun);
- Paper_column *internal_make_column (SCM sym, char const *name,
- char const *f, int l, char const *fun);
-
/**
override other ctor
*/
TRANSLATOR_DECLARATIONS (Engraver);
};
-#define make_item(x, cause) internal_make_item (ly_symbol2scm (x), cause, x, __FILE__, __LINE__, __FUNCTION__)
-#define make_spanner(x, cause) internal_make_spanner (ly_symbol2scm (x), cause, x, __FILE__, __LINE__, __FUNCTION__)
-#define make_paper_column(x) internal_make_column (ly_symbol2scm (x), x, __FILE__, __LINE__, __FUNCTION__)
-
+#define make_item(x, cause) make_item_from_properties (this, ly_symbol2scm (x), cause, x)
+#define make_spanner(x, cause) make_spanner_from_properties (this, ly_symbol2scm (x), cause, x)
+#define make_paper_column(x) make_paper_column_from_properties (this, ly_symbol2scm (x), x)
+Grob *make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, char const *name);
+Item *make_item_from_properties (Engraver *tg, SCM x, SCM cause, char const *name);
+Spanner *make_spanner_from_properties (Engraver *tg, SCM x, SCM cause, char const *name);
+Paper_column *make_paper_column_from_properties (Engraver *tg, SCM x, char const *name);
#endif // ENGRAVER_HH
SCM description_;
string file_name_;
- virtual Stencil text_stencil (string) const;
- virtual Stencil word_stencil (string) const;
- // ugh.
+ virtual Stencil text_stencil (string) const;
virtual Box text_dimension (string) const;
-
virtual string font_name () const;
virtual size_t count () const;
virtual Offset attachment_point (string) const;
{
PQueue<Moment> extra_mom_pq_;
Output_def *output_def_;
+ int unique_count_;
DECLARE_CLASSNAME(Global_context);
friend class Output_def;
public:
- Global_context (Output_def *, Object_key *key);
+ Global_context (Output_def *, Moment final, Object_key *key);
int get_moments_left () const;
Moment sneaky_insert_extra_moment (Moment);
void add_moment_to_process (Moment);
void run_iterator_on_me (Music_iterator *);
- virtual Context *get_score_context () const;
+ virtual Score_context *get_score_context () const;
void apply_finalizations ();
void add_finalization (SCM);
- DECLARE_LISTENER (prepare);
virtual SCM get_output ();
+ virtual void prepare (Moment);
+ virtual void one_time_step ();
+ virtual void finish ();
virtual Output_def *get_output_def () const;
virtual Moment now_mom () const;
virtual Context *get_default_interpreter ();
+ int new_unique ();
Moment previous_moment () const;
protected:
+ Moment final_mom_;
Moment prev_mom_;
Moment now_mom_;
};
--- /dev/null
+/*
+ gourlay-breaking.hh -- declare Gourlay_breaking
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef GOURLAY_BREAKING_HH
+#define GOURLAY_BREAKING_HH
+
+#include "break-algorithm.hh"
+
+/**
+ A dynamic programming solution to breaking scores into lines
+*/
+struct Gourlay_breaking : public Break_algorithm
+{
+ vector<Column_x_positions> solve ();
+ Gourlay_breaking ();
+ Real combine_demerits (Column_x_positions const &, Column_x_positions const &) const;
+};
+#endif // GOURLAY_BREAKING_HH
class Gregorian_ligature_engraver : public Coherent_ligature_engraver
{
- Stream_event *pes_or_flexa_req_;
+ Music *pes_or_flexa_req_;
public:
// no TRANSLATOR_DECLARATIONS (Gregorian_ligature_engraver) needed
protected:
Gregorian_ligature_engraver ();
-
- virtual void listen_pes_or_flexa (Stream_event *ev);
+ virtual bool try_music (Music *);
virtual void build_ligature (Spanner *ligature, vector<Grob_info> primitives);
virtual void transform_heads (Spanner *ligature,
vector<Grob_info> primitives) = 0;
Translator *origin_translator () const { return origin_trans_; }
Context *context () const;
- Stream_event *event_cause () const;
- Stream_event *ultimate_event_cause () const;
+ Music *music_cause () const;
+ Music *ultimate_music_cause () const;
vector<Context*> origin_contexts (Translator *) const;
Grob_info (Translator *, Grob *);
Grob_info ();
SCM internal_get_property (SCM symbol) const;
SCM get_property_data (SCM symbol) const;
SCM internal_get_object (SCM symbol) const;
- void internal_set_object (SCM sym, SCM val);
- void internal_del_property (SCM symbol);
-
-#ifndef NDEBUG
- void internal_set_property (SCM sym, SCM val, char const *file, int line, char const *fun);
-#else
+ void del_property (SCM symbol);
void internal_set_property (SCM sym, SCM val);
-#endif
+ void internal_set_object (SCM sym, SCM val);
/* messages */
void warning (string) const;
/* offsets */
void translate_axis (Real, Axis);
Real relative_coordinate (Grob const *refp, Axis) const;
- Real pure_relative_y_coordinate (Grob const *refp, int start, int end);
- Real maybe_pure_coordinate (Grob const *refp, Axis a, bool pure, int start, int end);
/* extents */
Interval extent (Grob *refpoint, Axis) const;
void flush_extent_cache (Axis);
- Interval pure_height (Grob *refpoint, int start_col, int end_col);
- Interval maybe_pure_extent (Grob *refpoint, Axis, bool pure, int start, int end);
/* refpoints */
Grob *common_refpoint (Grob const *s, Axis a) const;
void set_parent (Grob *e, Axis);
Grob *get_parent (Axis a) const;
void fixup_refpoint ();
-
- virtual Interval_t<int> spanned_rank_iv ();
};
/* smob utilities */
SCM axis_offset_symbol (Axis a);
SCM axis_parent_positioning (Axis a);
+
#endif /* GROB_HH */
public:
DECLARE_SCHEME_CALLBACK (force_hara_kiri_callback, (SCM));
DECLARE_SCHEME_CALLBACK (y_extent, (SCM smob));
- DECLARE_SCHEME_CALLBACK (pure_height, (SCM smob, SCM start, SCM end));
DECLARE_SCHEME_CALLBACK (force_hara_kiri_in_y_parent_callback, (SCM));
DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM));
static bool has_interface (Grob *);
- static bool request_suicide (Grob *me, int start, int end);
static void consider_suicide (Grob *me);
static void add_interesting_item (Grob *me, Grob *n);
};
--- /dev/null
+/*
+ input-smob.hh -- declare input smob
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef INPUT_SMOB_HH
+#define INPUT_SMOB_HH
+
+#include "input.hh"
+#include "smobs.hh"
+
+SCM make_input (Input spot);
+Input *unsmob_input (SCM);
+
+extern Input dummy_input_global;
+
+#endif /* INPUT_SMOB_HH */
+
char const *start_;
char const *end_;
Source_file *source_file_;
+
public:
Source_file *get_source_file () const;
char const *start () const;
char const *end () const;
void set (Source_file *, char const *, char const *);
- void warning (string) const;
- void programming_error (string) const;
+ void warning (string) const; // should use member func?
void non_fatal_error (string) const;
void error (string) const;
void message (string) const;
void set_spot (Input const &);
void step_forward ();
void set_location (Input const &, Input const &);
-
Input spot () const;
-
string location_string () const;
string line_number_string () const;
string file_string ()const;
Input ();
};
-
-
-#include "input.hh"
-#include "smobs.hh"
-
-SCM make_input (Input spot);
-Input *unsmob_input (SCM);
-
-extern Input dummy_input_global;
-
#endif // INPUT_HH
static bool is_non_musical (Grob *);
bool is_broken () const;
- bool pure_is_visible (int start, int end) const;
Direction break_status_dir () const;
virtual System *get_system () const;
virtual Paper_column *get_column () const;
virtual void handle_prebroken_dependencies ();
- virtual Interval_t<int> spanned_rank_iv ();
static bool has_interface (Grob *);
protected:
virtual void discretionary_processing ();
#include "std-string.hh"
string kpathsea_find_tfm (char const *name);
+void initialize_kpathsea (char *av0);
#endif /* KPATH_HH */
DECLARE_ACKNOWLEDGER (rest);
DECLARE_ACKNOWLEDGER (note_head);
- virtual void listen_ligature (Stream_event *ev);
+ virtual bool try_music (Music *);
void process_music ();
virtual Spanner *create_ligature_spanner () = 0;
virtual void typeset_ligature (Spanner *ligature,
// class is abstract
private:
- Drul_array<Stream_event *> events_drul_;
+ Drul_array<Music *> events_drul_;
Spanner *ligature_;
vector<Grob_info> primitives_;
Spanner *finished_ligature_;
vector<Grob_info> finished_primitives_;
- Stream_event *prev_start_event_;
+ Music *prev_start_event_;
// moment where ligature started.
Moment ligature_start_mom_;
#define SCM_UNPACK(x) (x)
#endif
+#if (__GNUC__ > 2)
/* Unreliable with gcc-2.x
FIXME: should add check for x86 as well? */
#define CACHE_SYMBOLS
-
-
-
+#endif
#ifdef CACHE_SYMBOLS
-/* this lets us "overload" macros such as get_property to take
- symbols as well as strings */
-inline SCM
-scm_or_str2symbol (char const *c) { return scm_str2symbol (c); }
-
-inline SCM
-scm_or_str2symbol (SCM s) {
- assert (scm_is_symbol (s));
- return s;
-}
-
/* Using this trick we cache the value of scm_str2symbol ("fooo") where
"fooo" is a constant string. This is done at the cost of one static
variable per ly_symbol2scm() use, and one boolean evaluation for
every call.
- */
+
+ The overall speedup of lily is about 5% on a run of wtk1-fugue2. */
#define ly_symbol2scm(x) \
({ \
static SCM cached; \
if (__builtin_constant_p ((x))) \
{ \
if (!cached) \
- value = cached = scm_gc_protect_object (scm_or_str2symbol (x)); \
+ value = cached = scm_gc_protect_object (scm_str2symbol ((x))); \
} \
else \
- value = scm_or_str2symbol (x); \
+ value = scm_str2symbol ((char *) (x)); \
value; \
})
#else
Make TYPE::FUNC available as a Scheme function.
*/
string mangle_cxx_identifier (string);
-#define MAKE_SCHEME_CALLBACK_WITH_OPTARGS(TYPE, FUNC, ARGCOUNT, OPTIONAL_COUNT) \
+#define MAKE_SCHEME_CALLBACK(TYPE, FUNC, ARGCOUNT) \
SCM TYPE ::FUNC ## _proc; \
void \
TYPE ## _ ## FUNC ## _init_functions () \
{ \
string id = mangle_cxx_identifier (string (#TYPE) + "::" + string (#FUNC)); \
TYPE ::FUNC ## _proc = scm_c_define_gsubr (id.c_str(), \
- (ARGCOUNT-OPTIONAL_COUNT), OPTIONAL_COUNT, 0, \
+ (ARGCOUNT), 0, 0, \
(Scheme_function_unknown) TYPE::FUNC); \
scm_c_export (id.c_str (), NULL); \
} \
ADD_SCM_INIT_FUNC (TYPE ## _ ## FUNC ## _callback, \
TYPE ## _ ## FUNC ## _init_functions);
-#define MAKE_SCHEME_CALLBACK(TYPE, FUNC, ARGCOUNT) \
- MAKE_SCHEME_CALLBACK_WITH_OPTARGS(TYPE,FUNC,ARGCOUNT,0);
-
void
ly_add_function_documentation (SCM proc, char const *fname,
char const *varlist,
#define get_property(x) internal_get_property (ly_symbol2scm (x))
#define get_object(x) internal_get_object (ly_symbol2scm (x))
-#define set_object(x, y) internal_set_object (ly_symbol2scm (x), y)
-#define del_property(x) internal_del_property (ly_symbol2scm (x))
-
-#ifndef NDEBUG
-#define set_property(x, y) internal_set_property (ly_symbol2scm (x), y, __FILE__, __LINE__, __FUNCTION__)
-#else
#define set_property(x, y) internal_set_property (ly_symbol2scm (x), y)
-#endif
+#define set_object(x, y) internal_set_object (ly_symbol2scm (x), y)
#endif /* LILY_GUILE_MACROS_HH */
Drul_array<bool> robust_scm2booldrul (SCM, Drul_array<bool>);
Interval robust_scm2interval (SCM, Drul_array<Real>);
Offset robust_scm2offset (SCM, Offset);
-string robust_scm2string (SCM, string);
SCM ly_quote_scm (SCM s);
bool type_check_assignment (SCM val, SCM sym, SCM type_symbol);
SCM ly_alist_vals (SCM alist);
SCM ly_hash2alist (SCM tab);
-SCM ly_hash_table_keys (SCM tab);
+
int procedure_arity (SCM);
/* inserts at front, removing dublicates */
Keyword_table *keytable_;
SCM scopes_;
SCM start_module_;
- int hidden_state_;
public:
- vector<int> extra_token_types_;
string main_input_name_;
void *lexval;
Input *lexloc;
SCM lookup_identifier (string s);
SCM lookup_identifier_symbol (SCM s);
- void push_extra_token (int token_type);
void push_chord_state (SCM tab);
void push_figuredbass_state ();
void push_lyric_state ();
void pop_state ();
void LexerError (char const *);
void set_identifier (SCM name_string, SCM);
- int get_state () const;
bool is_note_state () const;
bool is_chord_state () const;
bool is_lyric_state () const;
public:
Listener (const void *target, Listener_function_table *type);
Listener (Listener const &other);
- Listener ();
-
void listen (SCM ev) const;
bool operator == (Listener const &other) const
};
DECLARE_UNSMOB (Listener, listener);
-#define IMPLEMENT_LISTENER(cl, method) \
-void \
-cl :: method ## _callback (void *self, SCM ev) \
-{ \
- cl *s = (cl *)self; \
- s->method (ev); \
-} \
-void \
-cl :: method ## _mark (void *self) \
-{ \
- cl *s = (cl *)self; \
- scm_gc_mark (s->self_scm ()); \
-} \
-Listener \
-cl :: method ## _listener () const \
-{ \
- static Listener_function_table callbacks; \
- callbacks.listen_callback = &cl::method ## _callback; \
- callbacks.mark_callback = &cl::method ## _mark; \
- return Listener (this, &callbacks); \
+#define IMPLEMENT_LISTENER(cl, method) \
+void \
+cl :: method ## _callback (void *self, SCM ev) \
+{ \
+ cl *s = (cl *)self; \
+ s->method (ev); \
+} \
+void \
+cl :: method ## _mark (void *self) \
+{ \
+ cl *s = (cl *)self; \
+ scm_gc_mark (s->self_scm ()); \
+} \
+Listener \
+cl :: method ## _listener () const \
+{ \
+ static Listener_function_table callbacks; \
+ callbacks.listen_callback = &cl::method ## _callback; \
+ callbacks.mark_callback = &cl::method ## _mark; \
+ return Listener (this, &callbacks); \
}
-#define GET_LISTENER(proc) proc ## _listener ()
+#define GET_LISTENER(proc) ( proc ## _listener ())
#define DECLARE_LISTENER(name) \
inline void name (SCM); \
void \
CL::smobify_self () \
{ \
- protection_cons_ = SCM_EOL; \
self_scm_ = unprotected_smobify_self (); \
+ protection_cons_ = SCM_EOL; \
protect (); \
} \
void \
SCM \
CL::unprotect () \
{ \
- unprotect_smob (self_scm_, &protection_cons_); \
+ unprotect_smob (&protection_cons_); \
return self_scm_; \
} \
SCM \
static string i2varint_string (int i);
virtual string to_string () const = 0;
-};
-class Midi_channel_item : public Midi_item
-{
-public:
int channel_;
- DECLARE_CLASSNAME(Midi_channel_item);
- Midi_channel_item ();
- virtual const char *name () const { return "Midi_channel_item"; }
- virtual ~Midi_channel_item ();
};
/**
/**
Change instrument event
*/
-class Midi_instrument : public Midi_channel_item
+class Midi_instrument : public Midi_item
{
public:
Midi_instrument (Audio_instrument *);
/**
Turn a note on.
*/
-class Midi_note : public Midi_channel_item
+class Midi_note : public Midi_item
{
public:
Midi_note (Audio_note *);
Audio_note *audio_;
-
- static int const c0_pitch_ = 60;
+ static int const c0_pitch_i_ = 60;
Byte dynamic_byte_;
};
Audio_text *audio_;
};
-class Midi_dynamic : public Midi_channel_item
+class Midi_dynamic : public Midi_item
{
public:
Midi_dynamic (Audio_dynamic *);
Audio_dynamic *audio_;
};
-class Midi_piano_pedal : public Midi_channel_item
+class Midi_piano_pedal : public Midi_item
{
public:
Midi_piano_pedal (Audio_piano_pedal *);
class Midi_walker
{
public:
- Midi_walker (Audio_staff *audio_staff, Midi_track *midi_track,
- int channel);
+ Midi_walker (Audio_staff *audio_staff, Midi_track *midi_track);
~Midi_walker ();
void process ();
void do_stop_notes (Moment now_mom);
void output_event (Moment now_mom, Midi_item *l);
- int channel_;
Midi_track *track_;
Audio_staff *staff_;
vsize index_;
{
public:
Box text_dimension (string) const;
- Box word_dimension (string) const;
Stencil text_stencil (string) const;
static SCM make_scaled_font_metric (Font_metric *fm, Real magnification);
static int compare (Moment const &, Moment const &);
SCM as_scheme () const;
};
-
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, +);
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, -);
IMPLEMENT_ARITHMETIC_OPERATOR (Moment, /);
Context *get_outlet () const;
void set_context (Context *);
static SCM get_static_get_iterator (Music *mus);
- void init_context (Music *, Context *);
+ void init_translator (Music *, Context *);
void quit ();
void substitute_outlet (Context *from, Context *to);
void descend_to_bottom_context ();
bool internal_is_music_type (SCM) const;
- Stream_event *to_event () const;
-
DECLARE_SCHEME_CALLBACK (relative_callback, (SCM, SCM));
Pitch to_relative_octave (Pitch);
Pitch generic_to_relative_octave (Pitch);
void send_to_context (Context *c);
DECLARE_SCHEME_CALLBACK (duration_length_callback, (SCM));
-
+
protected:
virtual SCM copy_mutable_properties () const;
virtual void type_check_assignment (SCM, SCM) const;
SCM ly_music_deep_copy (SCM);
extern SCM ly_music_p_proc;
-/* common transposition function for music and event */
-SCM transpose_mutable (SCM alist, Pitch delta);
-
#endif /* MUSIC_HH */
class Note_column
{
public:
- static bool shift_less (Grob *const &, Grob *const &);
+ static int shift_compare (Grob *const &, Grob *const &);
static Direction dir (Grob *me);
static Grob *accidentals (Grob *me);
static Grob *arpeggio (Grob *me);
+++ /dev/null
-/*
- optimal-page-breaking.hh -- declare a page-breaker that
- will break pages in such a way that both horizontal and
- vertical spacing will be acceptable
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#ifndef OPTIMAL_PAGE_BREAKING_HH
-#define OPTIMAL_PAGE_BREAKING_HH
-
-#include "page-breaking.hh"
-#include "page-spacing.hh"
-
-class Optimal_page_breaking: public Page_breaking
-{
-public:
- virtual SCM solve ();
-
- Optimal_page_breaking (Paper_book *pb);
- virtual ~Optimal_page_breaking ();
-
-private:
- Spacing_result try_page_spacing (Line_division const&);
-};
-
-#endif /* OPTIMAL_PAGE_BREAKING_HH */
public:
VIRTUAL_COPY_CONSTRUCTOR (Output_def, Output_def);
DECLARE_SMOBS (Output_def, );
-
public:
SCM scope_;
Output_def *parent_;
void assign_context_def (Output_def *m, SCM transdef);
SCM find_context_def (Output_def const *m, SCM name);
+int get_tempo (Output_def*def, Moment moment);
+void set_tempo (Output_def*def, Moment moment, int count_per_minute_i);
+
Interval line_dimensions_int (Output_def*def, int);
+++ /dev/null
-/*
- page-breaking.hh -- declare a superclass and utility
- functions for several different page-breaking algorithms
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#ifndef PAGE_BREAKING_HH
-#define PAGE_BREAKING_HH
-
-#include "constrained-breaking.hh"
-#include "lily-guile.hh"
-
-/* Either a paper-score, markup or header.
- */
-struct System_spec
-{
- System_spec (Paper_score *ps)
- {
- pscore_ = ps;
- prob_ = NULL;
- }
-
- System_spec (Prob *pb)
- {
- prob_ = pb;
- pscore_ = NULL;
- }
-
- System_spec ()
- {
- pscore_ = NULL;
- prob_ = NULL;
- }
-
- Paper_score *pscore_;
- Prob *prob_;
-};
-
-struct Break_position
-{
- vsize sys_; /* our index in the all_ list */
- vsize score_break_; /* if sys_ is a score, then we start at the score_brk_'th
- possible page-break in the score */
- Grob *col_; /* if sys_ is a score, this points to the broken column */
- bool score_ender_;
-
- Break_position (vsize s=VPOS, vsize brk=VPOS, Grob *g=NULL, bool end=false)
- {
- sys_ = s;
- score_break_ = brk;
- col_ = g;
- score_ender_ = end;
- }
-
- bool operator< (const Break_position &other)
- {
- return (sys_ == VPOS && other.sys_ != VPOS)
- || (sys_ < other.sys_)
- || (sys_ == other.sys_ && score_break_ < other.score_break_);
- }
-
- bool operator<= (const Break_position &other)
- {
- return (sys_ == VPOS)
- || (sys_ < other.sys_ && other.sys_ != VPOS)
- || (sys_ == other.sys_ && score_break_ <= other.score_break_);
- }
-};
-
-class Page_breaking
-{
-public:
- typedef bool (*Break_predicate) (Grob *);
- typedef vector<vsize> Line_division;
- virtual SCM solve () = 0;
-
- Page_breaking (Paper_book *pb, Break_predicate);
- virtual ~Page_breaking ();
-
-protected:
- Paper_book *book_;
-
- Real page_height (int page_number, bool last);
- vsize next_system (Break_position const &break_pos) const;
-
- SCM make_pages (vector<vsize> lines_per_page, SCM lines);
-
- vsize min_system_count (vsize start, vsize end);
- vsize max_system_count (vsize start, vsize end);
- vector<Line_details> line_details (vsize start, vsize end, Line_division const &div);
-
- void break_into_pieces (vsize start, vsize end, Line_division const &div);
- SCM systems ();
-
-
- vector<Line_division> line_divisions (vsize start,
- vsize end,
- vsize system_count,
- Line_division lower_bound = Line_division (),
- Line_division upper_bound = Line_division ());
-
- SCM breakpoint_property (vsize breakpoint, char const *str);
- vector<Break_position> breaks_;
-
-private:
- vector<Break_position> chunks_;
- vector<System_spec> all_;
- vector<Constrained_breaking> line_breaking_;
-
- vector<Break_position> chunk_list (vsize start, vsize end);
- Line_division system_count_bounds (vector<Break_position> const &chunks, bool min);
- void line_breaker_args (vsize i,
- Break_position const &start,
- Break_position const &end,
- vsize *line_breaker_start,
- vsize *line_breaker_end);
-
- void line_divisions_rec (vsize system_count,
- Line_division const &min,
- Line_division const &max,
- vector<Line_division> *result,
- Line_division *cur);
-
- void create_system_list ();
- void find_chunks_and_breaks (Break_predicate);
-};
-#endif /* PAGE_BREAKING_HH */
+++ /dev/null
-/*
- page-spacing.hh -- routines for spacing systems
- vertically across pages
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#ifndef PAGE_SPACING_HH
-#define PAGE_SPACING_HH
-
-#include "constrained-breaking.hh"
-
-struct Spacing_result {
- vector<vsize> systems_per_page_;
- vector<Real> force_;
- Real penalty_;
- Real demerits_;
-
- Spacing_result ()
- {
- penalty_ = 0;
- demerits_ = infinity_f;
- }
-};
-
-/* for page_count > 2, we use a dynamic algorithm similar to
- constrained-breaking -- we have a class that stores the intermediate
- calculations so they can be reused for querying different page counts.
-*/
-
-class Page_spacer
-{
-public:
- Page_spacer (vector<Line_details> const &lines, Real page_height, bool ragged, bool ragged_last);
- Spacing_result solve (vsize page_count);
-
-private:
- struct Page_spacing_node
- {
- Page_spacing_node ()
- {
- demerits_ = infinity_f;
- force_ = infinity_f;
- penalty_ = infinity_f;
- prev_ = VPOS;
- }
-
- Real demerits_;
- Real force_;
- Real penalty_;
- vsize prev_;
- };
-
- Real page_height_;
- vector<Line_details> lines_;
- Matrix<Page_spacing_node> state_;
- vsize max_page_count_;
-
- bool ragged_;
- bool ragged_last_;
-
- void resize (vsize page_count);
- bool calc_subproblem (vsize page, vsize lines);
-};
-
-vsize
-min_page_count (vector<Line_details> const &lines,
- Real page_height, bool ragged, bool ragged_last);
-
-Spacing_result
-space_systems_on_n_pages (vector<Line_details> const&,
- vsize n,
- Real page_height,
- bool ragged,
- bool ragged_last);
-
-Spacing_result
-space_systems_on_n_or_one_more_pages (vector<Line_details> const&,
- vsize n,
- Real page_height,
- Real odd_pages_penalty,
- bool ragged,
- bool ragged_last);
-Spacing_result
-space_systems_on_best_pages (vector<Line_details> const&,
- Real page_height,
- Real odd_pages_penalty,
- bool ragged,
- bool ragged_last);
-
-#endif /* PAGE_SPACING_HH */
+++ /dev/null
-/*
- page-turn-page-breaking.hh -- break lines and pages optimally
- for a whole Paper_book such that page turns can only occur
- at specific places.
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#ifndef PAGE_TURN_PAGE_BREAKING_HH
-#define PAGE_TURN_PAGE_BREAKING_HH
-
-#include "constrained-breaking.hh"
-#include "page-breaking.hh"
-#include "lily-guile.hh"
-
-/*
- A dynamic programming solution to breaking pages
- */
-class Page_turn_page_breaking: public Page_breaking
-{
-public:
- virtual SCM solve ();
-
- Page_turn_page_breaking (Paper_book *pb);
- virtual ~Page_turn_page_breaking ();
-
-protected:
- struct Break_node
- {
- vsize prev_;
- int first_page_number_;
- vsize page_count_;
-
- Real force_;
- Real penalty_;
-
- Real line_force_;
- Real line_penalty_;
-
- /* true if every score here is too widely spaced */
- bool too_many_lines_;
-
- Real demerits_;
- vsize break_pos_; /* index into breaks_ */
-
- Line_division div_;
- vector<vsize> system_count_; /* systems per page */
-
- Break_node ()
- {
- prev_ = break_pos_ = VPOS;
- penalty_ = force_ = 0;
- line_penalty_ = line_force_ = 0;
- demerits_ = infinity_f;
- first_page_number_ = 0;
- page_count_ = 0;
- too_many_lines_ = false;
- }
- };
-
- vector<Break_node> state_;
-
- vsize final_page_num (Break_node const &b);
- Break_node put_systems_on_pages (vsize start,
- vsize end,
- vector<Line_details> const &lines,
- Line_division const &div,
- int page_number);
-
- SCM make_lines (vector<Break_node> *breaks);
- SCM make_pages (vector<Break_node> const &breaks, SCM systems);
-
- Real calc_demerits (Break_node const &me);
- void calc_subproblem (vsize i);
-};
-#endif /* PAGE_TURN_PAGE_BREAKING_HH */
Real);
~Pango_font ();
- string description_string () const;
SCM font_file_name () const;
void register_font_file (string, string);
- Stencil text_stencil (string, bool tight) const;
+ Stencil text_stencil (string) const;
+ Stencil pango_item_string_stencil (PangoItem const *, string) const;
- Stencil pango_item_string_stencil (PangoItem const *, string, bool tight) const;
-
- virtual Stencil word_stencil (string) const;
- virtual Stencil text_stencil (string) const;
virtual void derived_mark () const;
};
#define PAPER_COLUMN_ENGRAVER_HH
#include "engraver.hh"
-#include "listener.hh"
-#include "moment.hh"
-#include "stream-event.hh"
class Paper_column_engraver : public Engraver
{
void set_columns (Paper_column *, Paper_column *);
TRANSLATOR_DECLARATIONS (Paper_column_engraver);
- Paper_column *find_turnable_column (Moment after_this);
- void revoke_page_turns (Moment after_this, Real new_penalty);
-
protected:
void stop_translation_timestep ();
void start_translation_timestep ();
void process_music ();
virtual void initialize ();
virtual void finalize ();
-
- DECLARE_TRANSLATOR_LISTENER (break);
+ virtual bool try_music (Music *);
DECLARE_ACKNOWLEDGER (item);
DECLARE_ACKNOWLEDGER (note_spacing);
DECLARE_ACKNOWLEDGER (staff_spacing);
System *system_;
- vector<Stream_event*> break_events_;
+ vector<Music*> break_events_;
int breaks_; // used for stat printing
Paper_column *command_column_;
Paper_column *musical_column_;
bool first_;
Moment last_moment_;
+ Moment last_breakable_moment_;
+ Paper_column *last_breakable_column_;
public:
};
virtual void do_break_processing ();
virtual Paper_column *get_column () const;
virtual System *get_system () const;
- void set_system (System *);
-
- static int compare (Grob * const &a,
- Grob * const &b);
- static bool less_than (Grob *const &a,
- Grob *const &b);
int get_rank () const { return rank_; }
void set_rank (int);
System *system_;
SCM systems_;
SCM paper_systems_;
-
- mutable vector<Grob*> cols_;
- mutable vector<vsize> break_indices_;
public:
Paper_score (Output_def *);
void typeset_system (System *);
vector<Column_x_positions> calc_breaking ();
vector<vsize> find_break_indices () const;
- vector<vsize> get_break_indices () const;
- vector<Grob*> get_columns () const;
SCM get_paper_systems ();
protected:
virtual void process ();
--- /dev/null
+/*
+ percent-repeat-iterator.hh -- declare Percent_repeat_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2001--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef PERCENT_REPEAT_ITERATOR_HH
+#define PERCENT_REPEAT_ITERATOR_HH
+
+#include "sequential-iterator.hh"
+
+class Percent_repeat_iterator : public Sequential_iterator
+{
+public:
+ DECLARE_CLASSNAME(Percent_repeat_iterator);
+ DECLARE_SCHEME_CALLBACK (constructor, ());
+ Percent_repeat_iterator ();
+protected:
+ virtual SCM get_music_list () const;
+private:
+};
+
+#endif /* PERCENT_REPEAT_ITERATOR_HH */
void do_announces ();
virtual void announce_element (Audio_element_info);
+ virtual void play_element (Audio_element *p);
+ virtual int get_tempo () const;
protected:
vector<Audio_element_info> announce_infos_;
- virtual void acknowledge_audio_elements ();
+
+private:
+ void acknowledge_audio_elements ();
};
void performer_each (SCM list, Performer_method method);
virtual void announce_element (Audio_element_info);
virtual void acknowledge_audio_element (Audio_element_info);
virtual void create_audio_elements ();
+ virtual int get_tempo () const;
+ virtual void play_element (Audio_element *elem);
};
#endif /* PERFORMER_HH */
#include "lily-proto.hh"
#include "smobs.hh"
-#include "std-vector.hh"
-
-struct Scale
-{
- vector<int> step_semitones_;
- Scale ();
- Scale (Scale const&);
- DECLARE_SMOBS(Scale,);
-};
-
-
/** A "tonal" pitch. This is a pitch used in diatonal western music
(24 quartertones in an octave), as opposed to a frequency in Hz or a
integer number of semitones.
int notename_;
int alteration_;
int octave_;
- Scale *scale_;
-
+
void transpose (Pitch);
void up_to (int);
void down_to (int);
extern SCM pitch_less_proc;
Pitch pitch_interval (Pitch const &from, Pitch const &to);
-extern Scale *default_global_scale;
#endif /* MUSICAL_PITCH_HH */
SCM type () const { return type_; }
SCM get_property_alist (bool mutble) const;
SCM internal_get_property (SCM sym) const;
-
-#ifndef NDEBUG
- void internal_set_property (SCM sym, SCM val, const char *file, int line, char const *fun);
-#else
void internal_set_property (SCM sym, SCM val);
-#endif
};
DECLARE_UNSMOB(Prob,prob);
SCM ly_prob_set_property_x (SCM system, SCM sym, SCM value);
--- /dev/null
+/*
+ score-context.hh -- declare Score_context
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+#ifndef SCORE_CONTEXT_HH
+#define SCORE_CONTEXT_HH
+
+#include "global-context.hh"
+
+class Score_context : public Context
+{
+public:
+ Score_context (Object_key const *);
+
+ virtual SCM get_output ();
+ virtual void prepare (Moment);
+ virtual void finish ();
+ virtual void one_time_step ();
+};
+
+#endif /* SCORE_CONTEXT_HH */
#define SCORE_ENGRAVER_HH
#include "engraver-group.hh"
+#include "score-translator.hh"
-class Score_engraver : public Engraver_group
+class Score_engraver : public virtual Score_translator,
+ public virtual Engraver_group
{
System *system_;
void typeset_all ();
protected:
- DECLARE_LISTENER (finish);
- DECLARE_LISTENER (prepare);
- DECLARE_LISTENER (one_time_step);
+ /* Score_translator */
+ virtual void finish ();
+ virtual void prepare (Moment);
+ virtual void one_time_step ();
/* Engraver_group_engraver interface */
- virtual void connect_to_context (Context *);
- virtual void disconnect_from_context ();
+ virtual bool try_music (Music *);
virtual void initialize ();
virtual void finalize ();
virtual void announce_grob (Grob_info);
public:
Score_engraver ();
+ virtual SCM get_output ();
};
#endif /* SCORE_ENGRAVER_HH */
#ifndef SCORE_PERFORMER_HH
#define SCORE_PERFORMER_HH
-#include "moment.hh"
#include "performer-group.hh"
+#include "score-translator.hh"
/**
Top level performer. Completely takes care of MIDI output
*/
-class Score_performer : public Performer_group
+class Score_performer : public Score_translator,
+ public virtual Performer_group
{
public:
VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Score_performer);
+ ~Score_performer ();
Performance *performance_;
- ~Score_performer ();
Score_performer ();
-
protected:
- DECLARE_LISTENER (finish);
- DECLARE_LISTENER (prepare);
- DECLARE_LISTENER (one_time_step);
-
- /* Engraver_group_engraver interface */
- virtual void connect_to_context (Context *);
- virtual void disconnect_from_context ();
+ virtual void prepare (Moment mom);
+ virtual void finish ();
+ virtual void one_time_step ();
virtual void initialize ();
virtual void announce_element (Audio_element_info);
+ virtual int get_tempo () const;
+ virtual void play_element (Audio_element *p);
+ virtual SCM get_output ();
virtual void derived_mark () const;
- virtual void acknowledge_audio_elements ();
private:
void header (Midi_stream &);
--- /dev/null
+/*
+ score-translator.hh -- declare Score_translator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef SCORE_TRANSLATOR_HH
+#define SCORE_TRANSLATOR_HH
+
+#include "translator-group.hh"
+
+class Score_translator : public virtual Translator_group
+{
+ friend class Score_context;
+protected:
+ virtual SCM get_output ();
+ virtual void prepare (Moment);
+ virtual void finish ();
+ virtual void one_time_step ();
+};
+
+#endif /* SCORE_TRANSLATOR_HH */
+
#include "virtual-methods.hh"
#include "std-string.hh"
-class Score
+class Score : public Input
{
DECLARE_SMOBS (Score, foo);
SCM music_;
- SCM input_location_;
+
public:
- Input *origin() const;
-
vector<Output_def*> defs_;
string user_key_;
SCM header_;
Score ();
Score (Score const &);
- VIRTUAL_COPY_CONSTRUCTOR (Score, Score);
SCM get_music () const;
void add_output_def (Output_def *def);
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
- static bool less (Grob *const &s1,
- Grob *const &s2);
+ static int compare (Grob *const &s1,
+ Grob *const &s2);
static int get_position (Grob *);
};
--- /dev/null
+/*
+ Sequential_music-iterator.hh -- declare Sequential_music_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef SEQUENTIAL_MUSIC_ITERATOR_HH
+#define SEQUENTIAL_MUSIC_ITERATOR_HH
+
+#include "sequential-iterator.hh"
+
+/** Sequential_music iteration: walk each element in turn, and
+ construct an iterator for every element.
+*/
+class Sequential_music_iterator : public Sequential_iterator
+{
+public:
+ DECLARE_SCHEME_CALLBACK (constructor, ());
+ DECLARE_CLASSNAME(Sequential_music_iterator);
+private:
+ virtual SCM get_music_list ()const;
+};
+
+#endif // SEQUENTIAL_MUSIC_ITERATOR_HH
public:
DECLARE_SCHEME_CALLBACK (y_aligned_on_support_refpoints, (SCM element));
- DECLARE_SCHEME_CALLBACK (pure_y_aligned_on_support_refpoints, (SCM element, SCM start, SCM end));
- DECLARE_SCHEME_CALLBACK (x_aligned_side, (SCM element, SCM current));
- DECLARE_SCHEME_CALLBACK (y_aligned_side, (SCM element, SCM current));
- DECLARE_SCHEME_CALLBACK (pure_y_aligned_side, (SCM element, SCM start, SCM end));
+ DECLARE_SCHEME_CALLBACK (x_aligned_side, (SCM element));
+ DECLARE_SCHEME_CALLBACK (y_aligned_side, (SCM element));
- static SCM aligned_side (Grob*me, Axis a, bool pure, int start, int end, Real *current_off_ptr);
+ static SCM aligned_side (Grob*me, Axis a);
- static SCM general_side_position (Grob *, Axis, bool, bool my_extents,
- bool pure, int start, int end, Real *current_off);
+ static SCM general_side_position (Grob *, Axis, bool);
static Axis get_axis (Grob *);
static void set_axis (Grob *, Axis);
static bool has_interface (Grob *);
void add_spring (Real, Real);
Real range_ideal_len (int l, int r) const;
Real range_stiffness (int l, int r) const;
- Real configuration_length (Real) const;
+ Real configuration_length () const;
vector<Real> spring_positions () const;
- Real force () const;
- bool fits () const;
+ Real force ();
+ bool fits ();
DECLARE_SIMPLE_SMOBS (Simple_spacer,);
/* returns a vector of dimensions breaks.size () * breaks.size () */
vector<Real> get_line_forces (vector<Grob*> const &columns,
+ vector<vsize> breaks,
Real line_len,
Real indent,
bool ragged);
#include "std-vector.hh"
#include "main.hh"
-
-enum Configuration_tag
- {
- SLUR_STEM = 0x01,
- SLUR_HEAD = 0x02,
- SLUR_FREE = 0x04,
- SLUR_FREE_HEAD = 0x08,
- SLUR_FREE_STEM = 0x10,
- SLUR_STEM_TIP = 0x10,
- };
-
class Slur_configuration
{
Real score_;
Drul_array<Offset> attachment_;
Bezier curve_;
Real height_;
- unsigned tags_;
+
int index_;
Slur_configuration ();
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
- DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
DECLARE_SCHEME_CALLBACK (height, (SCM));
DECLARE_SCHEME_CALLBACK (outside_slur_callback, (SCM, SCM));
static bool has_interface (Grob *);
#define DECLARE_TYPE_P(CL) extern SCM CL ## _type_p_proc
void protect_smob (SCM smob, SCM *prot_cons);
-void unprotect_smob (SCM smob, SCM *prot_cons);
+void unprotect_smob (SCM *prot_cons);
#endif /* SMOBS_HH */
#include "flower-proto.hh"
#include "std-vector.hh"
#include "lily-proto.hh"
-#include "smobs.hh"
+#include "protected-scm.hh"
#include <iostream>
using namespace std;
class Source_file
{
- vector<char const*> newline_locations_;
- istream *istream_;
- vector<char> characters_;
- SCM str_port_;
-
- void load_stdin ();
- void init_port ();
- void init ();
-
- DECLARE_SMOBS(Source_file, bla);
public:
Source_file (string fn);
Source_file (string, string);
+ virtual ~Source_file ();
+
char const *c_str () const;
virtual string quote_input (char const *pos_str0) const;
istream *get_istream ();
bool contains (char const *pos_str0) const;
int length () const;
virtual int get_line (char const *pos_str0) const;
- void set_line (char const *pos_str0, int i);
string name_string () const;
string file_line_column_string (char const *str0) const;
+ // return start + n
+ char const *seek_str0 (int n);
+
+ int tell () const;
+ // return here + n bytes
+ char const *forward_str0 (int n);
+ char const *pos_str0 () { return pos_str0_; }
+ string get_string (int n);
+ void set_pos (char const *pos_str0);
public:
Slice line_slice (char const *pos_str0) const;
string line_string (char const *pos_str0) const;
void get_counts (char const *pos_str0, int *, int *, int *) const;
-
+
+ /*
+ JUNKME.
+
+ This thing doubles as a file-storage/file-iterator object.
+ */
+ char const *pos_str0_;
+
SCM get_port () const;
string name_;
-protected:
- int line_offset_;
+private:
+ vector<char*> newline_locations_;
+ istream *istream_;
+ char *contents_str0_;
+ vector<char> chs_;
+ int length_;
+ void load_stdin ();
+ void init_port ();
+
+ Protected_scm str_port_;
};
-vector<char> gulp_file (string fn, int desired);
+char *gulp_file (string fn, int *len);
#endif /* SOURCE_FILE_HH */
bool packed_;
bool stretch_uniformly_;
bool float_nonmusical_columns_;
- bool float_grace_columns_;
Rational global_shortest_;
Real increment_;
Real shortest_duration_space_;
- Spacing_options();
+ void init ();
void init_from_grob (Grob *me);
- Real get_duration_space (Rational d, bool *) const;
+ Real get_duration_space (Moment d, bool *) const;
};
/*
static Real default_bar_spacing (Grob *, Grob *, Grob *, Moment);
static Real note_spacing (Grob *, Grob *, Grob *, Spacing_options const *, bool *);
static Real get_duration_space (Moment dur, Spacing_options const *, bool *);
+ static Rational find_shortest (Grob *, vector<Grob*> const &);
static Rational effective_shortest_duration (Grob *me, vector<Grob*> const &all);
static void breakable_column_spacing (Grob *, Item *l, Item *r, Spacing_options const *);
static void prune_loose_columns (Grob *, vector<Grob*> *cols, Spacing_options const *);
static void set_implicit_neighbor_columns (vector<Grob*> const &cols);
static void generate_springs (Grob *me, vector<Grob*> const &cols, Spacing_options const *);
static void musical_column_spacing (Grob *, Item *, Item *, Spacing_options const *);
- static vector<Grob*> get_columns (Spanner *me);
-
DECLARE_SCHEME_CALLBACK (set_springs, (SCM));
- DECLARE_SCHEME_CALLBACK (calc_common_shortest_duration, (SCM));
static bool has_interface (Grob *);
};
void substitute_one_mutable_property (SCM sym, SCM val);
bool fast_substitute_grob_array (SCM sym, Grob_array *);
- virtual Interval_t<int> spanned_rank_iv ();
+ // TODO: make virtual and do this for Items as well.
+ Interval_t<int> spanned_rank_iv ();
void set_bound (Direction d, Grob *);
Item *get_bound (Direction d) const;
Real spanner_length () const;
static int compare (Spanner *const &, Spanner *const &);
- static bool less (Spanner *const &, Spanner *const &);
virtual Grob *find_broken_piece (System *) const;
virtual void derived_mark () const;
static bool has_interface (Grob *);
--- /dev/null
+/*
+ staff-symbol-engraver.hh -- declare Staff_symbol_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#ifndef STAFF_SYMBOL_ENGRAVER_HH
+#define STAFF_SYMBOL_ENGRAVER_HH
+
+#include "engraver.hh"
+#include "drul-array.hh"
+
+class Staff_symbol_engraver : public Engraver
+{
+public:
+ TRANSLATOR_DECLARATIONS (Staff_symbol_engraver);
+
+private:
+
+protected:
+ Drul_array<Music *> span_events_;
+ Spanner *span_;
+ Spanner *finished_span_;
+ bool first_start_;
+
+protected:
+ virtual void start_spanner ();
+ virtual void stop_spanner ();
+
+ void stop_translation_timestep ();
+ virtual bool try_music (Music *);
+ virtual ~Staff_symbol_engraver ();
+ DECLARE_ACKNOWLEDGER (grob);
+ virtual void finalize ();
+ void process_music ();
+};
+
+#endif /* STAFF_SYMBOL_ENGRAVER_HH */
static int get_rounded_position (Grob *);
};
-int compare_position (Grob *const &, Grob *const &);\
-bool position_less (Grob *const &, Grob *const &);
+int compare_position (Grob *const &, Grob *const &);
#endif /* STAFF_SYMBOL_REFERENCER_HH */
DECLARE_SCHEME_CALLBACK (print, (SCM));
DECLARE_SCHEME_CALLBACK (height, (SCM));
DECLARE_SCHEME_CALLBACK (calc_style, (SCM));
- static Stencil raw_stencil (Grob *, Real slope, Direction stemdir);
- static Stencil translated_stencil (Grob*, Real slope);
+ static Stencil raw_stencil (Grob *, Real, Direction stemdir);
static Real get_beam_translation (Grob *me);
};
DECLARE_SCHEME_CALLBACK (calc_stem_info, (SCM));
DECLARE_SCHEME_CALLBACK (calc_positioning_done, (SCM));
DECLARE_SCHEME_CALLBACK (width, (SCM smob));
- DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM));
DECLARE_SCHEME_CALLBACK (height, (SCM));
};
#endif
#include "smobs.hh"
#include "prob.hh"
-class Stream_event : public Prob
+class Stream_event
{
+ void init ();
+ SCM property_alist_;
+ Input *origin_;
+
public:
Stream_event ();
- VIRTUAL_COPY_CONSTRUCTOR (Stream_event, Stream_event);
- // todo: remove unneeded constructors
- Stream_event (SCM event_class, SCM mutable_props=SCM_EOL);
- Stream_event (SCM class_name, Input *);
- Stream_event (Stream_event *ev);
-
Input *origin () const;
- void set_spot (Input *i);
- bool internal_in_event_class (SCM class_name);
DECLARE_SCHEME_CALLBACK (undump, (SCM));
DECLARE_SCHEME_CALLBACK (dump, (SCM));
-};
+ // todo: make Input mandatory.
+ Stream_event (SCM property_alist);
+ Stream_event (Context *c, SCM class_name);
+ Stream_event (Context *c, Input *);
+ Stream_event (Stream_event *ev);
+
+ SCM internal_get_property (SCM) const;
+ void internal_set_property (SCM prop, SCM val);
-#define in_event_class(class_name) internal_in_event_class (ly_symbol2scm (class_name))
+protected:
+ DECLARE_SMOBS (Stream_event,);
+};
-Stream_event *unsmob_stream_event (SCM);
+DECLARE_UNSMOB (Stream_event, stream_event);
DECLARE_TYPE_P (Stream_event);
#endif /* STREAM_EVENT_HH */
--- /dev/null
+/*
+ tfm-reader.hh -- declare Tex_font_metric_reader
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+
+
+ revamped code from GNU Fontutils-0.6
+*/
+
+#ifndef TFM_READER_HH
+#define TFM_READER_HH
+
+#include "tfm.hh"
+#include "binary-source-file.hh"
+
+class Tex_font_metric_reader
+{
+private:
+ Real get_U32_fix ();
+ Real get_U32_fix_scaled ();
+ string get_bcpl_string ();
+ void read_header ();
+ void read_params ();
+ void read_char_metrics ();
+ Tex_font_char_metric read_char_metric (Char_code code);
+ Tex_font_char_metric read_char ();
+ void read_lig_kern_program (vector<Tfm_ligature> *ligatures,
+ vector<Tfm_kern> *kerns);
+
+ Binary_source_file input_;
+
+public:
+ Tex_font_metric_reader (string name);
+
+ Tfm_info info_;
+ Tfm_header header_;
+ vector<Tex_font_char_metric> char_metrics_;
+ vector<vsize> ascii_to_metric_idx_;
+};
+
+#endif /* TFM_READER_HH */
+
--- /dev/null
+/*
+ tfm.hh -- declare Tex_font_metric
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+
+
+ revamped code from GNU Fontutils-0.6
+*/
+
+/*
+ TODO: aren't there standard libs? Ideally it is better to just link
+ to a C-library. */
+
+#ifndef TFM_HH
+#define TFM_HH
+
+#include "std-vector.hh"
+#include "font-metric.hh"
+
+/* The type. */
+typedef long Fix;
+
+/* A character code. Perhaps someday we will allow for 16-bit
+ character codes, but for now we are restricted to 256 characters per
+ font (like TeX and PostScript). */
+typedef unsigned char Char_code;
+
+/* Used in file formats. */
+typedef int Byte_count;
+
+/* The restriction to 256 characters in a TFM file is part of the file
+ format, so this number should only be changed in the (very unlikely)
+ event that the file format changes. */
+#define TFM_SIZE 256
+
+/* Fontwide information. All real values are in printer's points:
+ 72.27 points = 1 inch. */
+
+/* TFM_MIN_DESIGNSIZE <= designsize < TFM_MAX_DESIGNSIZE. */
+#define TFM_MIN_DESIGNSIZE 1.0
+#define TFM_MAX_DESIGNSIZE 2048
+
+/* The maximum number of global font parameters we allow. */
+#define TFM_MAX_FONTDIMENS 30
+
+/* The maximum length of a codingscheme string. */
+#define TFM_MAX_CODINGSCHEME_LENGTH 39
+
+/* Define symbolic names for the numbers of the parameters we
+ recognize. Some numbers have more than one name. */
+#define TFM_SLANT_PARAMETER 1
+#define TFM_SPACE_PARAMETER 2
+#define TFM_STRETCH_PARAMETER 3
+#define TFM_SHRINK_PARAMETER 4
+#define TFM_XHEIGHT_PARAMETER 5
+#define TFM_QUAD_PARAMETER 6
+#define TFM_EXTRASPACE_PARAMETER 7
+#define TFM_NUM1_PARAMETER 8
+#define TFM_NUM2_PARAMETER 9
+#define TFM_NUM3_PARAMETER 10
+#define TFM_DENOM1_PARAMETER 11
+#define TFM_DENOM2_PARAMETER 12
+#define TFM_SUP1_PARAMETER 13
+#define TFM_SUP2_PARAMETER 14
+#define TFM_SUP3_PARAMETER 15
+#define TFM_SUB1_PARAMETER 16
+#define TFM_SUB2_PARAMETER 17
+#define TFM_SUPDROP_PARAMETER 18
+#define TFM_SUBDROP_PARAMETER 19
+#define TFM_DELIM1_PARAMETER 20
+#define TFM_DELIM2_PARAMETER 21
+#define TFM_AXISHEIGHT_PARAMETER 22
+#define TFM_DEFAULTRULETHICKNESS_PARAMETER 8
+#define TFM_BIGOPSPACING1_PARAMETER 9
+#define TFM_BIGOPSPACING2_PARAMETER 10
+#define TFM_BIGOPSPACING3_PARAMETER 11
+#define TFM_BIGOPSPACING4_PARAMETER 12
+#define TFM_BIGOPSPACING5_PARAMETER 13
+
+/* These are not in any of the standard TeX fonts, but the information
+ is useful nevertheless. */
+#define TFM_LEADINGHEIGHT_PARAMETER 23
+#define TFM_LEADINGDEPTH_PARAMETER 24
+#define TFM_FONTSIZE_PARAMETER 25
+#define TFM_VERSION_PARAMETER 26
+
+struct Tfm_header
+{
+ Byte_count char_info_pos;
+ Byte_count width_pos;
+ Byte_count height_pos;
+ Byte_count depth_pos;
+ Byte_count italic_correction_pos;
+ Byte_count lig_kern_pos;
+ Byte_count kern_pos;
+ unsigned param_word_count;
+};
+
+struct Tfm_info
+{
+ Char_code first_charcode, last_charcode;
+ U32 checksum;
+ Real design_size;
+ string coding_scheme;
+ unsigned parameter_count;
+ // Real parameters [Tex_font_metric::MAX_FONTDIMENS];
+ Real parameters [TFM_MAX_FONTDIMENS];
+};
+
+/* When typesetting, the current character + `character' leads to
+ `ligature'. The TFM format was extended in 1990 to allow for more
+ complicated ligatures than this, but we do not make those
+ distinctions. */
+struct Tfm_ligature
+{
+ Char_code character;
+ Char_code ligature;
+};
+
+/* Similarly for kerns. */
+struct Tfm_kern
+{
+ Char_code character;
+ Real kern;
+};
+
+struct Tex_font_char_metric
+{
+ bool exists_;
+ Char_code code_;
+ Real width_, height_, depth_, italic_correction_;
+ Fix width_fix_, height_fix_, depth_fix_, italic_correction_fix_;
+ vector<Tfm_kern> kerns_;
+ vector<Tfm_ligature> ligatures_;
+
+ Tex_font_char_metric ();
+
+ Box dimensions () const;
+};
+
+class Tex_font_metric : public Simple_font_metric
+{
+ DECLARE_CLASSNAME(Tex_font_metric);
+
+public:
+ static SCM make_tfm (string file_name);
+
+ vsize count () const;
+ Box get_ascii_char (vsize) const;
+ Real design_size () const;
+ void derived_mark () const;
+ vsize name_to_index (string) const;
+ string font_name () const;
+
+ Tfm_info const &info () const;
+
+protected:
+ Tfm_info info_;
+ Tfm_header header_;
+ vector<Tex_font_char_metric> char_metrics_;
+ vector<vsize> ascii_to_metric_idx_;
+ SCM encoding_table_;
+ string font_name_;
+
+private:
+ Tex_font_char_metric const *find_ascii (vsize ascii, bool warn = true) const;
+ Tex_font_metric ();
+};
+
+#endif /* TFM_HH */
+
DECLARE_SCHEME_CALLBACK (set_spacing_rods, (SCM));
DECLARE_SCHEME_CALLBACK (calc_direction, (SCM));
DECLARE_SCHEME_CALLBACK (calc_control_points, (SCM));
- static bool less (Grob *const &s1,
- Grob *const &s2);
+ static int compare (Grob *const &s1,
+ Grob *const &s2);
};
Translator_group_void_method
precomputed_self_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
- SCM protected_events_;
-
- DECLARE_LISTENER (create_child_translator);
+ DECLARE_LISTENER (eat_event);
public:
VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Translator_group);
DECLARE_SMOBS (Translator_group, dummy);
public:
- virtual void connect_to_context (Context *c);
- virtual void disconnect_from_context ();
+ void connect_to_context (Context *c);
virtual Translator_group *get_daddy_translator ()const;
virtual SCM get_simple_trans_list ();
+ virtual bool try_music (Music *req);
virtual void initialize ();
virtual void finalize ();
- void protect_event (SCM ev);
-
void stop_translation_timestep ();
void start_translation_timestep ();
Context *context () const { return context_; }
protected:
SCM simple_trans_list_;
+ SCM accept_hash_table_;
Context *context_;
friend class Context_def;
#include "input.hh"
#include "smobs.hh"
#include "std-vector.hh"
-#include "protected-scm.hh"
struct Acknowledge_information
{
Engraver_void_function_engraver_grob_info function_;
};
-
-/*
- Each translator class has a static list of listener records. Each
- record makes one explains how to register one of the class's stream event
- listeners to a context.
-*/
-typedef struct translator_listener_record {
- Listener (*get_listener_) (void *);
- SCM event_class_;
- struct translator_listener_record *next_;
-} translator_listener_record;
-
#define TRANSLATOR_DECLARATIONS(NAME) \
-private: \
- static translator_listener_record *listener_list_; \
public: \
NAME (); \
VIRTUAL_COPY_CONSTRUCTOR (Translator, NAME); \
} \
static Engraver_void_function_engraver_grob_info static_get_acknowledger (SCM sym); \
static Engraver_void_function_engraver_grob_info static_get_end_acknowledger(SCM); \
-public: \
- virtual translator_listener_record *get_listener_list () const \
- { \
- return listener_list_; \
- } \
/* end #define */
-#define DECLARE_TRANSLATOR_LISTENER(m) \
-public: \
-inline void listen_ ## m (Stream_event *); \
-/* Should be private */ \
-static void _internal_declare_ ## m (); \
-private: \
-static Listener _get_ ## m ## _listener (void *); \
-DECLARE_LISTENER (_listen_scm_ ## m);
#define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected:
#define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected:
virtual Translator_group *get_daddy_translator ()const;
virtual Moment now_mom () const;
+ virtual bool try_music (Music *req);
virtual void initialize ();
virtual void finalize ();
- /*should maybe be virtual*/
- void connect_to_context (Context *c);
- void disconnect_from_context (Context *c);
-
void stop_translation_timestep ();
void start_translation_timestep ();
void process_music ();
void process_acknowledged ();
- Context *get_score_context () const;
+ Score_context *get_score_context () const;
Global_context *get_global_context () const;
TRANSLATOR_DECLARATIONS (Translator);
protected: // should be private.
Context *daddy_context_;
- void protect_event (SCM ev);
virtual void derived_mark () const;
- static void add_translator_listener (translator_listener_record **listener_list, translator_listener_record *r, Listener (*get_listener) (void *), const char *ev_class);
- SCM get_listened_class_list (const translator_listener_record *listeners) const;
- friend class Translator_group;
+ friend class Context_def;
+ friend class Context;
};
void add_translator (Translator *trans);
Translator *get_translator (SCM s);
-Moment get_event_length (Stream_event *s);
DECLARE_UNSMOB (Translator, translator);
#endif // TRANSLATOR_HH
#ifndef TRANSLATOR_ICC
#define TRANSLATOR_ICC
-#include "listener.hh"
#include "std-vector.hh"
#include "translator.hh"
A macro to automate administration of translators.
*/
#define ADD_THIS_TRANSLATOR(T) \
- translator_listener_record *T::listener_list_; \
SCM T::static_description_ = SCM_EOL; \
static void _ ## T ## _adder () \
{ \
scm_makfrom0str (desc), static_properties); \
\
static_properties = scm_acons (ly_symbol2scm ("events-accepted"), \
- get_listened_class_list (listener_list_), static_properties); \
+ parse_symbol_list (accepted), static_properties); \
\
static_properties = scm_acons (ly_symbol2scm ("properties-read"), \
parse_symbol_list (read), static_properties); \
} \
ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
-/*
- Implement the method cl::listen_##m, and make it listen to stream
- events of class m.
- */
-#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m) \
-void \
-cl :: _internal_declare_ ## m () \
-{ \
- static translator_listener_record r; \
- add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \
-} \
- \
-ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); \
- \
-Listener \
-cl :: _get_ ## m ## _listener (void *me) \
-{ \
- cl *obj = (cl *) me; \
- return obj->GET_LISTENER (_listen_scm_ ## m); \
-} \
- \
-IMPLEMENT_LISTENER (cl, _listen_scm_ ## m) \
-void \
-cl::_listen_scm_ ## m (SCM sev) \
-{ \
- Stream_event *ev = unsmob_stream_event (sev); \
- protect_event (sev); \
- listen_ ## m (ev); \
-}
-
-/*
- This helper is only meaningful inside listen_* methods.
-*/
-extern bool internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function);
-#define ASSIGN_EVENT_ONCE(o,n) internal_event_assignment (&o, n, __FUNCTION__)
#endif /* TRANSLATOR_ICC */
+
*/
#include "std-string.hh"
-#include "input.hh"
+#include "input-smob.hh"
/* We don't use IMPLEMENT_TYPE_P, since the smobification part is
implemented separately from the class. */
(c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "input.hh"
-#include "source-file.hh"
+#include "input-smob.hh"
+
#include "std-string.hh"
#include "ly-smobs.icc"
static long input_tag;
static
-SCM mark_smob (SCM s)
+SCM mark_smob (SCM)
{
- Input *sc = (Input *) SCM_CELL_WORD_1 (s);
-
- if (Source_file *sf = sc->get_source_file ())
- return sf->self_scm ();
-
return SCM_EOL;
}
::message (s);
}
-
-void
-Input::programming_error (string s) const
-{
- message (_f ("programming error: %s", s.c_str ()));
- message (_ ("continuing, cross fingers") + "\n");
-}
-
-
void
Input::warning (string s) const
{
protected:
Spanner *text_spanner_;
- SCM long_text_;
- SCM short_text_;
-
- vector<Grob*> axis_groups_;
-
virtual void finalize ();
DECLARE_ACKNOWLEDGER (axis_group);
void process_music ();
- void start_spanner ();
- void consider_start_spanner ();
- void stop_spanner ();
};
Instrument_name_engraver::Instrument_name_engraver ()
{
text_spanner_ = 0;
-
- long_text_ = SCM_EOL;
- short_text_ = SCM_EOL;
}
void
Instrument_name_engraver::process_music ()
{
- consider_start_spanner ();
-}
-
-void
-Instrument_name_engraver::consider_start_spanner ()
-{
- SCM long_text = get_property ("instrumentName");
- SCM short_text = get_property ("shortInstrumentName");
-
- if (!(Text_interface::is_markup (long_text)
- || Text_interface::is_markup (short_text)))
+ if (!text_spanner_)
{
- long_text = get_property ("vocalName");
- short_text = get_property ("shortVocalName");
- }
+ SCM long_text = get_property ("instrument");
+ SCM short_text = get_property ("instr");
+
+ if (!(Text_interface::is_markup (long_text)
+ || Text_interface::is_markup (short_text)))
+ {
+ long_text = get_property ("vocalName");
+ short_text = get_property ("vocNam");
+ }
- if ((Text_interface::is_markup (long_text)
- || Text_interface::is_markup (short_text))
- && (!text_spanner_
- || short_text_ != short_text
- || long_text_ != long_text))
- {
- if (text_spanner_)
- stop_spanner ();
-
-
- short_text_ = short_text;
- long_text_ = long_text;
-
- start_spanner ();
- }
-}
-
-void
-Instrument_name_engraver::start_spanner ()
-{
- text_spanner_ = make_spanner ("InstrumentName", SCM_EOL);
+ if (Text_interface::is_markup (long_text)
+ || Text_interface::is_markup (short_text))
+ {
+ text_spanner_ = make_spanner ("InstrumentName", SCM_EOL);
- Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
- text_spanner_->set_bound (LEFT, col);
- text_spanner_->set_property ("text", short_text_);
- text_spanner_->set_property ("long-text", long_text_);
+ Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
+ text_spanner_->set_bound (LEFT, col);
+ text_spanner_->set_property ("text", short_text);
+ text_spanner_->set_property ("long-text", long_text);
+ }
+ }
}
-
void
Instrument_name_engraver::acknowledge_axis_group (Grob_info info)
{
- if (dynamic_cast<Spanner *> (info.grob ())
+ if (text_spanner_
+ && dynamic_cast<Spanner *> (info.grob ())
&& Axis_group_interface::has_axis (info.grob (), Y_AXIS)
&& (!Align_interface::has_interface (info.grob ())))
{
- axis_groups_.push_back (info.grob ());
+ Grob *staff = info.grob();
+ Pointer_group_interface::add_grob (text_spanner_, ly_symbol2scm ("elements"), staff);
+ Side_position_interface::add_support (text_spanner_, staff);
}
}
{
if (text_spanner_)
{
- stop_spanner ();
- }
-}
+ text_spanner_->set_bound (RIGHT,
+ unsmob_grob (get_property ("currentCommandColumn")));
-void
-Instrument_name_engraver::stop_spanner ()
-{
- for (vsize i = 0; i < axis_groups_.size (); i++)
- Pointer_group_interface::add_grob (text_spanner_, ly_symbol2scm ("elements"), axis_groups_[i]);
-
- text_spanner_->set_bound (RIGHT,
- unsmob_grob (get_property ("currentCommandColumn")));
-
- Pointer_group_interface::set_ordered (text_spanner_, ly_symbol2scm ("elements"), false);
+ Pointer_group_interface::set_ordered (text_spanner_, ly_symbol2scm ("elements"), false);
- System *system = get_root_system (text_spanner_);
+ System *system = get_root_system (text_spanner_);
- /*
- UGH, should handle this in Score_engraver.
- */
- if (system)
- Axis_group_interface::add_element (system, text_spanner_);
- else
- text_spanner_->programming_error ("can't find root system");
-
- text_spanner_ = 0;
+ /*
+ UGH, should handle this in Score_engraver.
+ */
+ if (system)
+ Axis_group_interface::add_element (system, text_spanner_);
+ else
+ text_spanner_->programming_error ("can't find root system");
+ }
}
#include "translator.icc"
"",
/* read */
- "currentCommandColumn "
- "shortInstrumentName "
- "instrumentName "
- "shortVocalName "
- "vocalName "
- ,
+ "vocNam vocalName instrument instr "
+ "currentCommandColumn",
/* write */ "");
+++ /dev/null
-/*
- instrument-switch-engraver.cc -- implement
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
-
-*/
-
-#include "engraver.hh"
-#include "item.hh"
-#include "translator.icc"
-
-
-class Instrument_switch_engraver : public Engraver
-{
-
- TRANSLATOR_DECLARATIONS(Instrument_switch_engraver);
-protected:
- Grob *text_;
- SCM cue_name_;
-
- void stop_translation_time_step ();
- void process_music ();
-};
-
-
-Instrument_switch_engraver::Instrument_switch_engraver ()
-{
- cue_name_ = SCM_EOL;
- text_ = 0;
-}
-
-void
-Instrument_switch_engraver::process_music ()
-{
- SCM cue_text = get_property ("instrumentCueName");
-
- if (!scm_is_eq (cue_name_, cue_text))
- {
- text_ = make_item ("InstrumentSwitch", SCM_EOL);
- text_->set_property ("text", cue_text);
- cue_name_ = cue_text;
- }
-}
-
-void
-Instrument_switch_engraver::stop_translation_time_step ()
-{
- text_ = 0;
-}
-
-ADD_TRANSLATOR(Instrument_switch_engraver,
- "Create a cue text for taking instrument.",
-
- "InstrumentSwitch ",
-
- "",
-
- "instrumentCueName",
-
- "");
#include "item.hh"
-#include "axis-group-interface.hh"
#include "paper-score.hh"
#include "warn.hh"
#include "paper-column.hh"
SCM vis = get_property ("break-visibility");
if (scm_is_vector (vis))
{
- bool visible = to_boolean (scm_c_vector_ref (vis, break_status_dir () + 1));
+ bool visible = to_boolean (scm_vector_ref (vis, scm_from_int (break_status_dir () + 1)));
if (!visible)
suicide ();
}
}
-bool
-Item::pure_is_visible (int start, int end) const
-{
- SCM vis = get_property ("break-visibility");
- if (scm_is_vector (vis))
- {
- int pos = 1;
- int pc_rank = Paper_column::get_rank (get_column ());
- if (pc_rank == start)
- pos = 2;
- else if (pc_rank == end)
- pos = 0;
- return to_boolean (scm_vector_ref (vis, scm_from_int (pos)));
- }
- return true;
-}
-
-Interval_t<int>
-Item::spanned_rank_iv ()
-{
- int c = get_column ()->get_rank ();
- return Interval_t<int> (c, c);
-}
-
void
Item::derived_mark () const
{
(c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
+#include "item.hh"
#include "bar-line.hh"
-#include "clef.hh"
+#include "staff-symbol-referencer.hh"
#include "context.hh"
#include "engraver.hh"
-#include "item.hh"
-#include "pitch.hh"
#include "protected-scm.hh"
-#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
+#include "clef.hh"
+#include "pitch.hh"
#include "translator.icc"
class Key_engraver : public Engraver
{
void create_key (bool);
- void read_event (Stream_event const *r);
+ void read_event (Music const *r);
- Stream_event *key_event_;
+ Music *key_event_;
Item *item_;
Item *cancellation_;
public:
protected:
virtual void initialize ();
virtual void finalize ();
+ virtual bool try_music (Music *event);
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (key_change);
DECLARE_ACKNOWLEDGER (clef);
DECLARE_ACKNOWLEDGER (bar_line);
};
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Key_engraver, key_change);
-void
-Key_engraver::listen_key_change (Stream_event *ev)
+bool
+Key_engraver::try_music (Music *event)
{
- /* do this only once, just to be on the safe side. */
- if (ASSIGN_EVENT_ONCE (key_event_, ev))
- read_event (key_event_);
+ if (event->is_mus_type ("key-change-event"))
+ {
+ /* do this only once, just to be on the safe side. */
+ if (!key_event_)
+ {
+ key_event_ = event;
+ read_event (key_event_);
+ }
+ return true;
+ }
+ return false;
}
void
}
void
-Key_engraver::read_event (Stream_event const *r)
+Key_engraver::read_event (Music const *r)
{
SCM p = r->get_property ("pitch-alist");
if (!scm_is_pair (p))
(c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
*/
-#include "audio-item.hh"
#include "music-sequence.hh"
+#include "audio-item.hh"
#include "performer.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
class Key_performer : public Performer
{
public:
~Key_performer ();
protected:
+ virtual bool try_music (Music *ev);
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (key_change);
private:
- Stream_event *key_ev_;
+ Music *key_ev_;
Audio_key *audio_;
};
{
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Key_performer, key_change);
-void
-Key_performer::listen_key_change (Stream_event *ev)
+bool
+Key_performer::try_music (Music *ev)
{
if (!key_ev_)
key_ev_ = ev;
+
+ return true;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Key_performer,
"", "",
"key-change-event",
using namespace std;
/* for qsort */
-bool tab_less (Keyword_ent const &p1, Keyword_ent const &p2)
+int tabcmp (Keyword_ent const &p1, Keyword_ent const &p2)
{
- return strcmp (p1.name_, p2.name_) < 0;
+ return strcmp (p1.name_, p2.name_);
}
Keyword_table::Keyword_table (Keyword_ent *tab)
while (tab->name_)
table_.push_back (*tab++);
- vector_sort (table_, tab_less);
+ vector_sort (table_, tabcmp);
}
vsize
{
Keyword_ent e;
e.name_ = s;
- vsize idx = binary_search (table_, e, tab_less);
+ vsize idx = binary_search (table_, e, tabcmp);
if (idx != VPOS)
return table_[idx].tokcode_;
return VPOS;
#include "engraver.hh"
#include "item.hh"
#include "pointer-group-interface.hh"
-#include "stream-event.hh"
#include "translator.icc"
class Laissez_vibrer_engraver : public Engraver
{
- Stream_event *event_;
+
+ Music *event_;
Grob *lv_column_;
vector<Grob*> lv_ties_;
void stop_translation_timestep ();
DECLARE_ACKNOWLEDGER (note_head);
-protected:
- DECLARE_TRANSLATOR_LISTENER (laissez_vibrer);
+
+ virtual bool try_music (Music *);
public:
TRANSLATOR_DECLARATIONS (Laissez_vibrer_engraver);
};
lv_ties_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Laissez_vibrer_engraver, laissez_vibrer);
-void
-Laissez_vibrer_engraver::listen_laissez_vibrer (Stream_event *ev)
+bool
+Laissez_vibrer_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ event_ = m;
+ return true;
}
void
lv_ties_.push_back (lv_tie);
}
+
+
ADD_ACKNOWLEDGER (Laissez_vibrer_engraver, note_head);
ADD_TRANSLATOR (Laissez_vibrer_engraver,
/* doc */ "Create Laissez vibrer items.",
sqx += sqr (x);
sxy += x*y;
}
-
- int count = input.size ();
+ int N = input.size ();
*coef = 0.0;
*offset = 0.;
- Real den = (count * sqx - sqr (sx));
- if (!count || !den)
+ Real den = (N * sqx - sqr (sx));
+ if (!N || !den)
{
programming_error ("minimise_least_squares (): Nothing to minimise");
*coef = 0.0;
- *offset = count ? sy / count : 0.0;
+ *offset = N ? sy / N : 0.0;
}
else
{
- *coef = (count * sxy - sx * sy) / den;
- *offset = (sy - (*coef) * sx) / count;
+ *coef = (N *sxy - sx * sy) / den;
+ *offset = (sy - (*coef) * sx) / N;
}
}
class Ledger_line_engraver : public Engraver
{
Spanner *span_;
- vector<Grob*> ledgered_grobs_;
-
+
public:
TRANSLATOR_DECLARATIONS (Ledger_line_engraver);
void start_spanner ();
void stop_spanner ();
- void stop_translation_timestep ();
};
Ledger_line_engraver::Ledger_line_engraver ()
Ledger_line_engraver::start_spanner ()
{
assert (!span_);
-
span_ = make_spanner ("LedgerLineSpanner", SCM_EOL);
- span_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
-}
-
-void
-Ledger_line_engraver::stop_translation_timestep ()
-{
- if (span_)
- {
- for (vsize i = 0; i < ledgered_grobs_.size (); i++)
- {
- if (!to_boolean (ledgered_grobs_[i]->get_property ("no-ledgers")))
- Pointer_group_interface::add_grob (span_,
- ly_symbol2scm ("note-heads"),
- ledgered_grobs_[i]);
- }
- }
- ledgered_grobs_.clear ();
+ span_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
}
void
Spanner *sym = dynamic_cast<Spanner *> (s.grob ());
if (!span_
- || (span_->get_bound (LEFT) != sym->get_bound (LEFT)))
+ || (span_->get_bound (LEFT) != sym->get_bound (LEFT)
+ && sym->get_bound (LEFT)))
{
stop_spanner ();
start_spanner ();
void
Ledger_line_engraver::acknowledge_ledgered (Grob_info s)
{
- ledgered_grobs_.push_back (s.grob ());
+ if (span_)
+ {
+ if (!to_boolean (s.grob ()->get_property ("no-ledgers")))
+ Pointer_group_interface::add_grob (span_, ly_symbol2scm ("note-heads"),
+ s.grob ());
+ }
}
#include "translator.icc"
#include "lily-lexer.hh"
#include "lilypond-input-version.hh"
#include "main.hh"
-#include "music.hh"
#include "music-function.hh"
#include "parse-scm.hh"
#include "parser.hh"
void strip_trailing_white (string&);
void strip_leading_white (string&);
string lyric_fudge (string s);
+int music_function_type (SCM);
SCM lookup_markup_command (string s);
bool is_valid_version (string s);
%option never-interactive
%option warn
-%x extratoken
%x chords
%x figures
%x incl
%x markup
%x notes
%x quote
-%x sourcefileline
%x sourcefilename
%x version
AA {A}|_
N [0-9]
AN {AA}|{N}
-ANY_CHAR (.|\n)
PUNCT [?!:'`]
ACCENT \\[`'"^]
NATIONAL [\001-\006\021-\027\031\036\200-\377]
// windows-suck-suck-suck
}
-<extratoken>{ANY_CHAR} {
- /* Generate a token without swallowing anything */
-
- /* First unswallow the eaten character */
- add_lexed_char (-YYLeng ());
- yyless (0);
-
- /* produce requested token */
- int type = extra_token_types_.back ();
- extra_token_types_.pop_back ();
- if (extra_token_types_.empty ())
- yy_pop_state ();
-
- return type;
-}
-
<INITIAL,chords,lyrics,figures,notes>{BOM_UTF8} {
if (this->lexloc->line_number () != 1 || this->lexloc->column_number () != 0)
{
}
}
-<INITIAL,notes,figures,chords,markup>{
- \" {
- start_quote ();
- }
-}
-
<INITIAL,chords,lyrics,notes,figures>\\version{WHITE}* {
yy_push_state (version);
}
<INITIAL,chords,lyrics,notes,figures>\\sourcefilename{WHITE}* {
yy_push_state (sourcefilename);
}
-<INITIAL,chords,lyrics,notes,figures>\\sourcefileline{WHITE}* {
- yy_push_state (sourcefileline);
-}
<version>\"[^"]*\" { /* got the version number */
string s (YYText () + 1);
s = s.substr (0, s.rfind ('\"'));
yy_pop_state ();
-
- SCM top_scope = scm_car (scm_last_pair (scopes_));
- scm_module_define (top_scope, ly_symbol2scm ("version-seen"), SCM_BOOL_T);
-
if (!is_valid_version (s))
return INVALID;
+ SCM top_scope = scm_car (scm_last_pair (scopes_));
+ scm_module_define (top_scope, ly_symbol2scm ("version-seen?"), SCM_BOOL_T);
}
<sourcefilename>\"[^"]*\" {
scm_makfrom0str (s.c_str ()));
}
-
-<sourcefileline>{INT} {
- int i;
- sscanf (YYText (), "%d", &i);
-
-// this->set_debug (1);
- yy_pop_state ();
- this->here_input ().get_source_file ()->set_line (here_input ().start (), i);
-}
-
<version>. {
LexerError (_ ("quoted string expected after \\version").c_str ());
yy_pop_state ();
LexerError (_ ("quoted string expected after \\sourcefilename").c_str ());
yy_pop_state ();
}
-<sourcefileline>. {
- LexerError (_ ("integer expected after \\sourcefileline").c_str ());
- yy_pop_state ();
-}
<longcomment>{
[^\%]* {
}
}
yylval.scm = sval;
- return SCM_TOKEN;
+ return SCM_T;
}
<INITIAL,notes,lyrics>{
- \<\< {
+ \<\< {
return DOUBLE_ANGLE_OPEN;
}
- \>\> {
+ \>\> {
return DOUBLE_ANGLE_CLOSE;
}
}
-
-<INITIAL,notes>{
- \< {
- return ANGLE_OPEN;
- }
- \> {
- return ANGLE_CLOSE;
- }
-}
-
<figures>{
_ {
return FIGURE_SPACE;
yylval.i = String_convert::dec2int (string (YYText () +1));
return E_UNSIGNED;
}
+ \" {
+ start_quote ();
+ }
}
-<quote,lyric_quote>{
+\" {
+ start_quote ();
+}
+<quote>{
\\{ESCAPED} {
*yylval.string += to_string (escaped_char (YYText ()[1]));
}
string *sp = yylval.string;
yylval.scm = scm_makfrom0str (sp->c_str ());
delete sp;
- return is_lyric_state () ? LYRICS_STRING : STRING;
+ return STRING;
+ }
+ . {
+ *yylval.string += YYText ();
+ }
+}
+<lyric_quote>{
+ \\{ESCAPED} {
+ *yylval.string += to_string (escaped_char (YYText ()[1]));
+ }
+ [^\\"]+ {
+ *yylval.string += YYText ();
+ }
+ \" {
+
+ yy_pop_state ();
+
+ /* yylval is union. Must remember STRING before setting SCM*/
+ string *sp = yylval.string;
+ yylval.scm = scm_makfrom0str (sp->c_str ());
+ delete sp;
+ return LYRICS_STRING;
}
. {
*yylval.string += YYText ();
yylval.i = String_convert::dec2int (string (YYText ()));
return UNSIGNED;
}
+ \" {
+ start_quote ();
+ }
- {
return CHORD_MINUS;
}
<markup>{
+ \" {
+ start_quote ();
+ }
\\score {
return SCORE;
}
}
}
-<*><<EOF>> {
+<<EOF>> {
if (is_main_input_)
{
is_main_input_ = false;
%%
-/* Make the lexer generate a token of the given type as the next token.
- TODO: make it possible to define a value for the token as well */
-void
-Lily_lexer::push_extra_token (int token_type)
-{
- if (extra_token_types_.empty ())
- {
- if (YY_START != extratoken)
- hidden_state_ = YY_START;
- yy_push_state (extratoken);
- }
- extra_token_types_.push_back (token_type);
-}
-
void
Lily_lexer::push_chord_state (SCM tab)
{
{
if (YYSTATE == notes || YYSTATE == chords)
pitchname_tab_stack_ = scm_cdr (pitchname_tab_stack_);
-
yy_pop_state ();
}
if (is_music_function (sid))
{
yylval.scm = get_music_function_transform (sid);
-
- SCM s = scm_object_property (yylval.scm, ly_symbol2scm ("music-function-signature"));
- push_extra_token (EXPECT_NO_MORE_ARGS);
- for (; scm_is_pair (s); s = scm_cdr (s))
- {
- if (scm_car (s) == ly_music_p_proc)
- push_extra_token (EXPECT_MUSIC);
- else if (scm_car (s) == ly_lily_module_constant ("markup?"))
- push_extra_token (EXPECT_MARKUP);
- else if (ly_is_procedure (scm_car (s)))
- push_extra_token (EXPECT_SCM);
- else programming_error ("Function parameter without type-checking predicate");
- }
- return MUSIC_FUNCTION;
+ return music_function_type (yylval.scm);
}
if (sid != SCM_UNDEFINED)
return STRING;
}
-int
-Lily_lexer::get_state () const
-{
- if (YY_START == extratoken)
- return hidden_state_;
- else
- return YY_START;
-}
-
bool
Lily_lexer::is_note_state () const
{
- return get_state () == notes;
+ return YY_START == notes;
}
bool
Lily_lexer::is_chord_state () const
{
- return get_state () == chords;
+ return YY_START == chords;
}
bool
Lily_lexer::is_lyric_state () const
{
- return get_state () == lyrics;
+ return YY_START == lyrics;
}
bool
Lily_lexer::is_figure_state () const
{
- return get_state () == figures;
+ return YY_START == figures;
}
/*
return scm_call_1 (proc, scm_makfrom0str (s.c_str ()));
}
+struct Parser_signature
+{
+ char *symbol;
+ int token_type;
+};
+static SCM signature_hash_table;
+
+static void init_signature_hash_table ()
+{
+ signature_hash_table = scm_gc_protect_object (scm_c_make_hash_table (31));
+ Parser_signature sigs[] = {
+ {"scm", MUSIC_FUNCTION_SCM},
+ {"music", MUSIC_FUNCTION_MUSIC},
+ {"scm-music", MUSIC_FUNCTION_SCM_MUSIC},
+ {"scm-scm", MUSIC_FUNCTION_SCM_SCM},
+ {"music-music", MUSIC_FUNCTION_MUSIC_MUSIC},
+ {"scm-music-music", MUSIC_FUNCTION_SCM_MUSIC_MUSIC},
+ {"scm-scm-music-music", MUSIC_FUNCTION_SCM_SCM_MUSIC_MUSIC},
+ {"scm-scm-music", MUSIC_FUNCTION_SCM_SCM_MUSIC},
+ {"scm-scm-scm-music", MUSIC_FUNCTION_SCM_SCM_SCM_SCM_MUSIC},
+ {"scm-scm-scm-scm-music", MUSIC_FUNCTION_SCM_SCM_SCM_MUSIC},
+ {"scm-scm-scm", MUSIC_FUNCTION_SCM_SCM_SCM},
+ {"markup", MUSIC_FUNCTION_MARKUP},
+ {"markup-music", MUSIC_FUNCTION_MARKUP_MUSIC},
+ {"markup-markup", MUSIC_FUNCTION_MARKUP_MARKUP},
+ {"markup-music-music", MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC},
+ {"markup-markup-music", MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC},
+ {"noarg", MUSIC_FUNCTION},
+ {0,0}
+ };
+
+ for (int i = 0; sigs[i].symbol; i++)
+ scm_hashq_set_x (signature_hash_table, scm_gc_protect_object (ly_symbol2scm (sigs[i].symbol)),
+ scm_from_int (sigs[i].token_type));
+}
+
+int
+music_function_type (SCM func)
+{
+ if (!signature_hash_table)
+ init_signature_hash_table ();
+
+ SCM type = scm_object_property (func, ly_symbol2scm ("music-function-signature-keyword"));
+ SCM token_type = scm_hashq_ref (signature_hash_table, type, SCM_BOOL_F);
+ if (!scm_is_number (token_type))
+ {
+ programming_error (_ ("can't find signature for music function"));
+ return MUSIC_FUNCTION_SCM;
+ }
+
+ return scm_to_int (token_type);
+}
+
/* Shut up lexer warnings. */
#if YY_STACK_USED
#include "international.hh"
#include "note-head.hh"
#include "rest.hh"
+#include "score-context.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
brew_ligature_primitive_proc = SCM_EOL;
}
-void
-Ligature_engraver::listen_ligature (Stream_event *ev)
+bool
+Ligature_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (events_drul_[d], ev);
+ if (m->is_mus_type ("ligature-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ events_drul_[d] = m;
+ return true;
+ }
+ return false;
}
void
if (ligature_)
{
primitives_.push_back (info);
- if (info.grob () && brew_ligature_primitive_proc != SCM_EOL)
+ if (info.grob () && (brew_ligature_primitive_proc != SCM_EOL))
{
info.grob ()->set_property ("stencil", brew_ligature_primitive_proc);
}
{
if (ligature_)
{
- info.event_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest"));
+ info.music_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest"));
prev_start_event_->origin ()->warning (_ ("ligature was started here"));
// TODO: maybe better should stop ligature here rather than
// ignoring the rest?
if (be_verbose_global)
progress_indication ("[" + s);
- vector<char> chars = gulp_file (s, size);
- string result (&chars[0], chars.size ());
+ int n = size;
+ char *str = gulp_file (s, &n);
+ string result (str, n);
+ delete[] str;
if (be_verbose_global)
progress_indication ("]");
{
assert (scm_is_string (str));
return string (scm_i_string_chars (str),
- (int) scm_i_string_length (str));
+ (int) scm_i_string_length (str));
}
char *
return o;
}
-string
-robust_scm2string (SCM k, string s)
-{
- if (scm_is_string (k))
- s = ly_scm2string (k);
- return s;
-}
-
int
robust_scm2int (SCM k, int o)
{
cxx_id = replace_all (cxx_id, '_', '-');
return cxx_id;
}
-
{"time", TIME_T},
{"times", TIMES},
{"transpose", TRANSPOSE},
+ {"transposition", TRANSPOSITION},
{"type", TYPE},
{"unset", UNSET},
{"with", WITH},
#include "file-name-map.hh"
#include "file-name.hh"
#include "file-path.hh"
-#include "input.hh"
#include "international.hh"
#include "lily-lexer.hh"
#include "lily-parser.hh"
"Upon failure, throw @code{ly-file-failed} key.")
{
SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG1, __FUNCTION__, "string");
- string file = ly_scm2string (name);
+ char const *file = scm_i_string_chars (name);
char const *extensions[] = {"ly", "", 0};
string file_name = global_path.find (file, extensions);
if (!output_name_global.empty ())
{
-
/* Interpret --output=DIR to mean --output=DIR/BASE. */
string dir;
if (is_dir (output_name_global))
output_name_global = "";
}
else
- {
- File_name out (output_name_global);
- if (is_dir (out.dir_part ()))
- {
- dir = out.dir_part ();
- out_file_name = out.file_part ();
- }
- }
-
+ dir = dir_name (output_name_global);
if (dir != "" && dir != "." && dir != get_working_directory ())
{
global_path.prepend (get_working_directory ());
exit (2);
}
- if ((file_name != "-") && file_name.empty ())
+ if ((file_name != "-") && global_path.find (file_name).empty ())
{
- warning (_f ("can't find file: `%s'", file));
+ warning (_f ("can't find file: `%s'", file_name));
scm_throw (ly_symbol2scm ("ly-file-failed"),
scm_list_1 (scm_makfrom0str (file_name.c_str ())));
}
parser->parse_file (init, file_name, out_file);
bool error = parser->error_level_;
-
parser->unprotect ();
+ parser = 0;
if (error)
/* TODO: pass renamed input file too. */
scm_throw (ly_symbol2scm ("ly-file-failed"),
return scm_makfrom0str (p->output_basename_.c_str ());
}
-LY_DEFINE (ly_parser_error, "ly:parser-error",
- 2, 1, 0, (SCM parser, SCM msg, SCM input),
- "Display an error message, and make the parser fail")
-{
- Lily_parser *p = unsmob_lily_parser (parser);
- SCM_ASSERT_TYPE (p, parser, SCM_ARG1, __FUNCTION__, "Lilypond parser");
- SCM_ASSERT_TYPE (scm_is_string (msg), msg, SCM_ARG2, __FUNCTION__, "string");
- string s = ly_scm2string (msg);
-
- Input *i = unsmob_input (input);
- if (i)
- p->parser_error (*i, s);
- else
- p->parser_error (s);
- return parser;
-}
lexer_->main_input_name_ = "<string>";
lexer_->is_main_input_ = true;
+ set_yydebug (0);
lexer_->new_input (lexer_->main_input_name_, ly_code, sources_);
SCM mod = lexer_->set_current_scope ();
scm_from_double (off),
scm_from_double (to[X_AXIS] - from[X_AXIS]),
scm_from_double (to[Y_AXIS] - from[Y_AXIS]),
- scm_from_double (0.0),
SCM_UNDEFINED);
Box box;
"@code{dashed-line}, @code{trill}, \n"
"@code{dotted-line} or @code{zigzag}.\n"
"\n",
-
- "arrow "
- "gap "
- "thickness "
- "zigzag-length "
- "zigzag-width "
- );
+ "gap zigzag-width zigzag-length thickness arrow");
#include "ly-smobs.icc"
#include "warn.hh"
-Listener::Listener ()
-{
- target_ = 0;
- type_ = 0;
-}
-
Listener::Listener (const void *target, Listener_function_table *type)
{
target_ = (void *)target;
Listener::mark_smob (SCM sm)
{
Listener *me = (Listener *) SCM_CELL_WORD_1 (sm);
- if (me->type_)
- (me->type_->mark_callback) (me->target_);
+ (me->type_->mark_callback) (me->target_);
return SCM_EOL;
}
int
-Listener::print_smob (SCM, SCM p, scm_print_state*)
+Listener::print_smob (SCM s, SCM p, scm_print_state*)
{
scm_puts ("#<Listener>", p);
return 1;
#define FUNC_NAME __FUNCTION__
-
+static SCM
+accumulate_symbol (void *closure, SCM key, SCM val, SCM result)
+{
+ (void) closure;
+ (void) val;
+ return scm_cons (key, result);
+}
SCM
ly_module_symbols (SCM mod)
SCM_VALIDATE_MODULE (1, mod);
SCM obarr = SCM_MODULE_OBARRAY (mod);
- return ly_hash_table_keys (obarr);
+ return scm_internal_hash_fold ((Hash_closure_function) & accumulate_symbol,
+ NULL, SCM_EOL, obarr);
}
static SCM
Lyric_combine_music_iterator::set_busy (SCM se)
{
Stream_event *e = unsmob_stream_event (se);
+ SCM mus = e->get_property ("music");
+ Music *m = unsmob_music (mus);
+ assert (m);
- if (e->in_event_class ("note-event") || e->in_event_class ("cluster-note-event"))
+ if (m->is_mus_type ("note-event") || m->is_mus_type ("cluster-note-event"))
busy_ = true;
}
{
if (music_context_)
{
- music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event"));
+ music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext"));
}
music_context_ = to;
if (to)
{
- to->event_source()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event"));
+ to->event_source()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
lyrics_context_->set_property ("associatedVoiceContext", to->self_scm ());
}
}
}
/*
- Look for a suitable voice to align lyrics to.
-
- Returns 0 if nothing should change; i.e., if we already listen to the
- right voice, or if we don't yet listen to a voice but no appropriate
- voice could be found.
+Look for a suitable voice to align lyrics to.
*/
Context *
Lyric_combine_music_iterator::find_voice ()
void
Lyric_combine_music_iterator::process (Moment)
{
- /* see if associatedVoice has been changed */
- Context *new_voice = find_voice ();
- if (new_voice)
- set_music_context (new_voice);
-
+ find_voice ();
if (!music_context_)
return;
#include "multi-measure-rest.hh"
#include "note-head.hh"
#include "rest.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
/**
Generate texts for lyric syllables. We only do one lyric at a time.
{
protected:
void stop_translation_timestep ();
+ virtual bool try_music (Music *);
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (lyric);
public:
TRANSLATOR_DECLARATIONS (Lyric_engraver);
private:
- Stream_event *event_;
+ Music *event_;
Item *text_;
Item *last_text_;
event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Lyric_engraver, lyric);
-void
-Lyric_engraver::listen_lyric (Stream_event *ev)
+bool
+Lyric_engraver::try_music (Music *r)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ if (!event_)
+ {
+ event_ = r;
+ return true;
+ }
+ return false;
}
void
event_ = 0;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Lyric_engraver,
/* doc */ "",
/* create */ "LyricText",
#include "note-head.hh"
#include "pointer-group-interface.hh"
-MAKE_SCHEME_CALLBACK (Lyric_extender, print, 1);
-SCM
+MAKE_SCHEME_CALLBACK (Lyric_extender, print, 1)
+ SCM
Lyric_extender::print (SCM smob)
{
Spanner *me = unsmob_spanner (smob);
right_point = max (right_point, heads.back ()->extent (common, X_AXIS)[RIGHT]);
Real h = sl * robust_scm2double (me->get_property ("thickness"), 0);
- Drul_array<Real> paddings (robust_scm2double (me->get_property ("left-padding"), h),
- robust_scm2double (me->get_property ("right-padding"), h));
+ Real pad = 2* h;
if (right_text)
- right_point = min (right_point, (robust_relative_extent (right_text, common, X_AXIS)[LEFT] - paddings[RIGHT]));
+ right_point = min (right_point, (robust_relative_extent (right_text, common, X_AXIS)[LEFT] - pad));
/* run to end of line. */
if (me->get_bound (RIGHT)->break_status_dir ())
- right_point = max (right_point, (robust_relative_extent (me->get_bound (RIGHT), common, X_AXIS)[LEFT] - paddings[RIGHT]));
+ right_point = max (right_point, (robust_relative_extent (me->get_bound (RIGHT), common, X_AXIS)[LEFT] - pad));
- left_point += paddings[LEFT];
+ left_point += pad;
Real w = right_point - left_point;
if (w < 1.5 * h)
ADD_INTERFACE (Lyric_extender, "lyric-extender-interface",
"The extender is a simple line at the baseline of the lyric "
"that helps show the length of a melissima (tied/slurred note).",
-
- "heads "
- "left-padding "
- "next "
- "right-padding "
- "thickness "
- );
+ "next thickness heads");
#include "audio-item.hh"
#include "performer.hh"
-#include "stream-event.hh"
-#include "translator.icc"
+#include "music.hh"
class Lyric_performer : public Performer
{
TRANSLATOR_DECLARATIONS (Lyric_performer);
protected:
+ virtual bool try_music (Music *event);
void stop_translation_timestep ();
- void process_music ();
- DECLARE_TRANSLATOR_LISTENER (lyric);
+ void process_music ();
+
private:
- vector<Stream_event *> events_;
+ vector<Music*> events_;
Audio_text *audio_;
};
{
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
events_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Lyric_performer, lyric);
-void
-Lyric_performer::listen_lyric (Stream_event *event)
+bool
+Lyric_performer::try_music (Music *event)
{
- events_.push_back (event);
+ if (event->is_mus_type ("lyric-event"))
+ {
+ events_.push_back (event);
+ return true;
+ }
+ return false;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Lyric_performer, "", "", "lyric-event",
"", "");
bool relocate_binary =
-#if 1
+#if ARGV0_RELOCATION
true;
#else
false
*tail = scm_cons (scm_makfrom0str (arg), SCM_EOL);
tail = SCM_CDRLOC (*tail);
}
-
delete option_parser;
option_parser = 0;
break;
case 'f':
- {
- vector<string> components
- = string_split (option_parser->optional_argument_str0_, ',');
- for (vsize i = 0; i < components.size (); i++)
- add_output_format (components[i]);
- }
+ output_format_global = option_parser->optional_argument_str0_;
break;
case 'H':
#include "grob-array.hh"
#include "international.hh"
#include "item.hh"
-#include "stream-event.hh"
#include "text-interface.hh"
#include "warn.hh"
-#include "translator.icc"
-
/**
put stuff over or next to bars. Examples: bar numbers, marginal notes,
rehearsal marks.
class Mark_engraver : public Engraver
{
- void create_items (Stream_event *);
+ void create_items (Music *);
Item *text_;
- Stream_event *mark_ev_;
+ Music *mark_ev_;
public:
TRANSLATOR_DECLARATIONS (Mark_engraver);
protected:
+ virtual bool try_music (Music *ev);
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (mark);
DECLARE_ACKNOWLEDGER (break_alignment);
DECLARE_ACKNOWLEDGER (break_aligned);
};
}
void
-Mark_engraver::create_items (Stream_event *ev)
+Mark_engraver::create_items (Music *ev)
{
if (text_)
return;
text_ = make_item ("RehearsalMark", ev->self_scm ());
}
-IMPLEMENT_TRANSLATOR_LISTENER (Mark_engraver, mark);
-void
-Mark_engraver::listen_mark (Stream_event *ev)
+bool
+Mark_engraver::try_music (Music *r)
{
- ASSIGN_EVENT_ONCE (mark_ev_, ev);
+ mark_ev_ = r;
+ return true;
}
/*
}
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Mark_engraver, break_aligned);
ADD_ACKNOWLEDGER (Mark_engraver, break_alignment);
#include "engraver.hh"
#include "grob.hh"
#include "context.hh"
-#include "music.hh"
#include "translator.icc"
-/* Remove this translator. */
-
/**
Signal existence of melismas.
*/
ADD_TRANSLATOR (Melisma_translator,
/* doc */ "This translator collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code. ",
/* create */ "",
- /* accept */ "",
- /* read */
- "beamMelismaBusy "
- "melismaBusy "
- "melismaBusyProperties "
- "slurMelismaBusy "
- "tieMelismaBusy "
- ,
-
+ /* accept */ "melisma-playing-event melisma-span-event",
+ /* read */ "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy",
/* write */ "");
#include "font-interface.hh"
#include "international.hh"
#include "mensural-ligature.hh"
+#include "music.hh"
#include "note-column.hh"
#include "note-head.hh"
#include "output-def.hh"
#include "paper-column.hh"
-#include "pitch.hh"
#include "rhythmic-head.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
/*
* TODO: accidentals are aligned with the first note;
* they must appear ahead.
protected:
virtual Spanner *create_ligature_spanner ();
virtual void build_ligature (Spanner *ligature, vector<Grob_info> primitives);
- DECLARE_TRANSLATOR_LISTENER (ligature);
-
+
public:
TRANSLATOR_DECLARATIONS (Mensural_ligature_engraver);
void fold_up_primitives (vector<Grob_info> primitives);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Mensural_ligature_engraver, ligature);
-void
-Mensural_ligature_engraver::listen_ligature (Stream_event *ev)
-{
- Ligature_engraver::listen_ligature (ev);
-}
-
Mensural_ligature_engraver::Mensural_ligature_engraver ()
{
brew_ligature_primitive_proc =
Item *primitive = dynamic_cast<Item *> (info.grob ());
int duration_log = Note_head::get_balltype (primitive);
- Stream_event *nr = info.event_cause ();
+ Music *nr = info.music_cause ();
/*
ugh. why not simply check for pitch?
*/
- if (!nr->in_event_class ("note-event"))
+ if (!nr->is_mus_type ("note-event"))
{
nr->origin ()->warning
(_f ("cannot determine pitch of ligature primitive -> skipping"));
}
// b. descendens longa or brevis
else if (i < s - 1
- && (unsmob_pitch (primitives[i + 1].event_cause ()
+ && (unsmob_pitch (primitives[i + 1].music_cause ()
->get_property ("pitch"))->steps () < pitch)
&& duration_log > -3)
{
fold_up_primitives (primitives);
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Mensural_ligature_engraver, rest);
ADD_ACKNOWLEDGER (Mensural_ligature_engraver, note_head);
ADD_TRANSLATOR (Mensural_ligature_engraver,
if (primitive & MLP_FLEXA)
{
- delta_pitch = robust_scm2int (me->get_property ("delta-position"),
+ delta_pitch = robust_scm2int (me->get_property ("delta-pitch"),
0);
width
= robust_scm2double (me->get_property ("flexa-width"), 2.0 * staff_space);
SCM join_right_scm = me->get_property ("join-right-amount");
- if (scm_is_pair (join_right_scm))
+ if (join_right_scm != SCM_EOL)
{
int join_right = scm_to_int (join_right_scm);
if (join_right)
ADD_INTERFACE (Mensural_ligature, "mensural-ligature-interface",
"A mensural ligature",
-
- "delta-position "
- "flexa-width "
- "head-width "
- "join-right-amount "
- "primitive "
- "thickness"
- );
-
+ "delta-pitch flexa-width head-width join-right-amount " // "add-join "
+ "primitive thickness");
#include "engraver.hh"
+#include "note-column.hh"
#include "context.hh"
-#include "duration.hh"
#include "grob-array.hh"
-#include "item.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
/**
put stuff over or next to bars. Examples: bar numbers, marginal notes,
protected:
Item *text_;
Grob *bar_line_;
+ Music *mark_ev_;
- SCM last_duration_;
- SCM last_count_;
-
+ void create_items (Music *);
protected:
- virtual void derived_mark () const;
void stop_translation_timestep ();
+ virtual bool try_music (Music *ev);
void process_music ();
};
Metronome_mark_engraver::Metronome_mark_engraver ()
{
text_ = 0;
- last_duration_ = SCM_EOL;
- last_count_ = SCM_EOL;
-}
-
-void
-Metronome_mark_engraver::derived_mark () const
-{
- scm_gc_mark (last_count_);
- scm_gc_mark (last_duration_);
+ mark_ev_ = 0;
}
void
text_ = 0;
}
+ mark_ev_ = 0;
+}
+
+void
+Metronome_mark_engraver::create_items (Music *rq)
+{
+ if (text_)
+ return;
+
+ text_ = make_item ("MetronomeMark", rq->self_scm ());
+}
+
+bool
+Metronome_mark_engraver::try_music (Music *r)
+{
+ mark_ev_ = r;
+ return true;
}
void
Metronome_mark_engraver::process_music ()
{
- SCM count = get_property ("tempoUnitCount");
- SCM duration = get_property ("tempoUnitDuration");
-
- if (unsmob_duration (duration)
- && scm_is_number (count)
- && !(ly_is_equal (count, last_count_)
- && ly_is_equal (duration, last_duration_)))
+ if (mark_ev_)
{
- text_ = make_item ("MetronomeMark", SCM_EOL);
+ create_items (mark_ev_);
SCM proc = get_property ("metronomeMarkFormatter");
- SCM result = scm_call_3 (proc,
- duration,
- count,
+ SCM result = scm_call_2 (proc, mark_ev_->self_scm (),
context ()->self_scm ());
text_->set_property ("text", result);
}
-
- last_duration_ = duration;
- last_count_ = count;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Metronome_mark_engraver,
/* doc */ "Engrave metro nome marking. This delegates the formatting work "
"to the function in the metronomeMarkFormatter property. "
"The staves are taken from the @code{stavesFound} property, "
"which is maintained by @code{@ref{Staff_collecting_engraver}}. ",
/* create */ "MetronomeMark",
- /* accept */ "",
-
- /* read */
- "stavesFound "
- "metronomeMarkFormatter "
- "tempoUnitDuration "
- "tempoUnitCount "
- ,
-
+ /* accept */ "metronome-change-event",
+ /* read */ "stavesFound metronomeMarkFormatter",
/* write */ "");
--- /dev/null
+/*
+ midi-def.cc -- implement midi output def functions
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+*/
+
+
+#include "misc.hh"
+#include "output-def.hh"
+#include "moment.hh"
+#include "warn.hh"
+#include "scm-hash.hh"
+
+int
+get_tempo (Output_def *def,
+ Moment one_beat_mom)
+{
+ SCM wis = ly_symbol2scm ("whole-in-seconds");
+ Moment *w = unsmob_moment (def->lookup_variable (wis));
+
+ Moment wholes_per_min = Moment (60);
+ if (!w)
+ {
+ programming_error ("wholes-in-seconds not set.");
+ wholes_per_min /= 4;
+ }
+ else
+ wholes_per_min /= *w;
+
+ Rational beats_per_min = (wholes_per_min / one_beat_mom).main_part_;
+ return beats_per_min.to_int ();
+}
+
+void
+set_tempo (Output_def *def,
+ Moment one_beat_mom,
+ int beats_per_minute_i)
+{
+ Moment beats_per_second = Moment (beats_per_minute_i) / Moment (60);
+
+ Moment m = Moment (1) / Moment (beats_per_second * one_beat_mom);
+ def->set_variable (ly_symbol2scm ("whole-in-seconds"), m.smobbed_copy ());
+}
+
{
Rational rat_dt = (delta_mom_.main_part_ * Rational (384)
+ delta_mom_.grace_part_ * Rational (100)) * Rational (4);
- int delta = rat_dt.to_int ();
+ int delta_i = rat_dt.to_int ();
- string delta_string = Midi_item::i2varint_string (delta);
+ string delta_string = Midi_item::i2varint_string (delta_i);
string midi_string = midi_->to_string ();
assert (midi_string.length ());
return delta_string + midi_string;
}
-Midi_header::Midi_header (int format, int tracks, int clocks_per_4)
+Midi_header::Midi_header (int format_i, int tracks_i, int clocks_per_4_i)
{
string str;
- string format_string = String_convert::int2hex (format, 4, '0');
+ string format_string = String_convert::int2hex (format_i, 4, '0');
str += String_convert::hex2bin (format_string);
- string tracks_string = String_convert::int2hex (tracks, 4, '0');
+ string tracks_string = String_convert::int2hex (tracks_i, 4, '0');
str += String_convert::hex2bin (tracks_string);
- string tempo_string = String_convert::int2hex (clocks_per_4, 4, '0');
+ string tempo_string = String_convert::int2hex (clocks_per_4_i, 4, '0');
str += String_convert::hex2bin (tempo_string);
set ("MThd", str, "");
}
Midi_item::Midi_item ()
-{
-}
-
-Midi_channel_item::~Midi_channel_item ()
-{
- channel_ = 0;
-}
-
-Midi_channel_item::Midi_channel_item ()
{
channel_ = 0;
}
string
Midi_item::i2varint_string (int i)
{
- int buffer = i & 0x7f;
+ int buffer_i = i & 0x7f;
while ((i >>= 7) > 0)
{
- buffer <<= 8;
- buffer |= 0x80;
- buffer += (i & 0x7f);
+ buffer_i <<= 8;
+ buffer_i |= 0x80;
+ buffer_i += (i & 0x7f);
}
string str;
while (1)
{
- str += ::to_string ((char)buffer);
- if (buffer & 0x80)
- buffer >>= 8;
+ str += ::to_string ((char)buffer_i);
+ if (buffer_i & 0x80)
+ buffer_i >>= 8;
else
break;
}
}
str += ::to_string ((char)status_byte);
- str += ::to_string ((char) (get_pitch () + c0_pitch_));
+ str += ::to_string ((char) (get_pitch () + c0_pitch_i_));
str += ::to_string ((char)dynamic_byte_);
return str;
Byte status_byte = (char) (0x80 + channel_);
string str = ::to_string ((char)status_byte);
- str += ::to_string ((char) (get_pitch () + Midi_note::c0_pitch_));
+ str += ::to_string ((char) (get_pitch () + Midi_note::c0_pitch_i_));
str += ::to_string ((char)aftertouch_byte_);
if (get_fine_tuning () != 0)
string
Midi_tempo::to_string () const
{
- int useconds_per_4 = 60 * (int)1e6 / audio_->per_minute_4_;
+ int useconds_per_4_i = 60 * (int)1e6 / audio_->per_minute_4_;
string str = "ff5103";
- str += String_convert::int2hex (useconds_per_4, 6, '0');
+ str += String_convert::int2hex (useconds_per_4_i, 6, '0');
return String_convert::hex2bin (str);
}
return 0;
}
-Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track,
- int channel)
+Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track)
{
- channel_ = channel;
track_ = track;
index_ = 0;
items_ = &audio_staff->audio_items_;
if (Midi_item *midi = Midi_item::get_midi (audio))
{
- if (Midi_channel_item *mci = dynamic_cast<Midi_channel_item*> (midi))
- mci->channel_ = channel_;
-
+ midi->channel_ = track_->channel_;
//midi->channel_ = track_->number_;
if (Midi_note *note = dynamic_cast<Midi_note *> (midi))
{
#include "engraver-group.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "moment.hh"
-#include "translator.icc"
-
/**
The name says it all: make multi measure rests
*/
TRANSLATOR_DECLARATIONS (Multi_measure_rest_engraver);
protected:
+ virtual bool try_music (Music *);
void process_music ();
void stop_translation_timestep ();
void start_translation_timestep ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (multi_measure_rest);
- DECLARE_TRANSLATOR_LISTENER (multi_measure_text);
private:
- Stream_event *rest_ev_;
- vector<Stream_event*> text_events_;
+ Music *rest_ev_;
+ vector<Music*> text_events_;
int start_measure_;
Rational last_main_moment_;
Moment stop_moment_;
rest_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_rest);
-void
-Multi_measure_rest_engraver::listen_multi_measure_rest (Stream_event *ev)
+bool
+Multi_measure_rest_engraver::try_music (Music *event)
{
- /* FIXME: Should use ASSIGN_EVENT_ONCE. Can't do that yet because of
- the kill-mm-rests hack in part-combine-iterator. */
- rest_ev_ = ev;
- stop_moment_ = now_mom () + get_event_length (rest_ev_);
- /*
- if (ASSIGN_EVENT_ONCE (rest_ev_, ev))
- stop_moment_ = now_mom () + get_event_length (rest_ev_);
- */
-}
+ if (event->is_mus_type ("multi-measure-rest-event"))
+ {
+ rest_ev_ = event;
+ stop_moment_ = now_mom () + rest_ev_->get_length ();
-IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_text);
-void
-Multi_measure_rest_engraver::listen_multi_measure_text (Stream_event *ev)
-{
- text_events_.push_back (ev);
+ return true;
+ }
+ else if (event->is_mus_type ("multi-measure-text-event"))
+ {
+ text_events_.push_back (event);
+ return true;
+ }
+ return false;
}
void
{
for (vsize i = 0; i < text_events_.size (); i++)
{
- Stream_event *e = text_events_[i];
+
+ Music *e = text_events_[i];
Spanner *sp
= make_spanner ("MultiMeasureRestText", e->self_scm ());
SCM t = e->get_property ("text");
}
start_measure_
- = scm_to_int (get_property ("internalBarNumber"));
+ = scm_to_int (get_property ("currentBarNumber"));
}
bar_seen_ = bar_seen_ || scm_is_string (get_property ("whichBar"));
last_rest_ = mmrest_;
last_numbers_ = numbers_;
- int cur = scm_to_int (get_property ("internalBarNumber"));
+ int cur = scm_to_int (get_property ("currentBarNumber"));
int num = cur - start_measure_;
/*
{
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Multi_measure_rest_engraver,
/* doc */
"Engraves multi-measure rests that are produced with @code{R}. Reads "
- "@code{measurePosition} and @code{internalBarNumber} to determine what number to print "
- "over the @ref{MultiMeasureRest}. Reads @code{measureLength} to determine if it "
+ "measurePosition and currentBarNumber to determine what number to print "
+ "over the MultiMeasureRest. Reads measureLength to determine if it "
"should use a whole rest or a breve rest to represent 1 measure ",
-
- /* create */
- "MultiMeasureRest "
- "MultiMeasureRestNumber "
- "MultiMeasureRestText ",
-
- /* accept */
- "multi-measure-rest-event "
- "multi-measure-text-event ",
-
+ /* create */ "MultiMeasureRest MultiMeasureRestNumber MultiMeasureRestText",
+ /* accept */ "multi-measure-rest-event multi-measure-text-event",
/* read */
- "internalBarNumber "
+ "currentBarNumber "
"restNumberThreshold "
"breakableSeparationItem "
"currentCommandColumn "
"measurePosition "
- "measureLength ",
-
+ "measureLength",
/* write */ "");
// ugh copy & paste.
- Grob *common_x = sp->get_bound (LEFT)->common_refpoint (sp->get_bound (RIGHT),
- X_AXIS);
Interval sp_iv;
Direction d = LEFT;
do
{
Item *col = sp->get_bound (d)->get_column ();
- Interval coldim = robust_relative_extent (col, common_x, X_AXIS);
+ Interval coldim = col->extent (0, X_AXIS);
sp_iv[d] = coldim[-d];
}
while ((flip (&d)) != LEFT);
Real x_off = 0.0;
- Real rx = sp->get_bound (LEFT)->relative_coordinate (common_x, X_AXIS);
+ Real rx = sp->get_bound (LEFT)->relative_coordinate (0, X_AXIS);
/*
we gotta stay clear of sp_iv, so move a bit to the right if
needed.
"Its arguments. @code{signature} is a list containing either "
"@code{ly:music?} predicates or other type predicates.")
{
+ extern SCM ly_music_p_proc;
+
+ string str = "";
+ for (SCM s = signature; scm_is_pair (s); s = scm_cdr (s))
+ {
+ if (str != "")
+ str += "-";
+
+ if (scm_car (s) == ly_music_p_proc)
+ str += "music";
+ else if (scm_car (s) == ly_lily_module_constant ("markup?"))
+ str += "markup";
+ else if (ly_is_procedure (scm_car (s)))
+ str += "scm";
+ }
+ if (str == "") str = "noarg";
scm_set_object_property_x (func, ly_symbol2scm ("music-function-signature"),
signature);
+ scm_set_object_property_x (func, ly_symbol2scm ("music-function-signature-keyword"),
+ ly_symbol2scm (str.c_str ()));
+
SCM_RETURN_NEWSMOB (music_function_tag, func);
}
}
void
-Music_iterator::init_context (Music *m, Context *report)
+Music_iterator::init_translator (Music *m, Context *report)
{
music_ = m;
assert (m);
SCM ip = get_static_get_iterator (m);
Music_iterator *p = unsmob_iterator (ip);
- p->init_context (m, get_outlet ());
+ p->init_translator (m, get_outlet ());
p->construct_children ();
return ip;
{
descend_to_bottom_context ();
- /*
- FIXME: then don't do it.
- */
if (!m->is_mus_type ("event"))
- m->origin ()->programming_error (_ ("Sending non-event to context"));
+ m->origin ()->warning (_f ("Sending non-event to context"));
m->send_to_context (get_outlet ());
}
#include "context.hh"
#include "dispatcher.hh"
#include "duration.hh"
-#include "input.hh"
+#include "input-smob.hh"
#include "international.hh"
#include "ly-smobs.icc"
#include "main.hh"
#include "warn.hh"
/*
- Music is anything that has (possibly zero) duration and supports
- both time compression and transposition.
+ Music is anything that has duration and supports both time compression
+ and transposition.
In Lily, everything that can be thought to have a length and a pitch
- (which has a duration which can be transposed) is considered "music".
+ (which has a duration which can be transposed) is considered "music",
*/
bool
Music::internal_is_music_type (SCM k) const
set_property ("duration", d->compressed (factor.main_part_).smobbed_copy ());
}
-/*
-TODO: make transposition non-destructive
-*/
-SCM
-transpose_mutable (SCM alist, Pitch delta)
+void
+Music::transpose (Pitch delta)
{
- SCM retval = SCM_EOL;
+ if (to_boolean (get_property ("untransposable")))
+ return;
- for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = this->get_property_alist (true); scm_is_pair (s); s = scm_cdr (s))
{
SCM entry = scm_car (s);
- SCM prop = scm_car (entry);
SCM val = scm_cdr (entry);
if (Pitch *p = unsmob_pitch (val))
delta.to_string ()));
}
}
- else if (prop == ly_symbol2scm ("element"))
- {
- if (Music *m = unsmob_music (val))
- m->transpose (delta);
- }
- else if (prop == ly_symbol2scm ("elements"))
- transpose_music_list (val, delta);
- else if (prop == ly_symbol2scm ("pitch-alist") &&
- scm_is_pair (val))
- entry = scm_cons (prop, ly_transpose_key_alist (val, delta.smobbed_copy ()));
- retval = scm_cons (entry, retval);
}
- return scm_reverse_x (retval, SCM_EOL);
-}
+ SCM elt = get_property ("element");
-void
-Music::transpose (Pitch delta)
-{
- if (to_boolean (get_property ("untransposable")))
- return;
+ if (Music *m = unsmob_music (elt))
+ m->transpose (delta);
+
+ transpose_music_list (get_property ("elements"), delta);
- mutable_property_alist_ = transpose_mutable (mutable_property_alist_, delta);
+ /*
+ UGH - how do this more generically?
+ */
+ SCM pa = get_property ("pitch-alist");
+ if (scm_is_pair (pa))
+ set_property ("pitch-alist", ly_transpose_key_alist (pa, delta.smobbed_copy ()));
}
void
return ip ? ip : &dummy_input_global;
}
-/*
- ES TODO: This method should probably be reworked or junked.
-*/
-Stream_event *
-Music::to_event () const
-{
- /* UGH. Temp hack */
- SCM orig_sym = get_property ("name");
- char out[200];
- string in = ly_symbol2string (orig_sym);
- /* don't add '-' before first character */
- out[0] = tolower (in[0]);
- size_t outpos = 1;
- for (size_t inpos = 1; inpos < in.size () && outpos < 190; inpos++)
- {
- if (isupper (in[inpos]))
- out[outpos++] = '-';
- out[outpos++] = tolower (in[inpos]);
- }
- out[outpos] = 0;
- SCM class_name = ly_symbol2scm (out);
-
- // catch programming mistakes.
- if (!internal_is_music_type (class_name))
- {
- programming_error ("Not a music type");
- }
-
- Stream_event *e = new Stream_event (class_name, mutable_property_alist_);
- Moment length = get_length ();
- if (length.to_bool ())
- e->set_property ("length", length.smobbed_copy ());
-
- // articulations as events.
- SCM art_mus = e->get_property ("articulations");
- if (scm_is_pair (art_mus))
- {
- SCM art_ev = SCM_EOL;
- for (; scm_is_pair (art_mus); art_mus = scm_cdr (art_mus))
- {
- Music *m = unsmob_music (scm_car (art_mus));
- SCM ev = m ? m->to_event ()->unprotect () : scm_car (art_mus);
- art_ev = scm_cons (ev, art_ev);
- }
- e->set_property ("articulations", scm_reverse_x (art_ev, SCM_EOL));
- }
-
- /*
- ES TODO: This is a temporary fix. Stream_events should not be
- aware of music.
- */
- e->set_property ("music-cause", self_scm ());
-
- return e;
-}
-
void
Music::send_to_context (Context *c)
{
- Stream_event *ev = to_event ();
- c->event_source ()->broadcast (ev);
- ev->unprotect ();
+ send_stream_event (c, "MusicEvent",
+ ly_symbol2scm("music"), self_scm (), 0);
}
Music *
#include "self-alignment-interface.hh"
#include "side-position-interface.hh"
#include "stem.hh"
-#include "stream-event.hh"
+#include "stem.hh"
#include "warn.hh"
#include "translator.icc"
{
Grob *head_;
Grob *script_;
- Stream_event *note_event_;
- Stream_event *finger_event_;
+ Music *note_event_;
+ Music *finger_event_;
bool follow_into_staff_;
int position_;
note_event_ = finger_event_ = 0;
follow_into_staff_ = false;
}
+ static int compare (Finger_tuple const &c1, Finger_tuple const &c2)
+ {
+ return c1.position_- c2.position_;
+ }
};
-bool
-operator< (Finger_tuple const &a, Finger_tuple const &b)
-{
- return a.position_ < b.position_;
-}
-
class New_fingering_engraver : public Engraver
{
vector<Finger_tuple> fingerings_;
vector<Grob*> heads_;
Grob *stem_;
- void position_all ();
public:
TRANSLATOR_DECLARATIONS (New_fingering_engraver);
protected:
void stop_translation_timestep ();
DECLARE_ACKNOWLEDGER (rhythmic_head);
DECLARE_ACKNOWLEDGER (stem);
- void add_fingering (Grob *, Stream_event *, Stream_event *);
- void add_script (Grob *, Stream_event *, Stream_event *);
- void add_string (Grob *, Stream_event *, Stream_event *);
+ void add_fingering (Grob *, Music *, Music *);
+ void add_script (Grob *, Music *, Music *);
+ void add_string (Grob *, Music *, Music *);
void position_scripts (SCM orientations, vector<Finger_tuple> *);
};
void
New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
{
- Stream_event *note_ev = inf.event_cause ();
+ Music *note_ev = inf.music_cause ();
if (!note_ev)
return;
for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s))
{
- Stream_event *ev = unsmob_stream_event (scm_car (s));
+ Music *m = unsmob_music (scm_car (s));
- if (!ev)
+ if (!m)
continue;
- if (ev->in_event_class ("fingering-event"))
- add_fingering (inf.grob (), ev, note_ev);
- else if (ev->in_event_class ("text-script-event"))
- ev->origin ()->warning (_ ("can't add text scripts to individual note heads"));
- else if (ev->in_event_class ("script-event"))
- add_script (inf.grob (), ev, note_ev);
- else if (ev->in_event_class ("string-number-event"))
- add_string (inf.grob (), ev, note_ev);
- else if (ev->in_event_class ("harmonic-event"))
+ if (m->is_mus_type ("fingering-event"))
+ add_fingering (inf.grob (), m, note_ev);
+ else if (m->is_mus_type ("text-script-event"))
+ m->origin ()->warning (_ ("can't add text scripts to individual note heads"));
+ else if (m->is_mus_type ("script-event"))
+ add_script (inf.grob (), m, note_ev);
+ else if (m->is_mus_type ("string-number-event"))
+ add_string (inf.grob (), m, note_ev);
+ else if (m->is_mus_type ("harmonic-event"))
{
inf.grob ()->set_property ("style", ly_symbol2scm ("harmonic"));
Grob *d = unsmob_grob (inf.grob ()->get_object ("dot"));
void
New_fingering_engraver::add_script (Grob *head,
- Stream_event *event,
- Stream_event *note)
+ Music *event,
+ Music *note)
{
(void) note;
if (g)
{
ft.script_ = g;
- ft.script_->set_parent (head, X_AXIS);
articulations_.push_back (ft);
+
+ ft.script_->set_parent (head, X_AXIS);
}
}
void
New_fingering_engraver::add_fingering (Grob *head,
- Stream_event *event,
- Stream_event *hevent)
+ Music *event,
+ Music *hevent)
{
Finger_tuple ft;
Side_position_interface::add_support (ft.script_, head);
+ int d = scm_to_int (event->get_property ("digit"));
+
/*
TODO:
Should add support for thumb. It's a little involved, since
the thumb lives in a different font. Maybe it should be moved?
+
*/
+ if (d > 5)
+ {
+ /*
+ music for the softenon children?
+ */
+ event->origin ()->warning (_ ("music for the martians."));
+ }
+ SCM sstr = scm_number_to_string (scm_from_int (d), scm_from_int (10));
+ ft.script_->set_property ("text", sstr);
ft.finger_event_ = event;
ft.note_event_ = hevent;
void
New_fingering_engraver::add_string (Grob *head,
- Stream_event *event,
- Stream_event *hevent)
+ Music *event,
+ Music *hevent)
{
Finger_tuple ft;
Side_position_interface::add_support (ft.script_, head);
+ int d = scm_to_int (event->get_property ("string-number"));
+
+ SCM sstr = scm_number_to_string (scm_from_int (d), scm_from_int (10));
+ ft.script_->set_property ("text", sstr);
+
ft.finger_event_ = event;
ft.note_event_ = hevent;
ft.head_ = head;
}
}
- vector_sort (*scripts, less<Finger_tuple> ());
+ vector_sort (*scripts, Finger_tuple::compare);
bool up_p = scm_c_memq (ly_symbol2scm ("up"), orientations) != SCM_BOOL_F;
bool down_p = scm_c_memq (ly_symbol2scm ("down"), orientations) != SCM_BOOL_F;
void
New_fingering_engraver::stop_translation_timestep ()
-{
- position_all();
- stem_ = 0;
- heads_.clear ();
-}
-
-
-void
-New_fingering_engraver::position_all ()
{
if (fingerings_.size ())
{
if (stem_ && to_boolean (script->get_property ("add-stem-support")))
Side_position_interface::add_support (script, stem_);
+
+
}
+
+ stem_ = 0;
+ heads_.clear ();
articulations_.clear ();
}
{
stem_ = 0;
}
-
-
ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head);
ADD_ACKNOWLEDGER (New_fingering_engraver, stem);
/* doc */ "Create fingering-scripts for notes in a new chord. "
"This engraver is ill-named, since it "
"also takes care of articulations and harmonic note heads",
- /* create */
- "Fingering",
+ /* create */ "Fingering",
/* accept */ "",
- /* read */
-
- "fingeringOrientations "
- "stringNumberOrientations "
- ,
-
+ /* read */ "fingeringOrientations",
/* write */ "");
if (cg[d].size ())
{
Grob *h = cg[d][0];
- Grob *fh = Note_column::first_head (h);
- if (fh)
- wid = fh->extent (h, X_AXIS).length ();
+ wid = Note_column::first_head (h)->extent (h, X_AXIS).length ();
}
}
while (flip (&d) != UP);
do
{
vector<Grob*> &clashes (clash_groups[d]);
- vector_sort (clashes, Note_column::shift_less);
+ vector_sort (clashes, Note_column::shift_compare);
}
while ((flip (&d)) != UP);
return unsmob_grob (me->get_object ("rest"));
}
-bool
-Note_column::shift_less (Grob *const &p1, Grob *const &p2)
+int
+Note_column::shift_compare (Grob *const &p1, Grob *const &p2)
{
SCM s1 = p1->get_property ("horizontal-shift");
SCM s2 = p2->get_property ("horizontal-shift");
int h1 = (scm_is_number (s1)) ? scm_to_int (s1) : 0;
int h2 = (scm_is_number (s2)) ? scm_to_int (s2) : 0;
- return h1 < h2;
+ return h1 - h2;
}
Item *
ADD_INTERFACE (Note_column, "note-column-interface",
"Stem and noteheads combined",
-
- /* properties */
- "accidentals "
- "arpeggio "
- "force-hshift "
- "horizontal-shift "
- "note-heads "
- "rest "
- "rest-collision "
- "stem "
- );
+ "arpeggio note-heads rest-collision rest horizontal-shift stem accidentals force-hshift");
Font_metric *fm = Font_interface::get_default_font (me);
- string idx_symmetric;
- string idx_directed;
- string idx_either;
- idx_symmetric = idx_either = "noteheads.s" + suffix;
- Stencil out = fm->find_by_name (idx_symmetric);
+ string idx = "noteheads.s" + suffix;
+ Stencil out = fm->find_by_name (idx);
if (out.is_empty ())
{
string prefix = "noteheads.";
if (stem_dir == CENTER)
programming_error ("must have stem dir for note head");
- idx_directed = idx_either =
- prefix + ((stem_dir == UP) ? "u" : "d") + suffix;
- out = fm->find_by_name (idx_directed);
+ idx = prefix + ((stem_dir == UP) ? "u" : "d") + suffix;
+ out = fm->find_by_name (idx);
}
if (out.is_empty ())
{
- me->warning (_f ("none of note heads `%s' or `%s' found",
- idx_symmetric.c_str (), idx_directed.c_str ()));
+ me->warning (_f ("note head `%s' not found", idx.c_str ()));
out = Stencil (Box (Interval (0, 0), Interval (0, 0)), SCM_EOL);
}
else
- *font_char = idx_either;
+ *font_char = idx;
return out;
}
#include <cctype>
using namespace std;
+#include "rhythmic-head.hh"
+#include "output-def.hh"
#include "dots.hh"
#include "dot-column.hh"
-#include "duration.hh"
-#include "item.hh"
-#include "output-def.hh"
-#include "pitch.hh"
-#include "rhythmic-head.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
+#include "item.hh"
#include "warn.hh"
-
-#include "translator.icc"
+#include "duration.hh"
class Note_heads_engraver : public Engraver
{
vector<Item*> notes_;
- vector<Stream_event*> note_evs_;
+ vector<Item*> dots_;
+ vector<Music*> note_evs_;
public:
TRANSLATOR_DECLARATIONS (Note_heads_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (note);
+ virtual bool try_music (Music *ev);
void process_music ();
void stop_translation_timestep ();
};
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Note_heads_engraver, note);
-void
-Note_heads_engraver::listen_note (Stream_event *ev)
+bool
+Note_heads_engraver::try_music (Music *m)
{
- note_evs_.push_back (ev);
+ if (m->is_mus_type ("note-event"))
+ {
+ note_evs_.push_back (m);
+ return true;
+ }
+ else if (m->is_mus_type ("busy-playing-event"))
+ return note_evs_.size ();
+
+ return false;
}
void
{
for (vsize i = 0; i < note_evs_.size (); i++)
{
- Stream_event *ev = note_evs_[i];
+ Music *ev = note_evs_[i];
Item *note = make_item ("NoteHead", ev->self_scm ());
+ Duration dur = *unsmob_duration (ev->get_property ("duration"));
+
+ note->set_property ("duration-log", scm_from_int (dur.duration_log ()));
+ if (dur.dot_count ())
+ {
+ Item *d = make_item ("Dots", note->self_scm ());
+ Rhythmic_head::set_dots (note, d);
+
+ if (dur.dot_count ()
+ != robust_scm2int (d->get_property ("dot-count"), 0))
+ d->set_property ("dot-count", scm_from_int (dur.dot_count ()));
+
+ d->set_parent (note, Y_AXIS);
+
+ dots_.push_back (d);
+ }
+
Pitch *pit = unsmob_pitch (ev->get_property ("pitch"));
#if 0 /* TODO: should have a mechanism to switch off these warnings. */
Note_heads_engraver::stop_translation_timestep ()
{
notes_.clear ();
+ dots_.clear ();
note_evs_.clear ();
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Note_heads_engraver,
/* doc */ "Generate noteheads.",
/* create */
- "NoteHead ",
+ "NoteHead "
+ "Dots",
/* accept */
- "note-event",
+ "note-event "
+ "busy-playing-event",
/* read */ "middleCPosition",
/* write */ "");
#include "engraver.hh"
#include "item.hh"
-#include "pitch.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
class Note_name_engraver : public Engraver
{
public:
TRANSLATOR_DECLARATIONS (Note_name_engraver);
- vector<Stream_event*> events_;
+ vector<Music*> events_;
vector<Item*> texts_;
- DECLARE_TRANSLATOR_LISTENER (note);
+ virtual bool try_music (Music *m);
void process_music ();
void stop_translation_timestep ();
};
-IMPLEMENT_TRANSLATOR_LISTENER (Note_name_engraver, note);
-void
-Note_name_engraver::listen_note (Stream_event *ev)
+bool
+Note_name_engraver::try_music (Music *m)
{
- events_.push_back (ev);
+ if (m->is_mus_type ("note-event"))
+ {
+ events_.push_back (m);
+ return true;
+ }
+ return false;
}
void
{
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Note_name_engraver,
- /* doc */ "Print pitches as words.",
+ /* doc */ "",
/* create */ "NoteName",
/* accept */ "note-event",
/* read */ "printOctaveNames",
#include "audio-item.hh"
#include "audio-column.hh"
#include "global-context.hh"
-#include "stream-event.hh"
#include "warn.hh"
-
-#include "translator.icc"
+#include "music.hh"
/**
Convert evs to audio notes.
TRANSLATOR_DECLARATIONS (Note_performer);
protected:
+ virtual bool try_music (Music *ev);
+
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (note);
private:
- vector<Stream_event*> note_evs_;
+ vector<Music*> note_evs_;
vector<Audio_note*> notes_;
};
while (note_evs_.size ())
{
- Stream_event *n = note_evs_.back ();
+ Music *n = note_evs_.back ();
note_evs_.pop_back ();
SCM pit = n->get_property ("pitch");
if (Pitch *pitp = unsmob_pitch (pit))
{
- SCM articulations = n->get_property ("articulations");
- Stream_event *tie_event = 0;
- for (SCM s = articulations;
- !tie_event && scm_is_pair (s);
- s = scm_cdr (s))
- {
- Stream_event *ev = unsmob_stream_event (scm_car (s));
- if (!ev)
- continue;
-
- if (ev->in_event_class ("tie-event"))
- tie_event = ev;
- }
-
- Audio_note *p = new Audio_note (*pitp, get_event_length (n),
- tie_event, - transposing);
+ Audio_note *p = new Audio_note (*pitp, n->get_length (), - transposing);
Audio_element_info info (p, n);
announce_element (info);
notes_.push_back (p);
{
// why don't grace notes show up here?
// --> grace notes effectively do not get delayed
+ Moment now = now_mom ();
+ for (vsize i = 0; i < notes_.size (); i++)
+ play_element (notes_[i]);
notes_.clear ();
note_evs_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Note_performer, note)
-void
-Note_performer::listen_note (Stream_event *ev)
+bool
+Note_performer::try_music (Music *ev)
{
- note_evs_.push_back (ev);
+ if (ev->is_mus_type ("note-event"))
+ {
+ note_evs_.push_back (ev);
+ return true;
+ }
+ else if (ev->is_mus_type ("busy-playing-event"))
+ return note_evs_.size ();
+
+ return false;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Note_performer, "", "",
- "note-event ",
+ "note-event "
+ "busy-playing-event",
"", "");
Note_performer::Note_performer ()
stems_drul[d] = stem;
beams_drul[d] = Stem::get_beam (stem);
- Direction stem_dir = get_grob_direction (stem);
- if (stem_dirs[d] && stem_dirs[d] != stem_dir)
+ Direction sd = get_grob_direction (stem);
+ if (stem_dirs[d] && stem_dirs[d] != sd)
{
correct_stem_dirs = false;
continue;
}
- stem_dirs[d] = stem_dir;
+ stem_dirs[d] = sd;
/*
Correction doesn't seem appropriate when there is a large flag
correct_stem_dirs = false;
Interval hp = Stem::head_positions (stem);
- if (correct_stem_dirs
- && !hp.is_empty ())
+ if (!hp.is_empty ())
{
- Real chord_start = hp[stem_dir];
+ Real chord_start = hp[sd];
+ Real stem_end = Stem::stem_end_position (stem);
- /*
- can't look at stem-end-position, since that triggers
- beam slope computations.
- */
- Real stem_end = hp[stem_dir] +
- stem_dir * robust_scm2double (stem->get_property ("length"), 7);
-
- stem_posns[d] = Interval (min (chord_start, stem_end),
- max (chord_start, stem_end));
+ stem_posns[d] = Interval (min (chord_start, stem_end), max (chord_start, stem_end));
head_posns[d].unite (hp);
}
}
ADD_INTERFACE (Note_spacing, "note-spacing-interface",
"This object calculates spacing wishes for individual voices.",
-
-
- "knee-spacing-correction "
- "left-items "
- "right-items "
- "same-direction-correction "
- "stem-spacing-correction "
-
- );
+ "left-items right-items stem-spacing-correction same-direction-correction knee-spacing-correction");
+++ /dev/null
-/*
- optimal-page-breaking.cc -- implement a page-breaker that
- will break pages in such a way that both horizontal and
- vertical spacing will be acceptable
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "optimal-page-breaking.hh"
-#include "output-def.hh"
-#include "page-spacing.hh"
-#include "paper-book.hh"
-#include "paper-score.hh"
-#include "prob.hh"
-#include "system.hh"
-
-static bool
-is_break (Grob *g)
-{
- (void) g; /* shutup warning */
- return false;
-}
-
-Optimal_page_breaking::Optimal_page_breaking (Paper_book *pb)
- : Page_breaking (pb, is_break)
-{
-}
-
-Optimal_page_breaking::~Optimal_page_breaking ()
-{
-}
-
-Spacing_result
-Optimal_page_breaking::try_page_spacing (Line_division const &line_count)
-{
- vector<Line_details> lines = line_details (0, breaks_.size () - 1, line_count);
- Real page_h = page_height (1, false); // FIXME
- SCM force_sym = ly_symbol2scm ("blank-last-page-force");
- Real blank_force = robust_scm2double (book_->paper_->lookup_variable (force_sym), 0);
- bool ragged_all = to_boolean (book_->paper_->c_variable ("ragged-bottom"));
- bool ragged_last = to_boolean (book_->paper_->c_variable ("ragged-last-bottom"));
- Spacing_result ret = space_systems_on_best_pages (lines,
- page_h,
- blank_force,
- ragged_all,
- ragged_last);
-
- /* add in the line penalties */
- Real line_force = 0;
- Real line_penalty = 0;
- Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 1);
-
- for (vsize i = 0; i < lines.size (); i++)
- {
- line_force += fabs (lines[i].force_);
- line_penalty += lines[i].break_penalty_;
- }
-
- ret.demerits_ = ret.force_[0] * ret.force_[0] * page_weighting;
- for (vsize i = 1; i < ret.force_.size (); i++)
- {
- Real uniformity = fabs (ret.force_[i] - ret.force_[i-1]);
- ret.demerits_ += (ret.force_[i] * ret.force_[i]
- + uniformity * uniformity) * page_weighting;
- }
- ret.demerits_ += line_force + line_penalty;
- return ret;
-}
-
-SCM
-Optimal_page_breaking::solve ()
-{
- vsize end = breaks_.size () - 1;
- vsize min_sys_count = min_system_count (0, end);
- vsize max_sys_count = max_system_count (0, end);
- vsize max_page_count = INT_MAX;
- vsize cur_page_count = 0;
- Spacing_result best;
- Line_division best_division;
- Line_division lower_bound;
-
- for (vsize sys_count = min_sys_count;
- cur_page_count <= max_page_count && sys_count <= max_sys_count;
- sys_count++)
- {
- Real this_best_demerits = infinity_f;
- vector<Line_division> div = line_divisions (0, end, sys_count, lower_bound);
- for (vsize d = 0; d < div.size (); d++)
- {
- Spacing_result cur = try_page_spacing (div[d]);
- cur_page_count = cur.systems_per_page_.size ();
- if (cur.demerits_ < best.demerits_ || isinf (best.demerits_))
- {
- best = cur;
- best_division = div[d];
- }
-
- if (cur.demerits_ < this_best_demerits || isinf (best.demerits_))
- {
- this_best_demerits = cur.demerits_;
- lower_bound = div[d];
- }
-
- vector<Line_details> det = line_details (0, end, div[d]);
- bool all_lines_stretched = true;
- for (vsize i = 0; i < det.size (); i++)
- if (det[i].force_ < 0)
- all_lines_stretched = false;
-
- if (all_lines_stretched)
- max_page_count = min (max_page_count, cur_page_count + 1);
- }
- }
-
- break_into_pieces (0, end, best_division);
- SCM lines = systems ();
- return make_pages (best.systems_per_page_, lines);
-}
-
*/
#include "engraver.hh"
-#include "context.hh"
#include "grob.hh"
-#include "stream-event.hh"
+#include "context.hh"
#include "translator.icc"
{
TRANSLATOR_DECLARATIONS (Output_property_engraver);
protected:
- vector<Stream_event*> props_;
-
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_TRANSLATOR_LISTENER (apply_output);
+ vector<Music*> props_;
+ DECLARE_ACKNOWLEDGER (grob)
void stop_translation_timestep ();
+ virtual bool try_music (Music*);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Output_property_engraver, apply_output);
-void
-Output_property_engraver::listen_apply_output (Stream_event *ev)
+
+bool
+Output_property_engraver::try_music (Music* m)
{
- /*
- UGH. Only swallow the output property event in the context
- it was intended for. This is inelegant but not inefficient.
- */
- if (context ()->is_alias (ev->get_property ("context-type")))
- props_.push_back (ev);
+ if (m->is_mus_type ("layout-instruction"))
+ {
+ /*
+ UGH. Only swallow the output property event in the context
+ it was intended for. This is inelegant but not inefficient.
+ */
+ if (context ()->is_alias (m->get_property ("context-type")))
+ {
+ props_.push_back (m);
+ return true;
+ }
+ }
+ return false;
}
void
{
for (vsize i = props_.size (); i--;)
{
- Stream_event *o = props_[i];
+ Music *o = props_[i];
Context *d = inf.context ();
SCM proc = o->get_property ("procedure");
scm_call_3 (proc,
"",
/* accept */
- "apply-output-event",
+ "layout-instruction",
/* read */
"",
+++ /dev/null
-/*
- page-breaking-scheme.cc -- implement bindings to the various
- page-breakers
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "paper-book.hh"
-#include "page-turn-page-breaking.hh"
-#include "optimal-page-breaking.hh"
-
-LY_DEFINE (ly_page_turn_breaking, "ly:page-turn-breaking",
- 1, 0, 0, (SCM pb),
- "Optimally break (pages and lines) the Paper_book PB such that page turns "
- "only happen in specified places, returning its pages.")
-{
- Page_turn_page_breaking b (unsmob_paper_book (pb));
- return b.solve ();
-}
-
-LY_DEFINE (ly_optimal_breaking, "ly:optimal-breaking",
- 1, 0, 0, (SCM pb),
- "Optimally break (pages and lines) the Paper_book PB to minimise badness in "
- "bother vertical and horizontal spacing.")
-{
- Optimal_page_breaking b (unsmob_paper_book (pb));
- return b.solve ();
-}
+++ /dev/null
-/*
- page-breaking.cc -- implement a superclass and utility
- functions shared by various page-breaking algorithms
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "page-breaking.hh"
-
-#include "international.hh"
-#include "item.hh"
-#include "output-def.hh"
-#include "page-spacing.hh"
-#include "paper-book.hh"
-#include "paper-score.hh"
-#include "paper-system.hh"
-#include "system.hh"
-#include "warn.hh"
-
-/* for Page_breaking, the start index (when we are dealing with the stuff
- between a pair of breakpoints) refers to the break_ index of the end of
- the previous page. So the system index of the start of the current page
- could either be the same as the end of the previous page or one more than
- it. */
-
-/* Turn a break index into the sys index that starts the next page */
-vsize
-Page_breaking::next_system (Break_position const &break_pos) const
-{
- vsize sys = break_pos.sys_;
-
- if (sys == VPOS) /* beginning of the book */
- return 0;
- if (all_[sys].pscore_ && !break_pos.score_ender_)
- return sys; /* the score overflows the previous page */
- return sys + 1; /* this page starts with a new sys */
-}
-
-Page_breaking::Page_breaking (Paper_book *pb, Break_predicate is_break)
-{
- book_ = pb;
- create_system_list ();
- find_chunks_and_breaks (is_break);
-}
-
-Page_breaking::~Page_breaking ()
-{
-}
-
-/* translate indices into breaks_ into start-end parameters for the line breaker */
-void
-Page_breaking::line_breaker_args (vsize sys,
- Break_position const &start,
- Break_position const &end,
- vsize *line_breaker_start,
- vsize *line_breaker_end)
-{
- assert (all_[sys].pscore_);
- assert (next_system (start) <= sys && sys <= end.sys_);
-
- if (start.sys_ == sys)
- *line_breaker_start = start.score_break_;
- else
- *line_breaker_start = 0;
-
- if (end.sys_ == sys)
- *line_breaker_end = end.score_break_;
- else
- *line_breaker_end = VPOS;
-}
-
-void
-Page_breaking::break_into_pieces (vsize start_break, vsize end_break, Line_division const &div)
-{
- vector<Break_position> chunks = chunk_list (start_break, end_break);
- assert (chunks.size () == div.size () + 1);
-
- for (vsize i = 0; i < chunks.size () - 1; i++)
- {
- vsize sys = next_system (chunks[i]);
- if (all_[sys].pscore_)
- {
- vsize start;
- vsize end;
- line_breaker_args (sys, chunks[i], chunks[i+1], &start, &end);
-
- vector<Column_x_positions> pos = line_breaking_[sys].get_solution (start, end, div[i]);
- all_[sys].pscore_->root_system ()->break_into_pieces (pos);
- }
- }
-}
-
-SCM
-Page_breaking::systems ()
-{
- SCM ret = SCM_EOL;
- for (vsize sys = 0; sys < all_.size (); sys++)
- {
- if (all_[sys].pscore_)
- {
- SCM lines = all_[sys].pscore_->root_system ()->get_paper_systems ();
- ret = scm_cons (scm_vector_to_list (lines), ret);
- }
- else
- {
- Prob *pb = all_[sys].prob_;
- ret = scm_cons (scm_list_1 (pb->self_scm ()), ret);
- pb->unprotect ();
- }
- }
- return scm_append (scm_reverse (ret));
-}
-
-vector<Line_details>
-Page_breaking::line_details (vsize start_break, vsize end_break, Line_division const &div)
-{
- vector<Break_position> chunks = chunk_list (start_break, end_break);
- vector<Line_details> ret;
- assert (chunks.size () == div.size () + 1);
-
- for (vsize i = 0; i < chunks.size () - 1; i++)
- {
- vsize sys = next_system (chunks[i]);
- if (all_[sys].pscore_)
- {
- vsize start;
- vsize end;
- line_breaker_args (sys, chunks[i], chunks[i+1], &start, &end);
-
- vector<Line_details> details = line_breaking_[sys].get_details (start, end, div[i]);
- ret.insert (ret.end (), details.begin (), details.end ());
- }
- else
- {
- assert (div[i] == 1);
- ret.push_back (Line_details (all_[sys].prob_));
- }
- }
- return ret;
-}
-
-Real
-Page_breaking::page_height (int page_num, bool last)
-{
- SCM mod = scm_c_resolve_module ("scm page");
- SCM calc_height = scm_c_module_lookup (mod, "calc-printable-height");
- SCM make_page = scm_c_module_lookup (mod, "make-page");
-
- calc_height = scm_variable_ref (calc_height);
- make_page = scm_variable_ref (make_page);
-
- SCM page = scm_apply_0 (make_page, scm_list_n (
- book_->self_scm (),
- ly_symbol2scm ("page-number"), scm_from_int (page_num),
- ly_symbol2scm ("is-last"), scm_from_bool (last),
- SCM_UNDEFINED));
- SCM height = scm_apply_1 (calc_height, page, SCM_EOL);
- return scm_to_double (height) - scm_to_double (book_->paper_->c_variable ("page-top-space"));
-}
-
-SCM
-Page_breaking::breakpoint_property (vsize breakpoint, char const *str)
-{
- Break_position const &pos = breaks_[breakpoint];
-
- if (pos.sys_ == VPOS)
- return SCM_EOL;
- if (all_[pos.sys_].pscore_)
- return pos.col_->get_property (str);
- return all_[pos.sys_].prob_->get_property (str);
-}
-
-SCM
-Page_breaking::make_pages (vector<vsize> lines_per_page, SCM systems)
-{
- SCM layout_module = scm_c_resolve_module ("scm layout-page-layout");
- SCM page_module = scm_c_resolve_module ("scm page");
-
- SCM make_page = scm_c_module_lookup (layout_module, "make-page-from-systems");
- SCM page_stencil = scm_c_module_lookup (page_module, "page-stencil");
- make_page = scm_variable_ref (make_page);
- page_stencil = scm_variable_ref (page_stencil);
-
- SCM book = book_->self_scm ();
- bool ragged_all = to_boolean (book_->paper_->c_variable ("ragged-bottom"));
- bool ragged_last = to_boolean (book_->paper_->c_variable ("ragged-last-bottom"));
- int first_page_number = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
- SCM ret = SCM_EOL;
-
- for (vsize i = 0; i < lines_per_page.size (); i++)
- {
- SCM page_num = scm_from_int (i + first_page_number);
- SCM last = scm_from_bool (i == lines_per_page.size () - 1);
- SCM ragged = scm_from_bool (ragged_all || (to_boolean (last) && ragged_last));
- SCM line_count = scm_from_int (lines_per_page[i]);
- SCM lines = scm_list_head (systems, line_count);
- SCM page = scm_apply_0 (make_page,
- scm_list_n (book, lines, page_num, ragged, last, SCM_UNDEFINED));
-
- scm_apply_1 (page_stencil, page, SCM_EOL);
- ret = scm_cons (page, ret);
- systems = scm_list_tail (systems, line_count);
- }
- ret = scm_reverse (ret);
- return ret;
-}
-
-/* The page-turn-page-breaker needs to have a line-breaker between any two
- columns with non-NULL page-turn-permission.
-
- The optimal-breaker needs to have a line-breaker between any two columns
- with page-break-permission = 'force.
-
- By using a grob predicate, we can accommodate both of these uses.
-*/
-void
-Page_breaking::create_system_list ()
-{
- SCM specs = book_->get_system_specs ();
- for (SCM s = specs; scm_is_pair (s); s = scm_cdr (s))
- {
- if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (scm_car (s))))
- {
- SCM system_count = ps->layout ()->c_variable ("system-count");
-
- if (scm_is_number (system_count))
- s = scm_append (scm_list_3 (scm_list_1 (scm_car (s)),
- scm_vector_to_list (ps->get_paper_systems ()),
- scm_cdr (s)));
- else
- all_.push_back (System_spec (ps));
- }
- else
- {
- Prob *pb = unsmob_prob (scm_car (s));
- assert (pb);
-
- pb->protect ();
- all_.push_back (System_spec (pb));
- }
- }
-}
-
-void
-Page_breaking::find_chunks_and_breaks (Break_predicate is_break)
-{
- SCM force_sym = ly_symbol2scm ("force");
-
- chunks_.push_back (Break_position ());
- breaks_.push_back (Break_position ());
-
- for (vsize i = 0; i < all_.size (); i++)
- {
- if (all_[i].pscore_)
- {
- vector<Grob*> cols = all_[i].pscore_->root_system ()->columns ();
- vector<vsize> line_breaker_columns;
- line_breaker_columns.push_back (0);
-
- for (vsize j = 1; j < cols.size (); j++)
- {
- bool last = j == cols.size () - 1;
- bool break_point = is_break (cols[j]);
- bool chunk_end = cols[j]->get_property ("page-break-permission") == force_sym;
- Break_position cur_pos = Break_position (i,
- line_breaker_columns.size (),
- cols[j],
- last);
-
- if (break_point || (i == all_.size () - 1 && last))
- breaks_.push_back (cur_pos);
- if (chunk_end || last)
- chunks_.push_back (cur_pos);
-
- if ((break_point || chunk_end) && !last)
- line_breaker_columns.push_back (j);
- }
- line_breaking_.push_back (Constrained_breaking (all_[i].pscore_, line_breaker_columns));
- }
- else
- {
- /* TODO: we want some way of applying Break_p to a prob? */
- if (i == all_.size () - 1)
- breaks_.push_back (Break_position (i));
-
- chunks_.push_back (Break_position (i));
- line_breaking_.push_back (Constrained_breaking (NULL));
- }
- }
-}
-
-vector<Break_position>
-Page_breaking::chunk_list (vsize start_index, vsize end_index)
-{
- Break_position start = breaks_[start_index];
- Break_position end = breaks_[end_index];
-
- vsize i;
- for (i = 0; i < chunks_.size () && chunks_[i] <= start; i++)
- ;
-
- vector<Break_position> ret;
- ret.push_back (start);
- for (; i < chunks_.size () && chunks_[i] < end; i++)
- ret.push_back (chunks_[i]);
- ret.push_back (end);
- return ret;
-}
-
-vsize
-Page_breaking::min_system_count (vsize start, vsize end)
-{
- vector<Break_position> chunks = chunk_list (start, end);
- Line_division div = system_count_bounds (chunks, true);
- vsize ret = 0;
-
- for (vsize i = 0; i < div.size (); i++)
- ret += div[i];
- return ret;
-}
-
-vsize
-Page_breaking::max_system_count (vsize start, vsize end)
-{
- vector<Break_position> chunks = chunk_list (start, end);
- Line_division div = system_count_bounds (chunks, false);
- vsize ret = 0;
-
- for (vsize i = 0; i < div.size (); i++)
- ret += div[i];
- return ret;
-}
-
-Page_breaking::Line_division
-Page_breaking::system_count_bounds (vector<Break_position> const &chunks, bool min)
-{
- assert (chunks.size () >= 2);
-
- Line_division ret;
- ret.resize (chunks.size () - 1, 1);
-
- for (vsize i = 0; i < chunks.size () - 1; i++)
- {
- vsize sys = next_system (chunks[i]);
- if (all_[sys].pscore_)
- {
- vsize start;
- vsize end;
- line_breaker_args (sys, chunks[i], chunks[i+1], &start, &end);
- ret[i] = min
- ? line_breaking_[sys].get_min_systems (start, end)
- : line_breaking_[sys].get_max_systems (start, end);
- }
- }
-
- return ret;
-}
-
-vector<Page_breaking::Line_division>
-Page_breaking::line_divisions (vsize start,
- vsize end,
- vsize system_count,
- Line_division lower_bound,
- Line_division upper_bound)
-{
- vector<Break_position> chunks = chunk_list (start, end);
-
- if (!lower_bound.size ())
- lower_bound = system_count_bounds (chunks, true);
- if (!upper_bound.size ())
- upper_bound = system_count_bounds (chunks, false);
-
- assert (lower_bound.size () == chunks.size () - 1);
- assert (upper_bound.size () == chunks.size () - 1);
-
- vector<Line_division> ret;
- Line_division work_in_progress;
-
- line_divisions_rec (system_count,
- lower_bound,
- upper_bound,
- &ret,
- &work_in_progress);
- return ret;
-}
-
-void
-Page_breaking::line_divisions_rec (vsize system_count,
- Line_division const &min_sys,
- Line_division const &max_sys,
- vector<Line_division > *result,
- Line_division *cur_division)
-{
- vsize my_index = cur_division->size ();
- vsize others_min = 0;
- vsize others_max = 0;
-
- for (vsize i = my_index + 1; i < min_sys.size (); i++)
- {
- others_min += min_sys[i];
- others_max += max_sys[i];
- }
- others_max = min (others_max, system_count);
- vsize real_min = max (min_sys[my_index], system_count - others_max);
- vsize real_max = min (max_sys[my_index], system_count - others_min);
-
- if (real_min > real_max || real_min <= 0)
- {
- /* this should never happen within a recursive call. If it happens
- at all, it means that we were called with an unsolvable problem
- and we should return an empty result */
- assert (my_index == 0);
- return;
- }
-
- for (vsize i = real_min; i <= real_max; i++)
- {
- cur_division->push_back (i);
- if (my_index == min_sys.size () - 1)
- result->push_back (*cur_division);
- else
- line_divisions_rec (system_count - i, min_sys, max_sys, result, cur_division);
- cur_division->pop_back ();
- }
-}
+++ /dev/null
-/*
- page-spacing.cc - implement routines for spacing
- systems vertically on pages
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "page-spacing.hh"
-
-#include "matrix.hh"
-#include "warn.hh"
-
-/*
- A much simplified rods-and-springs problem.
- */
-struct Page_spacing
-{
- Real force_;
- Real page_height_;
- Real rod_height_;
- Real spring_len_;
- Real inverse_spring_k_;
-
- Line_details last_line_;
-
- Page_spacing (Real page_height)
- {
- page_height_ = page_height;
- clear ();
- }
-
- void calc_force ();
-
- void append_system (const Line_details &line);
- void prepend_system (const Line_details &line);
- void clear ();
-};
-
-void
-Page_spacing::calc_force ()
-{
- if (rod_height_ + last_line_.bottom_padding_ >= page_height_ || !inverse_spring_k_)
- force_ = infinity_f;
- else
- force_ = (page_height_ - rod_height_ - last_line_.bottom_padding_ - spring_len_) / inverse_spring_k_;
-}
-
-void
-Page_spacing::append_system (const Line_details &line)
-{
- rod_height_ += last_line_.padding_;
-
- rod_height_ += line.extent_.length ();
- spring_len_ += line.space_;
- inverse_spring_k_ += line.inverse_hooke_;
-
- last_line_ = line;
-
- calc_force ();
-}
-
-void
-Page_spacing::prepend_system (const Line_details &line)
-{
- if (rod_height_)
- rod_height_ += line.padding_;
- else
- last_line_ = line;
-
- rod_height_ += line.extent_.length ();
- spring_len_ += line.space_;
- inverse_spring_k_ += line.inverse_hooke_;
-
- calc_force ();
-}
-
-void
-Page_spacing::clear ()
-{
- force_ = rod_height_ = spring_len_ = 0;
- inverse_spring_k_ = 0;
-}
-
-/* for each forbidden page break, merge the systems around it into one system. */
-static vector<Line_details>
-compress_lines (const vector<Line_details> &orig)
-{
- vector<Line_details> ret;
-
- for (vsize i = 0; i < orig.size (); i++)
- {
- if (ret.size () && ret.back ().page_permission_ == SCM_EOL)
- {
- Line_details const &old = ret.back ();
- Line_details compressed = orig[i];
- compressed.extent_[DOWN] = old.extent_[DOWN];
- compressed.extent_[UP] = old.extent_[UP] + orig[i].extent_.length () + old.padding_;
- compressed.space_ += old.space_;
- compressed.inverse_hooke_ += old.inverse_hooke_;
-
- /* we don't need the force_ field for the vertical spacing,
- so we use force_ = n to signal that the line was compressed,
- reducing the number of lines by n (and force_ = 0 otherwise).
- This makes uncompression much easier. */
- compressed.force_ = old.force_ + 1;
- ret.back () = compressed;
- }
- else
- {
- ret.push_back (orig[i]);
- ret.back ().force_ = 0;
- }
- }
- return ret;
-}
-
-/* translate the number of systems-per-page into something meaningful for
- the uncompressed lines.
-*/
-static vector<vsize>
-uncompress_solution (vector<vsize> const &systems_per_page,
- vector<Line_details> const &compressed)
-{
- vector<vsize> ret;
- vsize start_sys = 0;
-
- for (vsize i = 0; i < systems_per_page.size (); i++)
- {
- int compressed_count = 0;
- for (vsize j = start_sys; j < start_sys + systems_per_page[i]; j++)
- compressed_count += (int)compressed[j].force_;
-
- ret.push_back (systems_per_page[i] + compressed_count);
- start_sys += systems_per_page[i];
- }
- return ret;
-}
-
-/* the cases for page_count = 1 or 2 can be done in O(n) time. Since they
- are by far the most common cases, we have special functions for them */
-static Spacing_result
-space_systems_on_1_page (vector<Line_details> const &lines, Real page_height, bool ragged)
-{
- Page_spacing space (page_height);
- Spacing_result ret;
-
- for (vsize i = 0; i < lines.size (); i++)
- space.append_system (lines[i]);
-
- ret.systems_per_page_.push_back (lines.size ());
- ret.force_.push_back (ragged ? min (space.force_, 0.0) : space.force_);
- ret.penalty_ = lines.back ().page_penalty_ + lines.back ().turn_penalty_;
- ret.demerits_ = ret.force_.back () * ret.force_.back () + ret.penalty_;
-
- return ret;
-}
-
-static Spacing_result
-space_systems_on_2_pages (vector<Line_details> const &lines,
- Real page_height,
- bool ragged,
- bool ragged_last)
-{
- /* if there is a forced break, this reduces to 2 1-page problems */
- for (vsize i = 0; i < lines.size () - 1; i++)
- if (lines[i].page_permission_ == ly_symbol2scm ("force"))
- {
- vector<Line_details> lines1 (lines.begin (), lines.begin () + i + 1);
- vector<Line_details> lines2 (lines.begin () + i + 1, lines.end ());
- Spacing_result p1 = space_systems_on_1_page (lines1, page_height, ragged);
- Spacing_result p2 = space_systems_on_1_page (lines2, page_height, ragged || ragged_last);
-
- p1.systems_per_page_.push_back (p2.systems_per_page_[0]);
- p1.force_.push_back (p2.force_[0]);
- p1.penalty_ += p2.penalty_ - lines[i].turn_penalty_;
- p1.demerits_ += p2.demerits_ - lines[i].turn_penalty_;
- return p1;
- }
-
- vector<Real> page1_force;
- vector<Real> page2_force;
- Page_spacing page1 (page_height);
- Page_spacing page2 (page_height);
-
- page1_force.resize (lines.size () - 1, infinity_f);
- page2_force.resize (lines.size () - 1, infinity_f);
-
- for (vsize i = 0; i < page1_force.size (); i++)
- {
- page1.append_system (lines[i]);
- page2.prepend_system (lines[lines.size () - 1 - i]);
- page1_force[i] = (ragged && page1.force_ < 0 && i > 0) ? infinity_f : page1.force_;
-
- if (ragged || ragged_last)
- page2_force[page2_force.size () - 1 - i] =
- (page2.force_ < 0 && i < page1_force.size () - 1) ? infinity_f : 0;
- else
- page2_force[page2_force.size () - 1 - i] = page2.force_;
- }
-
- vsize best_sys_count = 1;
- Real best_demerits = infinity_f;
- for (vsize i = 0; i < page1_force.size (); i++)
- {
- Real dem = page1_force[i] * page1_force[i]
- + page2_force[i] * page2_force[i]
- + lines[i+1].page_penalty_
- + lines.back ().page_penalty_ + lines.back ().turn_penalty_;
- if (dem < best_demerits)
- {
- best_demerits = dem;
- best_sys_count = i+1;
- }
- }
-
- Spacing_result ret;
- ret.systems_per_page_.push_back (best_sys_count);
- ret.systems_per_page_.push_back (lines.size () - best_sys_count);
- ret.force_.push_back (page1_force[best_sys_count-1]);
- ret.force_.push_back (page2_force[best_sys_count-1]);
- ret.penalty_ = lines[best_sys_count-1].page_penalty_
- + lines.back ().page_penalty_
- + lines.back ().turn_penalty_;
- ret.demerits_ = best_demerits;
-
- return ret;
-}
-
-Page_spacer::Page_spacer (vector<Line_details> const &lines, Real page_height, bool ragged, bool ragged_last)
- : lines_ (lines)
-{
- page_height_ = page_height;
- max_page_count_ = 0;
- ragged_ = ragged;
- ragged_last_ = ragged_last;
-}
-
-Spacing_result
-Page_spacer::solve (vsize page_count)
-{
- if (page_count > max_page_count_)
- resize (page_count);
-
- Spacing_result ret;
- ret.force_.resize (page_count);
- ret.systems_per_page_.resize (page_count);
-
- vsize system = lines_.size () - 1;
-
- if (isinf (state_.at (system, page_count-1).demerits_))
- {
- programming_error ("tried to space systems on a bad number of pages");
- return Spacing_result (); /* bad number of pages */
- }
-
- ret.penalty_ = state_.at (system, page_count-1).penalty_
- + lines_.back ().page_penalty_ + lines_.back ().turn_penalty_;
-
- ret.demerits_ = 0;
- for (vsize p = page_count; p--;)
- {
- assert (system != VPOS);
-
- Page_spacing_node const &ps = state_.at (system, p);
- ret.force_[p] = ps.force_;
- ret.demerits_ += ps.force_ * ps.force_;
- if (p == 0)
- ret.systems_per_page_[p] = system + 1;
- else
- ret.systems_per_page_[p] = system - ps.prev_;
- system = ps.prev_;
- }
- ret.demerits_ += ret.penalty_;
- return ret;
-}
-
-void
-Page_spacer::resize (vsize page_count)
-{
- assert (page_count > 0);
-
- if (max_page_count_ >= page_count)
- return;
-
- state_.resize (lines_.size (), page_count, Page_spacing_node ());
- for (vsize page = max_page_count_; page < page_count; page++)
- for (vsize line = page; line < lines_.size (); line++)
- if (!calc_subproblem (page, line))
- break;
-
- max_page_count_ = page_count;
-}
-
-bool
-Page_spacer::calc_subproblem (vsize page, vsize line)
-{
- Page_spacing space (page_height_);
- Page_spacing_node &cur = state_.at (line, page);
- bool ragged = ragged_ || (ragged_last_ && line == lines_.size () - 1);
-
- for (vsize page_start = line+1; page_start > page && page_start--;)
- {
- Page_spacing_node const *prev = page > 0 ? &state_.at (page_start-1, page-1) : 0;
-
- space.prepend_system (lines_[page_start]);
- if (page_start < line && (isinf (space.force_) || (space.force_ < 0 && ragged)))
- break;
-
- if (page > 0 || page_start == 0)
- {
- if (line == lines_.size () - 1 && ragged_last_ && space.force_ > 0)
- space.force_ = 0;
-
- /* we may have to deal with single lines that are taller than a page */
- if (isinf (space.force_) && page_start == line)
- space.force_ = -200000;
-
- Real dem = fabs (space.force_) + (prev ? prev->demerits_ : 0);
- Real penalty = 0;
- if (page_start > 0)
- penalty = lines_[page_start-1].page_penalty_
- + (page % 2 == 0) ? lines_[page_start-1].turn_penalty_ : 0;
-
- dem += penalty;
- if (dem < cur.demerits_ || page_start == line)
- {
- cur.demerits_ = dem;
- cur.force_ = space.force_;
- cur.penalty_ = penalty + (prev ? prev->penalty_ : 0);
- cur.prev_ = page_start - 1;
- }
- }
-
- if (page_start > 0
- && lines_[page_start-1].page_permission_ == ly_symbol2scm ("force"))
- break;
- }
- return !isinf (cur.demerits_);
-}
-
-vsize
-min_page_count (vector<Line_details> const &uncompressed_lines,
- Real page_height, bool ragged, bool ragged_last)
-{
- vsize ret = 1;
- Real cur_rod_height = 0;
- vector<Line_details> lines = compress_lines (uncompressed_lines);
-
- assert (lines.size ());
- for (vsize i = lines.size (); i--;)
- {
- bool rag = ragged || (ragged_last && ret == 1);
- Real ext_len = lines[i].extent_.length ();
- Real next_height = cur_rod_height + ext_len
- + (rag ? lines[i].space_ : 0)
- + ((cur_rod_height > 0) ? lines[i].padding_: 0);
-
- if ((next_height > page_height && cur_rod_height > 0)
- || (i < lines.size () - 1 && lines[i].page_permission_ == ly_symbol2scm ("force")))
- {
- ret++;
- cur_rod_height = ext_len + (rag ? lines[i].space_ : 0);
- }
- else
- cur_rod_height = next_height;
- }
-
- return ret;
-}
-
-Spacing_result
-space_systems_on_n_pages (vector<Line_details> const &lines,
- vsize n,
- Real page_height,
- bool ragged,
- bool ragged_last)
-{
- vector<Line_details> compressed_lines = compress_lines (lines);
- Spacing_result ret;
- assert (n >= min_page_count (lines, page_height, ragged, ragged_last));
-
- if (n > compressed_lines.size ())
- return Spacing_result ();
- if (n == 1)
- ret = space_systems_on_1_page (compressed_lines, page_height, ragged || ragged_last);
- else if (n == 2)
- ret = space_systems_on_2_pages (compressed_lines, page_height, ragged, ragged_last);
-
- Page_spacer ps (compressed_lines, page_height, ragged, ragged_last);
- ret = ps.solve (n);
-
- ret.systems_per_page_ = uncompress_solution (ret.systems_per_page_, compressed_lines);
- return ret;
-}
-
-Spacing_result
-space_systems_on_n_or_one_more_pages (vector<Line_details> const &lines,
- vsize n,
- Real page_height,
- Real odd_pages_penalty,
- bool ragged,
- bool ragged_last)
-{
- Spacing_result n_res = space_systems_on_n_pages (lines, n, page_height, ragged, ragged_last);
- Spacing_result m_res = space_systems_on_n_pages (lines, n+1, page_height, ragged, ragged_last);
- n_res.demerits_ += odd_pages_penalty;
- n_res.force_.back () += odd_pages_penalty;
-
- if (n_res.demerits_ < m_res.demerits_)
- return n_res;
- return m_res;
-}
-
-Spacing_result
-space_systems_on_best_pages (vector<Line_details> const &lines,
- Real page_height,
- Real odd_pages_penalty,
- bool ragged,
- bool ragged_last)
-{
- vector<Line_details> compressed_lines = compress_lines (lines);
- vsize min_p_count = min_page_count (compressed_lines, page_height, ragged, ragged_last);
-
- Page_spacer ps (compressed_lines, page_height, ragged, ragged_last);
- Spacing_result best = ps.solve (min_p_count);
- best.force_.back () += (min_p_count % 2) ? odd_pages_penalty : 0;
- best.demerits_ += (min_p_count % 2) ? odd_pages_penalty : 0;
-
- for (vsize i = min_p_count+1; i <= compressed_lines.size (); i++)
- {
- Spacing_result cur = ps.solve (i);
- cur.demerits_ += (i % 2) ? odd_pages_penalty : 0;
- if (cur.demerits_ < best.demerits_)
- best = cur;
- }
-
- best.systems_per_page_ = uncompress_solution (best.systems_per_page_, compressed_lines);
- return best;
-}
+++ /dev/null
-/*
- page-turn-engraver.cc -- implement Page_turn_engraver
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "engraver.hh"
-
-#include "context.hh"
-#include "duration.hh"
-#include "grob.hh"
-#include "international.hh"
-#include "moment.hh"
-#include "paper-column.hh"
-#include "stream-event.hh"
-#include "warn.hh"
-
-#include "translator.icc"
-
-class Page_turn_event {
-public:
- SCM permission_;
- Real penalty_;
- Interval_t<Rational> duration_;
-
- Page_turn_event (Rational start, Rational end, SCM perm, Real pen)
- {
- duration_[LEFT] = start;
- duration_[RIGHT] = end;
- permission_ = perm;
- penalty_ = pen;
- }
-
- /* Suppose we have decided on a possible page turn, only to change
- out mind later (for example, if there is a volta repeat and it
- would be difficult to turn the page back). Then we need to
- re-penalize a region of the piece. Depending on how the events
- intersect, we may have to split it into as many as 3 pieces.
- */
- vector<Page_turn_event> penalize (Page_turn_event const &penalty)
- {
- Interval_t<Rational> intersect = intersection (duration_, penalty.duration_);
- vector<Page_turn_event> ret;
-
- if (intersect.is_empty ())
- {
- ret.push_back (*this);
- return ret;
- }
-
- Real new_pen = max (penalty_, penalty.penalty_);
-
- if (duration_[LEFT] < penalty.duration_[LEFT])
- ret.push_back (Page_turn_event (duration_[LEFT], penalty.duration_[LEFT], permission_, penalty_));
-
- if (penalty.permission_ != SCM_EOL)
- ret.push_back (Page_turn_event (intersect[LEFT], intersect[RIGHT], permission_, new_pen));
-
- if (penalty.duration_[RIGHT] < duration_[RIGHT])
- ret.push_back (Page_turn_event (penalty.duration_[RIGHT], duration_[RIGHT], permission_, penalty_));
-
- return ret;
- }
-};
-
-class Page_turn_engraver : public Engraver
-{
- Moment rest_begin_;
- Moment repeat_begin_;
- Moment note_end_;
- Rational repeat_begin_rest_length_;
-
- vector<Page_turn_event> forced_breaks_;
- vector<Page_turn_event> automatic_breaks_;
- vector<Page_turn_event> repeat_penalties_;
-
- /* the next 3 are in sync (ie. same number of elements, etc.) */
- vector<Rational> breakable_moments_;
- vector<Grob*> breakable_columns_;
- vector<bool> special_barlines_;
-
- SCM max_permission (SCM perm1, SCM perm2);
- Real penalty (Rational rest_len);
- Grob *breakable_column (Page_turn_event const &);
-
-protected:
- DECLARE_TRANSLATOR_LISTENER (break);
- DECLARE_ACKNOWLEDGER (note_head);
-
-public:
- TRANSLATOR_DECLARATIONS (Page_turn_engraver);
- void stop_translation_timestep ();
- void start_translation_timestep ();
- void finalize ();
-};
-
-Page_turn_engraver::Page_turn_engraver ()
-{
- repeat_begin_ = Moment (-1);
- repeat_begin_rest_length_ = 0;
- rest_begin_ = 0;
- note_end_ = 0;
-}
-
-Grob*
-Page_turn_engraver::breakable_column (Page_turn_event const &brk)
-{
- vsize start = lower_bound (breakable_moments_, brk.duration_[LEFT], less<Rational> ());
- vsize end = upper_bound (breakable_moments_, brk.duration_[RIGHT], less<Rational> ());
-
- if (start == breakable_moments_.size ())
- return NULL;
- if (end == 0)
- return NULL;
- end--;
-
- for (vsize i = end + 1; i-- > start;)
- if (special_barlines_[i])
- return breakable_columns_[i];
-
- return breakable_columns_[end];
-}
-
-Real
-Page_turn_engraver::penalty (Rational rest_len)
-{
- Rational min_turn = robust_scm2moment (get_property ("minimumPageTurnLength"), Moment (1)).main_part_;
-
- return (rest_len < min_turn) ? infinity_f : 0;
-}
-
-void
-Page_turn_engraver::acknowledge_note_head (Grob_info gi)
-{
- SCM dur_log_scm = gi.grob ()->get_property ("duration-log");
- if (!scm_is_number (dur_log_scm))
- return;
-
- int dur_log = scm_to_int (dur_log_scm);
- int dot_count = robust_scm2int (gi.grob ()->get_property ("dot-count"), 0);
-
- if (rest_begin_ < now_mom ())
- {
- Real pen = penalty ((now_mom () - rest_begin_).main_part_);
- if (!isinf (pen))
- automatic_breaks_.push_back (Page_turn_event (rest_begin_.main_part_,
- now_mom ().main_part_,
- ly_symbol2scm ("allow"), 0));
- }
-
- if (rest_begin_ <= repeat_begin_)
- repeat_begin_rest_length_ = (now_mom () - repeat_begin_).main_part_;
- note_end_ = now_mom () + Moment (Duration (dur_log, dot_count).get_length ());
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Page_turn_engraver, break);
-void
-Page_turn_engraver::listen_break (Stream_event *ev)
-{
- string name = ly_scm2string (scm_symbol_to_string (ev->get_property ("class")));
-
- if (name == "page-turn-event")
- {
- SCM permission = ev->get_property ("break-permission");
- Real penalty = robust_scm2double (ev->get_property ("break-penalty"), 0);
- Rational now = now_mom ().main_part_;
-
- forced_breaks_.push_back (Page_turn_event (now, now, permission, penalty));
- }
-}
-
-void
-Page_turn_engraver::start_translation_timestep ()
-{
- /* What we want to do is to build a list of all the
- breakable paper columns. In general, paper-columns won't be marked as
- such until the Paper_column_engraver has done stop_translation_timestep.
-
- Therefore, we just grab /all/ paper columns (in the
- stop_translation_timestep, since they're not created here yet)
- and remove the non-breakable ones at the beginning of the following
- timestep.
- */
-
- if (breakable_columns_.size () && !Paper_column::is_breakable (breakable_columns_.back ()))
- {
- breakable_columns_.pop_back ();
- breakable_moments_.pop_back ();
- special_barlines_.pop_back ();
- }
-}
-
-void
-Page_turn_engraver::stop_translation_timestep ()
-{
- Grob *pc = unsmob_grob (get_property ("currentCommandColumn"));
-
- if (pc)
- {
- breakable_columns_.push_back (pc);
- breakable_moments_.push_back (now_mom ().main_part_);
-
- SCM bar_scm = get_property ("whichBar");
- string bar = robust_scm2string (bar_scm, "");
-
- special_barlines_.push_back (bar != "" && bar != "|");
- }
-
- /* C&P from Repeat_acknowledge_engraver */
- SCM cs = get_property ("repeatCommands");
- bool start = false;
- bool end = false;
-
- for (; scm_is_pair (cs); cs = scm_cdr (cs))
- {
- SCM command = scm_car (cs);
- if (command == ly_symbol2scm ("start-repeat"))
- start = true;
- else if (command == ly_symbol2scm ("end-repeat"))
- end = true;
- }
-
- if (end && repeat_begin_.main_part_ >= Moment (0))
- {
- Rational now = now_mom ().main_part_;
- Real pen = penalty ((now_mom () - rest_begin_).main_part_ + repeat_begin_rest_length_);
- Moment *m = unsmob_moment (get_property ("minimumRepeatLengthForPageTurn"));
- if (m && *m > (now_mom () - repeat_begin_))
- pen = infinity_f;
-
- if (pen == infinity_f)
- repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, SCM_EOL, -infinity_f));
- else
- repeat_penalties_.push_back (Page_turn_event (repeat_begin_.main_part_, now, ly_symbol2scm ("allow"), pen));
-
- repeat_begin_ = Moment (-1);
- }
-
- if (start)
- {
- repeat_begin_ = now_mom ();
- repeat_begin_rest_length_ = 0;
- }
- rest_begin_ = note_end_;
-}
-
-/* return the most permissive symbol (where force is the most permissive and
- forbid is the least
-*/
-SCM
-Page_turn_engraver::max_permission (SCM perm1, SCM perm2)
-{
- if (perm1 == SCM_EOL)
- return perm2;
- if (perm1 == ly_symbol2scm ("allow") && perm2 == ly_symbol2scm ("force"))
- return perm2;
- return perm1;
-}
-
-void
-Page_turn_engraver::finalize ()
-{
- vsize rep_index = 0;
- vector<Page_turn_event> auto_breaks;
-
- /* filter the automatic breaks through the repeat penalties */
- for (vsize i = 0; i < automatic_breaks_.size (); i++)
- {
- Page_turn_event &brk = automatic_breaks_[i];
-
- /* find the next applicable repeat penalty */
- for (;
- rep_index < repeat_penalties_.size ()
- && repeat_penalties_[rep_index].duration_[RIGHT] <= brk.duration_[LEFT];
- rep_index++)
- ;
-
- if (rep_index >= repeat_penalties_.size ()
- || brk.duration_[RIGHT] <= repeat_penalties_[rep_index].duration_[LEFT])
- auto_breaks.push_back (brk);
- else
- {
- vector<Page_turn_event> split = brk.penalize (repeat_penalties_[rep_index]);
-
- /* it's possible that the last of my newly-split events overlaps the next repeat_penalty,
- in which case we need to refilter that event */
- if (rep_index < repeat_penalties_.size () - 1
- && split.size ()
- && split.back ().duration_[RIGHT] > repeat_penalties_[rep_index+1].duration_[LEFT])
- {
- automatic_breaks_[i] = split.back ();
- split.pop_back ();
- i--;
- }
- auto_breaks.insert (auto_breaks.end (), split.begin (), split.end ());
- }
- }
-
- /* apply the automatic breaks */
- for (vsize i = 0; i < auto_breaks.size (); i++)
- {
- Page_turn_event const &brk = auto_breaks[i];
- Grob *pc = breakable_column (auto_breaks[i]);
- if (pc)
- {
- SCM perm = max_permission (pc->get_property ("page-turn-permission"), brk.permission_);
- Real pen = min (robust_scm2double (pc->get_property ("page-turn-penalty"), infinity_f), brk.penalty_);
- pc->set_property ("page-turn-permission", perm);
- pc->set_property ("page-turn-penalty", scm_from_double (pen));
- }
- }
-
- /* apply the manual breaks */
- for (vsize i = 0; i < forced_breaks_.size (); i++)
- {
- Page_turn_event const &brk = forced_breaks_[i];
- Grob *pc = breakable_column (forced_breaks_[i]);
- if (pc)
- {
- pc->set_property ("page-turn-permission", brk.permission_);
- pc->set_property ("page-turn-penalty", scm_from_double (brk.penalty_));
- }
- }
-}
-
-ADD_ACKNOWLEDGER (Page_turn_engraver, note_head);
-ADD_TRANSLATOR (Page_turn_engraver,
- /* doc */ "Decide where page turns are allowed to go",
- /* create */ "",
- /* accept */ "",
- /* read */
- "minimumPageTurnLength "
- "minimumRepeatLengthForPageTurn ",
- /* write */ ""
- );
+++ /dev/null
-/*
- page-turn-page-breaking.cc -- implement Page_turn_page_breaking
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Joe Neeman <joeneeman@gmail.com>
-*/
-
-#include "page-turn-page-breaking.hh"
-
-#include "international.hh"
-#include "item.hh"
-#include "output-def.hh"
-#include "page-spacing.hh"
-#include "paper-book.hh"
-#include "paper-score.hh"
-#include "paper-system.hh"
-#include "system.hh"
-#include "warn.hh"
-
-static bool
-is_break (Grob *g)
-{
- return scm_is_symbol (g->get_property ("page-turn-permission"));
-}
-
-Page_turn_page_breaking::Page_turn_page_breaking (Paper_book *pb)
- : Page_breaking (pb, is_break)
-{
-}
-
-Page_turn_page_breaking::~Page_turn_page_breaking ()
-{
-}
-
-Real
-Page_turn_page_breaking::calc_demerits (const Break_node &me)
-{
- Real prev_f = 0;
- Real prev_dem = 0;
- Real page_weighting = robust_scm2double (book_->paper_->c_variable ("page-spacing-weight"), 1);
- if (me.prev_ != VPOS)
- {
- prev_f = state_[me.prev_].force_;
- prev_dem = state_[me.prev_].demerits_;
- }
-
- Real dem = me.force_ * me.force_ * page_weighting
- + me.line_force_ * me.line_force_
- + fabs (me.force_ - prev_f);
- if (isinf (me.line_force_) || isinf (me.force_) || me.page_count_ == 0)
- dem = infinity_f;
-
- return dem + prev_dem + me.penalty_ + me.line_penalty_;
-}
-
-Page_turn_page_breaking::Break_node
-Page_turn_page_breaking::put_systems_on_pages (vsize start,
- vsize end,
- vector<Line_details> const &lines,
- Line_division const &div,
- int page_number)
-{
- bool last = end == breaks_.size () - 1;
- bool ragged_all = to_boolean (book_->paper_->c_variable ("ragged-bottom"));
- bool ragged_last = last && to_boolean (book_->paper_->c_variable ("ragged-last-bottom"));
- Real page_h = page_height (1, false); // FIXME
- SCM force_sym = last ? ly_symbol2scm ("blank-last-page-force") : ly_symbol2scm ("blank-page-force");
- Real blank_force = robust_scm2double (book_->paper_->lookup_variable (force_sym), 0);
- int min_p_count = min_page_count (lines, page_h, ragged_all, ragged_last);
- bool auto_first = to_boolean (book_->paper_->c_variable ("auto-first-page-number"));
-
- /* If [START, END] does not contain an intermediate
- breakpoint, we may need to consider solutions that result in a bad turn.
- In this case, we won't abort if the min_page_count is too big */
- if (start < end - 1 && min_p_count > 2)
- return Break_node ();
-
- /* if PAGE-NUMBER is odd, we are starting on a right hand page. That is, we
- have the options
- PAGE-NUMBER odd:
- - even number of pages + a blank page
- - odd number of pages
- PAGE-NUMBER even:
- - odd number of pages + a blank page
- - even number of pages
-
- No matter which case PAGE-NUMBER falls into, we take the second choice if
- min_p_count has that evenness. (For example, if PAGE-NUMBER is even and
- min_p_count is even, we don't even consider the blank page option). */
-
- Spacing_result result;
- if (start == 0 && auto_first)
- {
- if (min_p_count % 2)
- result = space_systems_on_n_or_one_more_pages (lines, min_p_count, page_h, 0, ragged_all, ragged_last);
- else
- result = space_systems_on_n_pages (lines, min_p_count, page_h, ragged_all, ragged_last);
- }
- else if (page_number % 2 == min_p_count % 2)
- result = space_systems_on_n_pages (lines, min_p_count, page_h, ragged_all, ragged_last);
- else
- result = space_systems_on_n_or_one_more_pages (lines, min_p_count, page_h, blank_force, ragged_all, ragged_last);
-
- Break_node ret;
- ret.prev_ = start - 1;
- ret.break_pos_ = end;
- ret.page_count_ = result.force_.size ();
- ret.first_page_number_ = page_number;
- if (auto_first && start == 0)
- ret.first_page_number_ += 1 - (ret.page_count_ % 2);
- ret.force_ = 0;
- for (vsize i = 0; i < result.force_.size (); i++)
- ret.force_ += fabs (result.force_[i]);
-
- ret.penalty_ = result.penalty_;
- ret.div_ = div;
- ret.system_count_ = result.systems_per_page_;
-
- ret.too_many_lines_ = true;
- ret.line_force_ = 0;
- ret.line_penalty_ = 0;
- for (vsize i = 0; i < lines.size (); i++)
- {
- ret.line_force_ += fabs (lines[i].force_);
- ret.line_penalty_ += lines[i].break_penalty_;
- if (lines[i].force_ < 0)
- ret.too_many_lines_ = false;
- }
- return ret;
-}
-
-/* "final page" meaning the number of the final right-hand page,
- which always has an odd page number */
-vsize
-Page_turn_page_breaking::final_page_num (Break_node const &b)
-{
- vsize end = b.first_page_number_ + b.page_count_;
- return end + 1 - (end % 2);
-}
-
-void
-Page_turn_page_breaking::calc_subproblem (vsize ending_breakpoint)
-{
- vsize end = ending_breakpoint + 1;
- Break_node best;
- Break_node cur;
- Break_node this_start_best;
- vsize prev_best_system_count = 0;
-
- for (vsize start = end; start--;)
- {
- if (start < end-1
- && breakpoint_property (start+1, "page-turn-permission") == ly_symbol2scm ("force"))
- break;
-
- if (start > 0 && best.demerits_ < state_[start-1].demerits_)
- continue;
-
- int p_num = robust_scm2int (book_->paper_->c_variable ("first-page-number"), 1);
- if (start > 0)
- {
- /* except possibly for the first page, enforce the fact that first_page_number_
- should always be even (left hand page).
- TODO: are there different conventions in right-to-left languages?
- */
- p_num = state_[start-1].first_page_number_ + state_[start-1].page_count_;
- p_num += p_num % 2;
- }
-
- Line_division min_division;
- Line_division max_division;
-
- vsize min_sys_count = min_system_count (start, end);
- vsize max_sys_count = max_system_count (start, end);
- this_start_best.demerits_ = infinity_f;
-
- bool ok_page = true;
-
- /* heuristic: we've just added a breakpoint, we'll need at least as
- many systems as before */
- min_sys_count = max (min_sys_count, prev_best_system_count);
- for (vsize sys_count = min_sys_count; sys_count <= max_sys_count && ok_page; sys_count++)
- {
- vector<Line_division> div = line_divisions (start, end, sys_count, min_division, max_division);
- bool found = false;
-
- for (vsize d = 0; d < div.size (); d++)
- {
- vector<Line_details> line = line_details (start, end, div[d]);
-
- cur = put_systems_on_pages (start, end, line, div[d], p_num);
- cur.demerits_ = calc_demerits (cur);
-
- if (isinf (cur.demerits_)
- || (cur.page_count_ > 2
- && (!isinf (this_start_best.demerits_))
- && final_page_num (cur) > final_page_num (this_start_best)))
- {
- ok_page = false;
- break;
- }
-
- if (cur.demerits_ < this_start_best.demerits_)
- {
- found = true;
- this_start_best = cur;
- prev_best_system_count = sys_count;
-
- /* heuristic: if we increase the number of systems, we can bound the
- division from below by our current best division */
- min_division = div[d];
- }
- }
- if (!found && this_start_best.too_many_lines_)
- break;
- }
- if (isinf (this_start_best.demerits_))
- {
- assert (!isinf (best.demerits_) && start < end - 1);
- break;
- }
-
- if (start == 0 && end == 1
- && this_start_best.first_page_number_ == 1
- && this_start_best.page_count_ > 1)
- warning (_ ("couldn't fit the first page turn onto a single page. "
- "Consider setting first-page-number to an even number."));
-
- if (this_start_best.demerits_ < best.demerits_)
- best = this_start_best;
- }
- state_.push_back (best);
-}
-
-SCM
-Page_turn_page_breaking::solve ()
-{
- state_.clear ();
- message (_f ("Calculating page and line breaks (%d possible page breaks)...",
- (int)breaks_.size () - 1) + " ");
- for (vsize i = 0; i < breaks_.size () - 1; i++)
- {
- calc_subproblem (i);
- progress_indication (string ("[") + to_string (i + 1) + "]");
- }
- progress_indication ("\n");
-
- vector<Break_node> breaking;
- int i = state_.size () - 1;
- while (i >= 0)
- {
- breaking.push_back (state_[i]);
- i = state_[i].prev_;
- }
- reverse (breaking);
-
- message (_ ("Drawing systems..."));
- SCM systems = make_lines (&breaking);
- return make_pages (breaking, systems);
-}
-
-/* do the line breaking in all the scores and return a big list of systems */
-SCM
-Page_turn_page_breaking::make_lines (vector<Break_node> *psoln)
-{
- vector<Break_node> &soln = *psoln;
- for (vsize n = 0; n < soln.size (); n++)
- {
- vsize start = n > 0 ? soln[n-1].break_pos_ : 0;
- vsize end = soln[n].break_pos_;
-
- break_into_pieces (start, end, soln[n].div_);
- }
-
- return systems ();
-}
-
-SCM
-Page_turn_page_breaking::make_pages (vector<Break_node> const &soln, SCM systems)
-{
- vector<vsize> lines_per_page;
- for (vsize i = 0; i < soln.size (); i++)
- {
- for (vsize j = 0; j < soln[i].page_count_; j++)
- lines_per_page.push_back (soln[i].system_count_[j]);
-
- if (i < soln.size () - 1 && (soln[i].first_page_number_ + soln[i].page_count_) % 2)
- /* add a blank page */
- lines_per_page.push_back (0);
- }
-
- /* this should only actually modify first-page-number if
- auto-first-page-number was true. */
- book_->paper_->set_variable (ly_symbol2scm ("first-page-number"),
- scm_from_int (soln[0].first_page_number_));
- return Page_breaking::make_pages (lines_per_page, systems);
-}
Stencil
-Pango_font::pango_item_string_stencil (PangoItem const *item, string str,
- bool tight_bbox) const
+Pango_font::pango_item_string_stencil (PangoItem const *item, string str) const
{
const int GLYPH_NAME_LEN = 256;
char glyph_name[GLYPH_NAME_LEN];
PangoFcFont);
FT_Face ftface = pango_fc_font_lock_face (fcfont);
-
- PangoRectangle const *which_rect
- = (tight_bbox)
- ? &ink_rect
- : &logical_rect;
-
- Box b (Interval (PANGO_LBEARING (logical_rect),
- PANGO_RBEARING (logical_rect)),
- Interval (-PANGO_DESCENT (*which_rect),
- PANGO_ASCENT (*which_rect)));
+ Box b (Interval (PANGO_LBEARING (ink_rect),
+ PANGO_RBEARING (ink_rect)),
+ Interval (-PANGO_DESCENT (ink_rect),
+ PANGO_ASCENT (ink_rect)));
b.scale (scale_);
char const *ps_name_str0 = FT_Get_Postscript_Name (ftface);
FcPattern *fcpat = fcfont->font_pattern;
- FcChar8 *file_name_as_ptr = 0;
- FcPatternGetString (fcpat, FC_FILE, 0, &file_name_as_ptr);
+ char *file_name_as_ptr = 0;
+ FcPatternGetString (fcpat, FC_FILE, 0, (FcChar8 **) & file_name_as_ptr);
string file_name;
if (file_name_as_ptr)
{
/* Normalize file name. */
- file_name = File_name ((char const *)file_name_as_ptr).to_string ();
+ file_name = File_name (file_name_as_ptr).to_string ();
}
SCM glyph_exprs = SCM_EOL;
if (glyph_name[0] == '\0' && has_glyph_names)
{
- programming_error ("Glyph has no name, but font supports glyph naming. Skipping glyph: "
- + description_string ());
+ programming_error ("Glyph has no name, but font supports glyph naming. Skipping glyph.");
continue;
}
return physical_font_tab_;
}
-
-Stencil
-Pango_font::word_stencil (string str) const
-{
- return text_stencil (str, true);
-}
-
Stencil
Pango_font::text_stencil (string str) const
-{
- return text_stencil (str, false);
-}
-
-Stencil
-Pango_font::text_stencil (string str, bool tight) const
{
GList *items
= pango_itemize (context_,
{
PangoItem *item = (PangoItem *) ptr->data;
- Stencil item_stencil = pango_item_string_stencil (item, str, tight);
+ Stencil item_stencil = pango_item_string_stencil (item, str);
if (text_dir == RIGHT)
{
/*
For Pango based backends, we take a shortcut.
*/
+ char *descr_string = pango_font_description_to_string (pango_description_);
SCM exp
= scm_list_3 (ly_symbol2scm ("utf-8-string"),
- scm_makfrom0str (description_string ().c_str ()),
+ scm_makfrom0str (descr_string),
scm_makfrom0str (str.c_str ()));
+ g_free (descr_string);
+
Box b (Interval (0, 0), Interval (0, 0));
b.unite (dest.extent_box ());
return Stencil (b, exp);
return dest;
}
-string
-Pango_font::description_string () const
-{
- char *descr_string = pango_font_description_to_string (pango_description_);
- string s (descr_string);
- g_free (descr_string);
- return s;
-}
-
-
SCM
Pango_font::font_file_name () const
{
#include "paper-book.hh"
-#include "grob.hh"
#include "main.hh"
#include "output-def.hh"
#include "paper-score.hh"
return title;
}
-/* read the breakbefore property of a score block and set up the preceding
- system-spec to honour it. That is, SYM should be the system spec that
- immediately precedes the score (from which HEADER is taken)
- in the get_system_specs() list */
void
-set_system_penalty (SCM sys, SCM header)
+set_system_penalty (Prob *ps, SCM header)
{
if (ly_is_module (header))
{
if (SCM_VARIABLEP (force)
&& scm_is_bool (SCM_VARIABLE_REF (force)))
{
- bool b = to_boolean (SCM_VARIABLE_REF (force));
- SCM sym = b ? ly_symbol2scm ("force") : SCM_EOL;
-
- if (Paper_score *ps = dynamic_cast<Paper_score*> (unsmob_music_output (sys)))
- {
- vector<Grob*> cols = ps->get_columns ();
- if (cols.size ())
- cols.back ()->set_property ("page-break-permission", sym);
- }
- else if (Prob *pb = unsmob_prob (sys))
- pb->set_property ("page-break-permission", sym);
+ ps->set_property ("penalty",
+ scm_from_int(to_boolean (SCM_VARIABLE_REF (force))
+ ? -10000
+ : 10000));
}
}
}
SCM props = paper_->lookup_variable (ly_symbol2scm ("score-title-properties"));
Prob *ps = make_paper_system (props);
paper_system_set_stencil (ps, title);
+ set_system_penalty (ps, header);
return ps->self_scm();
}
SCM props = paper_->lookup_variable (ly_symbol2scm ("book-title-properties"));
Prob *ps = make_paper_system (props);
paper_system_set_stencil (ps, title);
+ set_system_penalty (ps, header_);
system_specs = scm_cons (ps->self_scm (), system_specs);
ps->unprotect ();
paper_->self_scm ());
SCM header = SCM_EOL;
- for (SCM s = scm_reverse (scores_); scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = scm_reverse (scores_); s != SCM_EOL; s = scm_cdr (s))
{
if (ly_is_module (scm_car (s)))
{
if (Paper_score *pscore = dynamic_cast<Paper_score *> (mop))
{
SCM title = get_score_title (header);
-
- if (scm_is_pair (system_specs))
- set_system_penalty (scm_car (system_specs), header);
-
if (unsmob_prob (title))
{
system_specs = scm_cons (title, system_specs);
int i = 0;
Prob *last = 0;
- for (SCM s = systems_; scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = systems_; s != SCM_EOL; s = scm_cdr (s))
{
Prob *ps = unsmob_prob (scm_car (s));
ps->set_property ("number", scm_from_int (++i));
return pages_;
pages_ = SCM_EOL;
- SCM proc = paper_->c_variable ("page-breaking-wrapper");
- pages_ = scm_apply_0 (proc, scm_list_1(self_scm ()));
-
- /* set systems_ from the pages */
- if (systems_ == SCM_BOOL_F)
- {
- systems_ = SCM_EOL;
- for (SCM p = pages_; scm_is_pair (p); p = scm_cdr (p))
- {
- Prob *page = unsmob_prob (scm_car (p));
- SCM systems = page->get_property ("lines");
-
- systems_ = scm_append (scm_list_2 (systems_, systems));
- }
- }
-
+ SCM proc = paper_->c_variable ("page-breaking");
+ pages_ = scm_apply_0 (proc, scm_list_2 (systems (), self_scm ()));
return pages_;
}
#include "paper-column-engraver.hh"
#include "system.hh"
-#include "international.hh"
-#include "axis-group-interface.hh"
-#include "context.hh"
#include "item.hh"
-#include "note-spacing.hh"
#include "paper-column.hh"
-#include "pointer-group-interface.hh"
#include "staff-spacing.hh"
-#include "system.hh"
+#include "note-spacing.hh"
+#include "pointer-group-interface.hh"
+#include "context.hh"
+#include "score-context.hh"
+#include "axis-group-interface.hh"
#include "warn.hh"
#include "translator.icc"
breaks_ = 0;
system_ = 0;
first_ = true;
+ last_breakable_column_ = 0;
+ last_breakable_moment_ = Moment (-1);
}
void
if (command_column_)
{
command_column_->set_property ("line-break-permission", ly_symbol2scm ("allow"));
- command_column_->set_property ("page-turn-permission", ly_symbol2scm ("allow"));
system_->set_bound (RIGHT, command_column_);
}
}
*/
Paper_column *p1 = make_paper_column ("NonMusicalPaperColumn");
Paper_column *p2 = make_paper_column ("PaperColumn");
- /*
- The columns are timestamped with now_mom () in
- stop_translation_timestep. Cannot happen now, because the
- first column is sometimes created before now_mom is initialised.
- */
+
+ SCM m = now_mom ().smobbed_copy ();
+ p1->set_property ("when", m);
+ p2->set_property ("when", m);
set_columns (p1, p2);
}
ly_symbol2scm ("spacing-wishes"),
gi.grob ());
}
-
void
Paper_column_engraver::acknowledge_note_spacing (Grob_info gi)
{
system_->add_column (musical_column_);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Paper_column_engraver, break);
-void
-Paper_column_engraver::listen_break (Stream_event *ev)
+bool
+Paper_column_engraver::try_music (Music *m)
{
- break_events_.push_back (ev);
+ break_events_.push_back (m);
+
+ return true;
}
void
for (vsize i = 0; i < break_events_.size (); i++)
{
string prefix;
- SCM name_sym = break_events_[i]->get_property ("class");
- string name = ly_scm2string (scm_symbol_to_string (name_sym));
- size_t end = name.rfind ("-event");
- if (end)
- prefix = name.substr (0, end);
+ SCM name = break_events_[i]->get_property ("name");
+ if (name == ly_symbol2scm ("LineBreakEvent"))
+ prefix = "line-break";
+ else if (name == ly_symbol2scm ("PageBreakEvent"))
+ prefix = "page-break";
+ else if (name == ly_symbol2scm ("PageTurnEvent"))
+ prefix = "page-turn";
else
{
programming_error ("Paper_column_engraver doesn't know about this break-event");
return;
}
-
string perm_str = prefix + "-permission";
string pen_str = prefix + "-penalty";
void
Paper_column_engraver::stop_translation_timestep ()
{
- SCM m = now_mom ().smobbed_copy ();
- command_column_->set_property ("when", m);
- musical_column_->set_property ("when", m);
-
for (vsize i = 0; i < items_.size (); i++)
{
Item *elem = items_[i];
else if (Paper_column::is_breakable (command_column_))
{
breaks_++;
-
+ last_breakable_column_ = command_column_;
+ last_breakable_moment_ = now_mom ();
if (! (breaks_%8))
progress_indication ("[" + to_string (breaks_) + "]");
}
+ SCM page_br = get_property ("allowPageTurn");
+ if (scm_is_pair (page_br) && last_breakable_moment_ >= Rational (0))
+ {
+ SCM pen = scm_cdr (page_br);
+ Moment *m = unsmob_moment (scm_car (page_br));
+ if (m && scm_is_number (pen) && *m <= last_breakable_moment_)
+ {
+ last_breakable_column_->set_property ("page-turn-permission", ly_symbol2scm ("allow"));
+ last_breakable_column_->set_property ("page-turn-penalty", pen);
+ }
+ }
+
context ()->get_score_context ()->unset_property (ly_symbol2scm ("forbidBreak"));
+ context ()->get_score_context ()->unset_property (ly_symbol2scm ("allowPageTurn"));
first_ = false;
break_events_.clear ();
/* accept */ "break-event",
/* read */
"forbidBreak "
- ,
+ "allowPageTurn",
/* write */
"forbidBreak "
+ "allowPageTurn "
"currentCommandColumn "
- "currentMusicalColumn "
- );
+ "currentMusicalColumn");
return system_;
}
-void
-Paper_column::set_system (System *s)
-{
- system_ = s;
-}
-
Paper_column *
Paper_column::get_column () const
{
rank_ = src.rank_;
}
-int
-Paper_column::compare (Grob * const &a,
- Grob * const &b)
-{
- return sign (dynamic_cast<Paper_column*> (a)->rank_
- - dynamic_cast<Paper_column*> (b)->rank_);
-}
-
-bool
-Paper_column::less_than (Grob *const &a,
- Grob *const &b)
-{
- Paper_column *pa = dynamic_cast<Paper_column*> (a);
- Paper_column *pb = dynamic_cast<Paper_column*> (b);
-
- return pa->rank_ < pb->rank_;
-}
-
Moment
Paper_column::when_mom (Grob *me)
{
/* properties */
"between-cols "
"bounded-by-me "
- "grace-spacing "
"line-break-system-details "
"line-break-penalty "
"line-break-permission "
"page-turn-permission "
"shortest-playing-duration "
"shortest-starter-duration "
- "spacing "
"used "
"when ");
#include "dimensions.hh"
#include "file-name.hh"
#include "font-metric.hh"
-#include "input.hh"
+#include "input-smob.hh"
#include "lily-version.hh"
#include "main.hh"
#include "output-def.hh"
#include "all-font-metrics.hh"
#include "book.hh"
+#include "gourlay-breaking.hh"
#include "international.hh"
#include "main.hh"
#include "misc.hh"
retval.push_back (i);
}
- cols_ = all;
- break_indices_ = retval;
-
return retval;
}
-vector<vsize>
-Paper_score::get_break_indices () const
-{
- if (break_indices_.empty ())
- find_break_indices ();
- return break_indices_;
-}
-
-vector<Grob*>
-Paper_score::get_columns () const
-{
- if (cols_.empty ())
- find_break_indices ();
- return cols_;
-}
vector<Column_x_positions>
Paper_score::calc_breaking ()
{
- Constrained_breaking algorithm (this);
+ Break_algorithm *algorithm = 0;
vector<Column_x_positions> sol;
message (_ ("Calculating line breaks...") + " ");
int system_count = robust_scm2int (layout ()->c_variable ("system-count"), 0);
if (system_count)
- algorithm.resize (system_count);
-
- return algorithm.solve ();
+ {
+ Constrained_breaking *b = new Constrained_breaking;
+ b->resize (system_count);
+ algorithm = b;
+ }
+ else
+ algorithm = new Gourlay_breaking;
+
+ algorithm->set_pscore (this);
+ sol = algorithm->solve ();
+ delete algorithm;
+
+ return sol;
}
void
#include "engraver.hh"
+#include "warn.hh"
+#include "simple-closure.hh"
+#include "music.hh"
#include "grob.hh"
#include "item.hh"
#include "pointer-group-interface.hh"
-#include "simple-closure.hh"
-#include "stream-event.hh"
-#include "warn.hh"
#include "translator.icc"
void
Parenthesis_engraver::acknowledge_grob (Grob_info info)
{
- if (Stream_event *ev = info.event_cause ())
+ if (Music *music = info.music_cause ())
{
- if (to_boolean (ev->get_property ("parenthesize")))
+ if (to_boolean (music->get_property ("parenthesize")))
{
if (Item *victim = dynamic_cast<Item*> (info.grob ()))
{
Engraver *eng = dynamic_cast<Engraver*> (info.origin_translator ());
- Item *paren = eng->make_item ("ParenthesesItem", victim->self_scm ());
- Pointer_group_interface::add_grob (paren, ly_symbol2scm ("elements"), victim);
+ Item *paren = make_item_from_properties (eng,
+ ly_symbol2scm ("ParenthesesItem"),
+ victim->self_scm (),
+ "ParenthesesItem");
- paren->set_parent (victim, Y_AXIS);
+ Pointer_group_interface::add_grob (paren, ly_symbol2scm ("elements"), victim);
Real size = robust_scm2double (paren->get_property ("font-size"), 0.0)
+ robust_scm2double (victim->get_property ("font-size"), 0.0);
%{
-#define YYDEBUG 1
#define YYERROR_VERBOSE 1
#define YYPARSE_PARAM my_lily_parser
#define YYLEX_PARAM my_lily_parser
#include "context-def.hh"
#include "dimensions.hh"
#include "file-path.hh"
+#include "input-smob.hh"
#include "input.hh"
#include "international.hh"
#include "lily-guile.hh"
- Don't use lily module, create a new module instead.
- delay application of the function
*/
-#define LOWLEVEL_MAKE_SYNTAX(proc, args) \
- scm_apply_0 (proc, args)
-/* Syntactic Sugar. */
#define MAKE_SYNTAX(name, location, ...) \
- LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant (name), scm_list_n (PARSER->self_scm (), make_input (location), __VA_ARGS__, SCM_UNDEFINED));
+ scm_apply_0 (ly_lily_module_constant (name), scm_list_n (make_input (location), __VA_ARGS__, SCM_UNDEFINED));
+Music *property_op_to_music (SCM op);
+SCM context_spec_music (SCM type, SCM id, SCM m, SCM ops, bool create_new);
SCM get_next_unique_context_id ();
SCM get_next_unique_lyrics_context_id ();
+SCM make_lyric_combine_music (SCM name, SCM music);
SCM make_music_relative (Pitch start, SCM music);
-SCM run_music_function (Lily_parser *, SCM expr);
+Music *run_music_function (Lily_parser *, SCM expr);
+Music *set_property_music (SCM sym, SCM value);
SCM get_first_context_id (SCM type, Music *m);
-SCM make_chord_elements (SCM pitch, SCM dur, SCM modification_list);
+SCM make_chord (SCM pitch, SCM dur, SCM modification_list);
SCM make_chord_step (int step, int alter);
SCM make_simple_markup (SCM a);
bool is_duration (int t);
%token ADDQUOTE "\\addquote"
%token ALIAS "\\alias"
%token ALTERNATIVE "\\alternative"
-%token BOOK "\\book"
+%token BOOK "\book"
%token CHANGE "\\change"
%token CHORDMODE "\\chordmode"
%token CHORDS "\\chords"
%token TEMPO "\\tempo"
%token TIMES "\\times"
%token TRANSPOSE "\\transpose"
+%token TRANSPOSITION "\\transposition"
%token TYPE "\\type"
%token UNSET "\\unset"
%token WITH "\\with"
%token CHORD_COLON ":"
%token CHORD_MINUS "-"
%token CHORD_SLASH "/"
-%token ANGLE_OPEN "<"
-%token ANGLE_CLOSE ">"
-%token DOUBLE_ANGLE_OPEN "<<"
%token DOUBLE_ANGLE_CLOSE ">>"
+%token DOUBLE_ANGLE_OPEN "<<"
%token E_BACKSLASH "\\"
%token E_ANGLE_CLOSE "\\>"
%token E_CHAR "\\C[haracter]"
%token CHORDMODIFIERS
%token LYRIC_MARKUP
%token MULTI_MEASURE_REST
+%token SCM_T
%token <i> DIGIT
%token <i> E_UNSIGNED
%token <i> UNSIGNED
-/* Artificial tokens, for more generic function syntax */
-%token <i> EXPECT_MARKUP;
-%token <i> EXPECT_MUSIC;
-%token <i> EXPECT_SCM;
-/* After the last argument. */
-%token <i> EXPECT_NO_MORE_ARGS;
-
%token <scm> BOOK_IDENTIFIER
%token <scm> CHORDMODIFIER_PITCH
%token <scm> CHORD_MODIFIER
%token <scm> MARKUP_HEAD_SCM0_SCM1_SCM2
%token <scm> MARKUP_IDENTIFIER
%token <scm> MUSIC_FUNCTION
+%token <scm> MUSIC_FUNCTION_MARKUP
+%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP
+%token <scm> MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC
+%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC
+%token <scm> MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC
+%token <scm> MUSIC_FUNCTION_MUSIC
+%token <scm> MUSIC_FUNCTION_MUSIC_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM
+%token <scm> MUSIC_FUNCTION_SCM_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_MUSIC_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_SCM
+%token <scm> MUSIC_FUNCTION_SCM_SCM_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_SCM_SCM
+%token <scm> MUSIC_FUNCTION_SCM_SCM_SCM_MUSIC
+%token <scm> MUSIC_FUNCTION_SCM_SCM_SCM_SCM_MUSIC
%token <scm> MUSIC_IDENTIFIER
%token <scm> NOTENAME_PITCH
%token <scm> NUMBER_IDENTIFIER
%token <scm> REAL
%token <scm> RESTNAME
%token <scm> SCM_IDENTIFIER
-%token <scm> SCM_TOKEN
+%token <scm> SCM_T
%token <scm> SCORE_IDENTIFIER
%token <scm> STRING
%token <scm> STRING_IDENTIFIER
%type <i> tremolo_type
/* Music */
-%type <scm> composite_music
-%type <scm> grouped_music_list
-%type <scm> music
-%type <scm> prefix_composite_music
-%type <scm> repeated_music
-%type <scm> sequential_music
-%type <scm> simple_music
-%type <scm> simultaneous_music
+%type <scm> Composite_music
+%type <scm> Grouped_music_list
+%type <scm> Music
+%type <scm> Prefix_composite_music
+%type <scm> Repeated_music
+%type <scm> Sequential_music
+%type <scm> Simple_music
+%type <scm> Simultaneous_music
%type <scm> chord_body
%type <scm> chord_body_element
%type <scm> command_element
%type <scm> re_rhythmed_music
%type <scm> relative_music
%type <scm> simple_element
-%type <scm> simple_music_property_def
%type <scm> string_number_event
%type <scm> tempo_event
+%type <scm> toplevel_music
%type <outputdef> output_def_body
%type <outputdef> output_def_head
%type <outputdef> output_def
%type <outputdef> paper_block
-%type <scm> alternative_music
-%type <scm> generic_prefix_music_scm
-%type <scm> music_list
+%type <scm> Alternative_music
+%type <scm> Generic_prefix_music_scm
+%type <scm> Music_list
%type <scm> absolute_pitch
%type <scm> assignment_id
%type <scm> bare_number
+%type <scm> music_function_event
+%type <scm> music_function_chord_body
+%type <scm> music_function_musicless_prefix
%type <scm> bass_figure
%type <scm> figured_bass_modification
%type <scm> br_bass_figure
%type <scm> figure_spec
%type <scm> fraction
%type <scm> full_markup
-%type <scm> function_scm_argument
-%type <scm> function_arglist
-%type <scm> function_arglist_music_last
-%type <scm> function_arglist_nonmusic_last
-%type <scm> function_arglist_nonmusic
%type <scm> identifier_init
%type <scm> lilypond_header
%type <scm> lilypond_header_body
%type <scm> mode_changing_head
%type <scm> mode_changing_head_with_context
%type <scm> multiplied_duration
-%type <scm> music_function_identifier_musicless_prefix
-%type <scm> music_function_event
-%type <scm> music_function_chord_body
%type <scm> new_chord
%type <scm> new_lyrics
%type <scm> number_expression
%type <scm> property_operation
%type <scm> scalar
%type <scm> script_abbreviation
-%type <scm> simple_chord_elements
%type <scm> simple_markup
%type <scm> simple_string
%type <scm> steno_duration
%type <scm> step_number
%type <scm> step_numbers
%type <scm> string
+%type <scm> function_scm_argument
%type <score> score_block
%type <score> score_body
scm_call_2 (proc, PARSER->self_scm (), score->self_scm ());
score->unprotect ();
}
- | composite_music {
+ | toplevel_music {
Music *music = unsmob_music ($1);
SCM proc = PARSER->lexer_->lookup_identifier ("toplevel-music-handler");
scm_call_2 (proc, PARSER->self_scm (), music->self_scm ());
}
;
+toplevel_music:
+ Composite_music {
+ }
+ ;
+
embedded_scm:
- SCM_TOKEN
+ SCM_T
| SCM_IDENTIFIER
;
assignment:
assignment_id '=' identifier_init {
+ if (! is_regular_identifier ($1))
+ {
+#if 0
+ /* no longer valid with dashes in \paper{} block. */
+ @1.warning (_ ("identifier should have alphabetic characters only"));
+#endif
+ }
+
+
PARSER->lexer_->set_identifier ($1, $3);
/*
| context_def_spec_block {
$$ = $1;
}
- | music {
- /* Hack: Create event-chord around standalone events.
- Prevents the identifier from being interpreted as a post-event. */
- Music *mus = unsmob_music ($1);
- bool is_event = mus &&
- (scm_memq (ly_symbol2scm ("event"), mus->get_property ("types"))
- != SCM_BOOL_F);
- if (!is_event)
- $$ = $1;
- else
- $$ = MAKE_SYNTAX ("event-chord", @$, scm_list_1 ($1));
+ | Music {
+ $$ = $1;
}
| post_event {
$$ = $1;
context_def_spec_body:
/**/ {
$$ = Context_def::make_scm ();
- unsmob_context_def ($$)->origin ()->set_spot (@$);
+ unsmob_context_def ($$)->set_spot (@$);
}
| CONTEXT_DEF_IDENTIFIER {
$$ = $1;
- unsmob_context_def ($$)->origin ()->set_spot (@$);
+ unsmob_context_def ($$)->set_spot (@$);
}
| context_def_spec_body GROBDESCRIPTIONS embedded_scm {
Context_def*td = unsmob_context_def ($$);
book_body:
{
$$ = new Book;
- $$->origin ()->set_spot (@$);
+ $$->set_spot (@$);
$$->paper_ = dynamic_cast<Output_def*> (unsmob_output_def (PARSER->lexer_->lookup_identifier ("$defaultpaper"))->clone ());
$$->paper_->unprotect ();
$$->header_ = PARSER->lexer_->lookup_identifier ("$defaultheader");
}
| BOOK_IDENTIFIER {
$$ = unsmob_book ($1);
- $$->protect ();
- $$->origin ()->set_spot (@$);
+ $$->set_spot (@$);
}
| book_body paper_block {
$$->paper_ = $2;
;
score_body:
- music {
+ Music {
SCM m = $1;
SCM scorify = ly_lily_module_constant ("scorify-music");
SCM score = scm_call_2 (scorify, m, PARSER->self_scm ());
// pass ownernship to C++ again.
$$ = unsmob_score (score);
$$->protect ();
- $$->origin ()->set_spot (@$);
+ $$->set_spot (@$);
}
| SCORE_IDENTIFIER {
$$ = unsmob_score ($1);
- $$->protect ();
- $$->origin ()->set_spot (@$);
+ $$->set_spot (@$);
}
| score_body object_id_setting {
$$->user_key_ = ly_scm2string ($2);
if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T)
{
PARSER->parser_error (@1, _ ("need \\paper for paper block"));
- $1->unprotect ();
$$ = get_paper (PARSER);
}
}
}
| output_def_head_with_mode_switch '{' OUTPUT_DEF_IDENTIFIER {
$1->unprotect ();
-
Output_def *o = unsmob_output_def ($3);
o->input_origin_.set_spot (@$);
$$ = o;
- $$->protect ();
PARSER->lexer_->remove_scope ();
PARSER->lexer_->add_scope (o->scope_);
}
| output_def_body context_def_spec_block {
assign_context_def ($$, $2);
}
+ | output_def_body tempo_event {
+ /*
+ junk this ? there already is tempo stuff in
+ music.
+ */
+ int m = scm_to_int (unsmob_music($2)->get_property ("metronome-count"));
+ Duration *d = unsmob_duration (unsmob_music($2)->get_property ("tempo-unit"));
+ set_tempo ($$, d->get_length (), m);
+ }
| output_def_body error {
}
tempo_event:
TEMPO steno_duration '=' bare_unsigned {
- $$ = MAKE_SYNTAX ("tempo", @$, $2, scm_int2num ($4));
- }
+ Music *m = MY_MAKE_MUSIC ("MetronomeChangeEvent");
+ m->set_property ("tempo-unit", $2);
+ m->set_property ("metronome-count", scm_from_int ( $4));
+ $$ = m->unprotect ();
+ }
;
/*
to have efficient append. */
-music_list:
+Music_list:
/* empty */ {
$$ = scm_cons (SCM_EOL, SCM_EOL);
}
- | music_list music {
+ | Music_list Music {
SCM s = $$;
SCM c = scm_cons ($2, SCM_EOL);
scm_set_car_x (s, c); /* set first cons */
scm_set_cdr_x (s, c); /* remember last cell */
}
- | music_list embedded_scm {
+ | Music_list embedded_scm {
}
- | music_list error {
+ | Music_list error {
Music *m = MY_MAKE_MUSIC("Music");
// ugh. code dup
m->set_property ("error-found", SCM_BOOL_T);
}
;
-music:
- simple_music
- | composite_music
+Music:
+ Simple_music
+ | Composite_music
;
-alternative_music:
+Alternative_music:
/* empty */ {
$$ = SCM_EOL;
}
- | ALTERNATIVE '{' music_list '}' {
+ | ALTERNATIVE '{' Music_list '}' {
$$ = scm_car ($3);
}
;
-repeated_music:
- REPEAT simple_string bare_unsigned music alternative_music
+Repeated_music:
+ REPEAT simple_string bare_unsigned Music Alternative_music
{
$$ = MAKE_SYNTAX ("repeat", @$, $2, scm_int2num ($3), $4, $5);
}
;
-sequential_music:
- SEQUENTIAL '{' music_list '}' {
+Sequential_music:
+ SEQUENTIAL '{' Music_list '}' {
$$ = MAKE_SYNTAX ("sequential-music", @$, scm_car ($3));
}
- | '{' music_list '}' {
+ | '{' Music_list '}' {
$$ = MAKE_SYNTAX ("sequential-music", @$, scm_car ($2));
}
;
-simultaneous_music:
- SIMULTANEOUS '{' music_list '}'{
+Simultaneous_music:
+ SIMULTANEOUS '{' Music_list '}'{
$$ = MAKE_SYNTAX ("simultaneous-music", @$, scm_car ($3));
}
- | DOUBLE_ANGLE_OPEN music_list DOUBLE_ANGLE_CLOSE {
+ | simul_open Music_list simul_close {
$$ = MAKE_SYNTAX ("simultaneous-music", @$, scm_car ($2));
}
;
-simple_music:
+Simple_music:
event_chord
| MUSIC_IDENTIFIER
| music_property_def
}
;
-composite_music:
- prefix_composite_music { $$ = $1; }
- | grouped_music_list { $$ = $1; }
+Composite_music:
+ Prefix_composite_music { $$ = $1; }
+ | Grouped_music_list { $$ = $1; }
;
-grouped_music_list:
- simultaneous_music { $$ = $1; }
- | sequential_music { $$ = $1; }
+Grouped_music_list:
+ Simultaneous_music { $$ = $1; }
+ | Sequential_music { $$ = $1; }
;
function_scm_argument:
| simple_string
;
-/* An argument list. If a function \foo expects scm scm music, then the lexer expands \foo into the token sequence:
- MUSIC_FUNCTION EXPECT_MUSIC EXPECT_SCM EXPECT_SCM
-and this rule returns the reversed list of arguments. */
-
-function_arglist_music_last:
- EXPECT_MUSIC function_arglist music {
- $$ = scm_cons ($3, $2);
+/*
+TODO: use code generation for this
+*/
+Generic_prefix_music_scm:
+ MUSIC_FUNCTION {
+ $$ = scm_list_2 ($1, make_input (@$));
}
- ;
-
-function_arglist_nonmusic_last:
- EXPECT_MARKUP function_arglist full_markup {
- $$ = scm_cons ($3, $2);
+ | MUSIC_FUNCTION_SCM function_scm_argument {
+ $$ = scm_list_3 ($1, make_input (@$), $2);
}
- | EXPECT_SCM function_arglist function_scm_argument {
- $$ = scm_cons ($3, $2);
+ | MUSIC_FUNCTION_MARKUP full_markup {
+ $$ = scm_list_3 ($1, make_input (@$), $2);
}
- ;
-
-function_arglist_nonmusic: EXPECT_NO_MORE_ARGS {
- $$ = SCM_EOL;
+ | music_function_musicless_prefix Music {
+ $$ = ly_append2 ($1, scm_list_1 ($2));
}
- | EXPECT_MARKUP function_arglist_nonmusic full_markup {
- $$ = scm_cons ($3, $2);
+ | MUSIC_FUNCTION_SCM_SCM function_scm_argument function_scm_argument {
+ $$ = scm_list_4 ($1, make_input (@$), $2, $3);
}
- | EXPECT_SCM function_arglist_nonmusic function_scm_argument {
- $$ = scm_cons ($3, $2);
+ | MUSIC_FUNCTION_SCM_SCM_SCM function_scm_argument function_scm_argument function_scm_argument {
+ $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
}
- ;
-
-function_arglist: EXPECT_NO_MORE_ARGS {
- /* This is for 0-ary functions, so they don't need to
- read a lookahead token */
- $$ = SCM_EOL;
+ | MUSIC_FUNCTION_MARKUP_MUSIC full_markup Music {
+ $$ = scm_list_4 ($1, make_input (@$), $2, $3);
}
- | function_arglist_music_last
- | function_arglist_nonmusic_last
- ;
-
-generic_prefix_music_scm:
- MUSIC_FUNCTION function_arglist {
- $$ = ly_append2 (scm_list_2 ($1, make_input (@$)), scm_reverse_x ($2, SCM_EOL));
+ | MUSIC_FUNCTION_MARKUP_MARKUP full_markup full_markup {
+ $$ = scm_list_4 ($1, make_input (@$), $2, $3);
+ }
+ | MUSIC_FUNCTION_MUSIC_MUSIC Music Music {
+ $$ = scm_list_4 ($1, make_input (@$), $2, $3);
+ }
+ | MUSIC_FUNCTION_SCM_MUSIC_MUSIC function_scm_argument Music Music {
+ $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
+ }
+ | MUSIC_FUNCTION_SCM_SCM_MUSIC_MUSIC function_scm_argument function_scm_argument Music Music {
+ $$ = scm_list_n ($1, make_input (@$), $2, $3, $4, $5, SCM_UNDEFINED);
+ }
+ | MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC full_markup Music Music {
+ $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
}
;
-
optional_id:
/**/ { $$ = SCM_EOL; }
| '=' simple_string {
;
-prefix_composite_music:
- generic_prefix_music_scm {
- $$ = run_music_function (PARSER, $1);
+Prefix_composite_music:
+ Generic_prefix_music_scm {
+ $$ = run_music_function (PARSER, $1)->unprotect ();
}
- | CONTEXT simple_string optional_id optional_context_mod music {
- $$ = MAKE_SYNTAX ("context-specification", @$, $2, $3, $5, $4, SCM_BOOL_F);
+ | CONTEXT simple_string optional_id optional_context_mod Music {
+ $$ = context_spec_music ($2, $3, $5, $4, false);
}
- | NEWCONTEXT simple_string optional_id optional_context_mod music {
- $$ = MAKE_SYNTAX ("context-specification", @$, $2, $3, $5, $4, SCM_BOOL_T);
+ | NEWCONTEXT simple_string optional_id optional_context_mod Music {
+ $$ = context_spec_music ($2, $3, $5, $4, true);
}
- | TIMES fraction music {
- $$ = MAKE_SYNTAX ("time-scaled-music", @$, $2, $3);
+ | TIMES fraction Music
+ {
+ int n = scm_to_int (scm_car ($2));
+ int d = scm_to_int (scm_cdr ($2));
+
+ Music *m = MY_MAKE_MUSIC ("TimeScaledMusic");
+ m->set_spot (@$);
+
+ m->set_property ("element", $3);
+ m->set_property ("numerator", scm_from_int (n));
+ m->set_property ("denominator", scm_from_int (d));
+ m->compress (Moment (Rational (n,d)));
+ $$ = m->unprotect ();
}
- | repeated_music { $$ = $1; }
- | TRANSPOSE pitch_also_in_chords pitch_also_in_chords music {
+ | Repeated_music { $$ = $1; }
+ | TRANSPOSE pitch_also_in_chords pitch_also_in_chords Music {
+ Music *m = MY_MAKE_MUSIC ("TransposedMusic");
Pitch from = *unsmob_pitch ($2);
Pitch to = *unsmob_pitch ($3);
- SCM pitch = pitch_interval (from, to).smobbed_copy ();
- $$ = MAKE_SYNTAX ("transpose-music", @$, pitch, $4);
+
+ Music *p = unsmob_music ($4);
+ p->transpose (pitch_interval (from, to));
+ m->set_property ("element", $4);
+ $$ = m->unprotect ();
}
- | mode_changing_head grouped_music_list {
+ | mode_changing_head Grouped_music_list {
if ($1 == ly_symbol2scm ("chords"))
{
- $$ = MAKE_SYNTAX ("unrelativable-music", @$, $2);
+ Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
+ chm->set_property ("element", $2);
+ $$ = chm->unprotect ();
}
else
{
}
PARSER->lexer_->pop_state ();
}
- | mode_changing_head_with_context optional_context_mod grouped_music_list {
- $$ = MAKE_SYNTAX ("context-specification", @$, $1, SCM_EOL, $3, $2, SCM_BOOL_T);
+ | mode_changing_head_with_context optional_context_mod Grouped_music_list {
+ $$ = context_spec_music ($1, SCM_UNDEFINED, $3, $2, true);
if ($1 == ly_symbol2scm ("ChordNames"))
{
- $$ = MAKE_SYNTAX ("unrelativable-music", @$, $$);
+ Music *chm = MY_MAKE_MUSIC ("UnrelativableMusic");
+ chm->set_property ("element", $$);
+ $$ = chm->unprotect ();
}
PARSER->lexer_->pop_state ();
}
relative_music:
- RELATIVE absolute_pitch music {
+ RELATIVE absolute_pitch Music {
Pitch start = *unsmob_pitch ($2);
$$ = make_music_relative (start, $3);
}
- | RELATIVE composite_music {
+ | RELATIVE Composite_music {
Pitch middle_c (0, 0, 0);
$$ = make_music_relative (middle_c, $2);
}
new_lyrics:
ADDLYRICS { PARSER->lexer_->push_lyric_state (); }
/*cont */
- grouped_music_list {
- /* Can also use music at the expensive of two S/Rs similar to
+ Grouped_music_list {
+ /* Can also use Music at the expensive of two S/Rs similar to
\repeat \alternative */
PARSER->lexer_->pop_state ();
}
| new_lyrics ADDLYRICS {
PARSER->lexer_->push_lyric_state ();
- } grouped_music_list {
+ } Grouped_music_list {
PARSER->lexer_->pop_state ();
$$ = scm_cons ($4, $1);
}
;
re_rhythmed_music:
- grouped_music_list new_lyrics {
- $$ = MAKE_SYNTAX ("add-lyrics", @$, $1, scm_reverse_x ($2, SCM_EOL));
+ Grouped_music_list new_lyrics {
+ SCM voice = $1;
+ SCM name = get_first_context_id (scm_makfrom0str ("Voice"), unsmob_music (voice));
+ if (!scm_is_string (name))
+ {
+ name = get_next_unique_lyrics_context_id ();
+ voice = context_spec_music (scm_makfrom0str ("Voice"),
+ name,
+ voice, SCM_EOL, false);
+ }
+
+ SCM context = scm_makfrom0str ("Lyrics");
+ Music *all = MY_MAKE_MUSIC ("SimultaneousMusic");
+
+ SCM lst = SCM_EOL;
+ for (SCM s = $2; scm_is_pair (s); s = scm_cdr (s))
+ {
+ SCM com = make_lyric_combine_music (name, scm_car (s));
+ SCM csm = context_spec_music (context,
+ SCM_UNDEFINED, com, SCM_EOL, true);
+ lst = scm_cons (csm, lst);
+ }
+ all->set_property ("elements", scm_cons (voice,
+ lst));
+ $$ = all->unprotect ();
}
| LYRICSTO simple_string {
PARSER->lexer_->push_lyric_state ();
- } music {
+ } Music {
PARSER->lexer_->pop_state ();
- $$ = MAKE_SYNTAX ("lyric-combine", @$, $2, $4);
+ SCM name = $2;
+ $$ = make_lyric_combine_music (name, $4);
}
;
context_change:
CHANGE STRING '=' STRING {
- $$ = MAKE_SYNTAX ("context-change", @$, scm_string_to_symbol ($2), $4);
+ Music *t = MY_MAKE_MUSIC ("ContextChange");
+ t-> set_property ("change-to-type", scm_string_to_symbol ($2));
+ t-> set_property ("change-to-id", $4);
+ t->set_spot (@$);
+
+ $$ = t->unprotect ();
}
;
}
;
-simple_music_property_def:
+music_property_def:
OVERRIDE context_prop_spec embedded_scm '=' scalar {
- $$ = scm_list_5 (scm_car ($2),
- ly_symbol2scm ("OverrideProperty"),
+ Music *m = property_op_to_music (scm_list_4 (
+ ly_symbol2scm ("push"),
scm_cadr ($2),
- $5, $3);
+ $5, $3));
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, m->unprotect (), SCM_EOL, false);
}
| OVERRIDE context_prop_spec embedded_scm embedded_scm '=' scalar {
- $$ = scm_list_n (scm_car ($2),
- ly_symbol2scm ("OverrideProperty"),
+ Music *m = property_op_to_music (scm_list_5 (
+ ly_symbol2scm ("push"),
scm_cadr ($2),
- $6, $4, $3, SCM_UNDEFINED);
+ $6, $4, $3));
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, m->unprotect (), SCM_EOL, false);
}
| REVERT context_prop_spec embedded_scm {
- $$ = scm_list_4 (scm_car ($2),
- ly_symbol2scm ("RevertProperty"),
+ Music *m = property_op_to_music (scm_list_3 (
+ ly_symbol2scm ("pop"),
scm_cadr ($2),
- $3);
+ $3));
+
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, m->unprotect (), SCM_EOL, false);
}
| SET context_prop_spec '=' scalar {
- $$ = scm_list_4 (scm_car ($2),
- ly_symbol2scm ("PropertySet"),
+ Music *m = property_op_to_music (scm_list_3 (
+ ly_symbol2scm ("assign"),
scm_cadr ($2),
- $4);
+ $4));
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, m->unprotect (), SCM_EOL, false);
}
| UNSET context_prop_spec {
- $$ = scm_list_3 (scm_car ($2),
- ly_symbol2scm ("PropertyUnset"),
- scm_cadr ($2));
+ Music *m = property_op_to_music (scm_list_2 (
+ ly_symbol2scm ("unset"),
+ scm_cadr ($2)));
+ $$ = context_spec_music (scm_car ($2), SCM_UNDEFINED, m->unprotect (), SCM_EOL, false);
+ }
+ | ONCE music_property_def {
+ Music *m = unsmob_music ($2);
+ SCM e = m->get_property ("element");
+ unsmob_music (e)->set_property ("once", SCM_BOOL_T);
+ $$ = $2;
}
;
-music_property_def:
- simple_music_property_def {
- $$ = LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("property-operation"), scm_cons (PARSER->self_scm (), scm_cons2 (make_input (@$), SCM_BOOL_F, $1)));
- }
- | ONCE simple_music_property_def {
- $$ = LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("property-operation"), scm_cons (PARSER->self_scm (), scm_cons2 (make_input (@$), SCM_BOOL_T, $2)));
- }
- ;
string:
STRING {
}
;
+/*
+
+pre_events doesn't contain anything. It is a trick:
+
+Adding pre_events to the simple_element
+makes the choice between
+
+ string: STRING
+
+and
+
+ simple_element: STRING
+
+a single shift/reduction conflict.
+
+nevertheless, this is not very clean, and we should find a different
+solution.
+
+*/
+pre_events: /* empty */
+ ;
+
event_chord:
- /* TODO: Create a special case that avoids the creation of
- EventChords around simple_elements that have no post_events?
- */
- simple_chord_elements post_events {
- SCM elts = ly_append2 ($1, scm_reverse_x ($2, SCM_EOL));
+ pre_events simple_element post_events {
+ Music *m = unsmob_music ($2);
+ m->protect ();
+ SCM elts = m->get_property ("elements");
- Input i;
+ elts = ly_append2 (elts, scm_reverse_x ($3, SCM_EOL));
+
+ m->set_property ("elements", elts);
/* why is this giving wrong start location? -ns
- * i = @$; */
- i.set_location (@1, @2);
- $$ = MAKE_SYNTAX ("event-chord", i, elts);
- }
- | MULTI_MEASURE_REST optional_notemode_duration post_events {
+ * $2->set_spot (@$); */
Input i;
- i.set_location (@1, @3);
- $$ = MAKE_SYNTAX ("multi-measure-rest", i, $2, $3);
+ i.set_location (@2, @3);
+ m->set_spot (i);
+ $$ = m->unprotect ();
}
- | command_element
+ | command_element { $$ = $1; }
| note_chord_element
;
}
;
+chord_open: '<'
+ ;
+
+chord_close: '>'
+ ;
+
+simul_open: DOUBLE_ANGLE_OPEN
+ ;
+
+simul_close: DOUBLE_ANGLE_CLOSE
+ ;
+
chord_body:
- ANGLE_OPEN chord_body_elements ANGLE_CLOSE
+ chord_open chord_body_elements chord_close
{
- $$ = MAKE_SYNTAX ("event-chord", @$, scm_reverse_x ($2, SCM_EOL));
+ Music *m = MY_MAKE_MUSIC ("EventChord");
+ m->set_spot (@$);
+ m->set_property ("elements",
+ scm_reverse_x ($2, SCM_EOL));
+ $$ = m->unprotect ();
}
;
$$ = n->unprotect ();
}
| music_function_chord_body {
- $$ = run_music_function (PARSER, $1);
- }
- ;
-
-music_function_identifier_musicless_prefix: MUSIC_FUNCTION {
- SCM sig = scm_object_property (yylval.scm, ly_symbol2scm ("music-function-signature"));
- if (scm_is_pair (sig) && to_boolean (scm_memq (ly_music_p_proc, scm_cdr (scm_reverse (sig)))))
- {
- PARSER->parser_error (@$, "Music function applied to event may not have a Music argument, except as the last argument.");
- }
+ Music *m = run_music_function (PARSER, $1);
+ m->set_spot (@$);
+ $$ = m->unprotect ();
}
;
music_function_chord_body:
- /* We could allow chord functions to have multiple music arguments,
- but it's more consistent with music_function_event if we
- prohibit it here too */
- music_function_identifier_musicless_prefix EXPECT_MUSIC function_arglist_nonmusic chord_body_element {
- $$ = ly_append2 (scm_list_2 ($1, make_input (@$)), scm_reverse_x ($3, scm_list_1 ($4)));
+ MUSIC_FUNCTION {
+ $$ = scm_list_2 ($1, make_input (@$));
}
- | music_function_identifier_musicless_prefix function_arglist_nonmusic {
- $$ = ly_append2 (scm_list_2 ($1, make_input (@$)), scm_reverse_x ($2, SCM_EOL));
+ | music_function_musicless_prefix chord_body_element {
+ $$ = ly_append2 ($1, scm_list_1 ($2));
}
;
music_function_event:
- /* Post-events can only have the last argument as music, without this
- restriction we get a shift/reduce conflict from e.g.
- c8-\partcombine c8 -. */
- music_function_identifier_musicless_prefix EXPECT_MUSIC function_arglist_nonmusic post_event {
- $$ = ly_append2 (scm_list_2 ($1, make_input (@$)), scm_reverse_x ($3, scm_list_1 ($4)));
+ music_function_musicless_prefix post_event {
+ $$ = ly_append2 ($1, scm_list_1 ($2));
+ }
+ ;
+
+/*
+TODO: use code generation for this
+*/
+music_function_musicless_prefix:
+ MUSIC_FUNCTION_MUSIC {
+ $$ = scm_list_2 ($1, make_input (@$));
}
- | music_function_identifier_musicless_prefix function_arglist_nonmusic {
- $$ = ly_append2 (scm_list_2 ($1, make_input (@$)), scm_reverse_x ($2, SCM_EOL));
+ | MUSIC_FUNCTION_SCM_MUSIC function_scm_argument {
+ $$ = scm_list_3 ($1, make_input (@$), $2);
+ }
+ | MUSIC_FUNCTION_SCM_SCM_MUSIC function_scm_argument function_scm_argument {
+ $$ = scm_list_4 ($1, make_input (@$), $2, $3);
+ }
+ | MUSIC_FUNCTION_SCM_SCM_SCM_MUSIC function_scm_argument function_scm_argument function_scm_argument {
+ $$ = scm_list_5 ($1, make_input (@$), $2, $3, $4);
+ }
+ | MUSIC_FUNCTION_SCM_SCM_SCM_SCM_MUSIC function_scm_argument function_scm_argument function_scm_argument function_scm_argument {
+ $$ = scm_list_n ($1, make_input (@$), $2, $3, $4, $5, SCM_UNDEFINED);
}
;
+
command_element:
command_event {
- $$ = $1;
+ Music *m = MY_MAKE_MUSIC ("EventChord");
+ m->set_property ("elements", scm_cons ($1, SCM_EOL));
+ Music *e = unsmob_music ($1);
+ e-> set_spot (@$);
+ m-> set_spot (@$);
+ $$ = m->unprotect ();
}
| SKIP duration_length {
- $$ = MAKE_SYNTAX ("skip-music", @$, $2);
+ Music *skip = MY_MAKE_MUSIC ("SkipMusic");
+ skip->set_property ("duration", $2);
+ skip->set_spot (@$);
+ $$ = skip->unprotect ();
}
| E_BRACKET_OPEN {
Music *m = MY_MAKE_MUSIC ("LigatureEvent");
m->set_property ("span-direction", scm_from_int (START));
m->set_spot (@$);
- $$ = m->unprotect();
+
+ Music *chord = MY_MAKE_MUSIC ("EventChord");
+ chord->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
+ m->unprotect();
+ chord->set_spot (@$);
+ $$ = chord->unprotect ();
}
| E_BRACKET_CLOSE {
Music *m = MY_MAKE_MUSIC ("LigatureEvent");
m->set_property ("span-direction", scm_from_int (STOP));
m->set_spot (@$);
- $$ = m->unprotect ();
+
+ Music *chord = MY_MAKE_MUSIC ("EventChord");
+ chord->set_property ("elements", scm_cons (m->self_scm (), SCM_EOL));
+ chord->set_spot (@$);
+ m->unprotect ();
+ $$ = chord->unprotect ();
}
| E_BACKSLASH {
- $$ = MAKE_SYNTAX ("voice-separator", @$, SCM_UNDEFINED);
+ Music *m = MY_MAKE_MUSIC ("VoiceSeparator");
+ m->set_spot (@$);
+ $$ = m->unprotect ();
}
| '|' {
SCM pipe = PARSER->lexer_->lookup_identifier ("pipeSymbol");
Music *m = unsmob_music (pipe);
if (m)
- {
m = m->clone ();
- m->set_spot (@$);
- $$ = m->unprotect ();
- }
else
- $$ = MAKE_SYNTAX ("bar-check", @$, SCM_UNDEFINED);
+ m = MY_MAKE_MUSIC ("BarCheck");
+ m->set_spot (@$);
+ $$ = m->unprotect ();
}
- | PARTIAL duration_length {
+ | TRANSPOSITION pitch {
+ Pitch middle_c;
+ Pitch sounds_as_c = pitch_interval (*unsmob_pitch ($2), middle_c);
+ Music *m = set_property_music (ly_symbol2scm ("instrumentTransposition"),
+ sounds_as_c.smobbed_copy());
+ m->set_spot (@$);
+ $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
+ m->unprotect (), SCM_EOL, false);
+ }
+ | PARTIAL duration_length {
Moment m = - unsmob_duration ($2)->get_length ();
- $$ = MAKE_SYNTAX ("property-operation", @$, SCM_BOOL_F, ly_symbol2scm ("Timing"), ly_symbol2scm ("PropertySet"), ly_symbol2scm ("measurePosition"), m.smobbed_copy ());
- $$ = MAKE_SYNTAX ("context-specification", @$, ly_symbol2scm ("Score"), SCM_BOOL_F, $$, SCM_EOL, SCM_BOOL_F);
+ Music *p = set_property_music (ly_symbol2scm ( "measurePosition"),m.smobbed_copy ());
+ p->set_spot (@$);
+ SCM ps = p->unprotect ();
+ ps = context_spec_music (ly_symbol2scm ("Timing"), SCM_UNDEFINED,
+ ps, SCM_EOL, false);
+ $$ = context_spec_music (ly_symbol2scm ("Score"), SCM_UNDEFINED,
+ ps, SCM_EOL, false);
}
| TIME_T fraction {
$$ = $1;
}
| '-' music_function_event {
- $$ = run_music_function (PARSER, $2);
+ Music *mus = run_music_function (PARSER, $2);
+ mus->set_spot (@1);
+ $$ = mus->unprotect ();
}
| HYPHEN {
if (!PARSER->lexer_->is_lyric_state ())
$$ = t->unprotect ();
}
| DIGIT {
- Music *t = MY_MAKE_MUSIC ("FingeringEvent");
+ Music *t = MY_MAKE_MUSIC ("FingerEvent");
t->set_property ("digit", scm_from_int ($1));
t->set_spot (@$);
$$ = t->unprotect ();
| '|' {
$$ = scm_makfrom0str ("Bar");
}
- | ANGLE_CLOSE {
+ | '>' {
$$ = scm_makfrom0str ("Larger");
}
| '.' {
figure_spec:
FIGURE_OPEN figure_list FIGURE_CLOSE {
- $$ = scm_reverse_x ($2, SCM_EOL);
+ Music *m = MY_MAKE_MUSIC ("EventChord");
+ $2 = scm_reverse_x ($2, SCM_EOL);
+ m->set_property ("elements", $2);
+ $$ = m->self_scm ();
}
;
if ($2 % 2 || $3 % 2)
n->set_property ("force-accidental", SCM_BOOL_T);
+ Music *v = MY_MAKE_MUSIC ("EventChord");
+ v->set_property ("elements", scm_list_1 (n->self_scm ()));
+ n->unprotect ();
+
+ v->set_spot (@$);
n->set_spot (@$);
- $$ = n->unprotect ();
+ $$ = v->unprotect ();
}
| DRUM_PITCH optional_notemode_duration {
Music *n = MY_MAKE_MUSIC ("NoteEvent");
n->set_property ("duration", $2);
n->set_property ("drum-type", $1);
- $$ = n->unprotect ();
+ Music *v = MY_MAKE_MUSIC ("EventChord");
+ v->set_property ("elements", scm_list_1 (n->self_scm ()));
+ n->unprotect ();
+ v->set_spot (@$);
+ n->set_spot (@$);
+ $$ = v->unprotect ();
+
}
+ | figure_spec optional_notemode_duration {
+ Music *m = unsmob_music ($1);
+ m->set_spot (@$);
+ for (SCM s = m->get_property ("elements"); scm_is_pair (s); s = scm_cdr (s))
+ {
+ unsmob_music (scm_car (s))->set_property ("duration", $2);
+ }
+ $$ = m->unprotect ();
+ }
| RESTNAME optional_notemode_duration {
Music *ev = 0;
if (ly_scm2string ($1) == "s") {
}
ev->set_property ("duration", $2);
ev->set_spot (@$);
- $$ = ev->unprotect ();
+ Music *velt = MY_MAKE_MUSIC ("EventChord");
+ velt->set_property ("elements", scm_list_1 (ev->self_scm ()));
+ velt->set_spot (@$);
+
+ ev->unprotect();
+
+ $$ = velt->unprotect ();
+ }
+ | MULTI_MEASURE_REST optional_notemode_duration {
+ SCM proc = ly_lily_module_constant ("make-multi-measure-rest");
+ $$ = scm_call_2 (proc, $2, make_input (@$));
}
| lyric_element optional_notemode_duration {
if (!PARSER->lexer_->is_lyric_state ())
levent->set_property ("text", $1);
levent->set_property ("duration",$2);
levent->set_spot (@$);
- $$= levent->unprotect ();
- }
- ;
+ Music *velt = MY_MAKE_MUSIC ("EventChord");
+ velt->set_property ("elements", scm_list_1 (levent->self_scm ()));
-simple_chord_elements:
- simple_element {
- $$ = scm_list_1 ($1);
- }
+ $$= velt->unprotect ();
+ }
| new_chord {
if (!PARSER->lexer_->is_chord_state ())
PARSER->parser_error (@1, _ ("have to be in Chord mode for chords"));
$$ = $1;
}
- | figure_spec optional_notemode_duration {
- for (SCM s = $1; scm_is_pair (s); s = scm_cdr (s))
- {
- unsmob_music (scm_car (s))->set_property ("duration", $2);
- }
- $$ = $1;
- }
;
lyric_element:
new_chord:
steno_tonic_pitch optional_notemode_duration {
- $$ = make_chord_elements ($1, $2, SCM_EOL);
+ $$ = make_chord ($1, $2, SCM_EOL);
}
| steno_tonic_pitch optional_notemode_duration chord_separator chord_items {
SCM its = scm_reverse_x ($4, SCM_EOL);
- $$ = make_chord_elements ($1, $2, scm_cons ($3, its));
+ $$ = make_chord ($1, $2, scm_cons ($3, its));
}
;
%%
void
-Lily_parser::set_yydebug (bool x)
+Lily_parser::set_yydebug (bool )
{
- yydebug = x;
+#if 0
+ yydebug = 1;
+#endif
}
void
*destination = sid;
return STRING_IDENTIFIER;
} else if (unsmob_book (sid)) {
- Book *book = unsmob_book (sid)->clone ();
- *destination = book->self_scm ();
- book->unprotect ();
-
+ *destination = unsmob_book (sid)->clone ()->self_scm ();
return BOOK_IDENTIFIER;
} else if (scm_is_number (sid)) {
*destination = sid;
return NUMBER_IDENTIFIER;
} else if (unsmob_context_def (sid)) {
- Context_def *def= unsmob_context_def (sid)->clone ();
-
- *destination = def->self_scm ();
- def->unprotect ();
-
+ *destination = unsmob_context_def (sid)->clone_scm ();
return CONTEXT_DEF_IDENTIFIER;
} else if (unsmob_score (sid)) {
Score *score = new Score (*unsmob_score (sid));
*destination = score->self_scm ();
-
- score->unprotect ();
return SCORE_IDENTIFIER;
} else if (Music *mus = unsmob_music (sid)) {
mus = mus->clone ();
bool is_event = scm_memq (ly_symbol2scm ("event"), mus->get_property ("types"))
!= SCM_BOOL_F;
- mus->unprotect ();
return is_event ? EVENT_IDENTIFIER : MUSIC_IDENTIFIER;
} else if (unsmob_duration (sid)) {
*destination = unsmob_duration (sid)->smobbed_copy ();
} else if (unsmob_output_def (sid)) {
Output_def *p = unsmob_output_def (sid);
p = p->clone ();
-
+
*destination = p->self_scm ();
- p->unprotect ();
return OUTPUT_DEF_IDENTIFIER;
} else if (Text_interface::is_markup (sid)) {
*destination = sid;
return -1;
}
+Music *
+property_op_to_music (SCM op)
+{
+ Music *m = 0;
+ SCM tag = scm_car (op);
+ SCM symbol = scm_cadr (op);
+ SCM args = scm_cddr (op);
+ SCM grob_val = SCM_UNDEFINED;
+ SCM grob_path = SCM_UNDEFINED;
+ SCM val = SCM_UNDEFINED;
+
+ if (tag == ly_symbol2scm ("assign"))
+ {
+ m = MY_MAKE_MUSIC ("PropertySet");
+ val = scm_car (args);
+ }
+ else if (tag == ly_symbol2scm ("unset"))
+ m = MY_MAKE_MUSIC ("PropertyUnset");
+ else if (tag == ly_symbol2scm ("push"))
+ {
+ m = MY_MAKE_MUSIC ("OverrideProperty");
+ grob_val = scm_car (args);
+ grob_path = scm_cdr (args);
+ m->set_property ("pop-first", SCM_BOOL_T);
+ }
+ else if (tag == ly_symbol2scm ("pop")) {
+ m = MY_MAKE_MUSIC ("RevertProperty");
+ grob_path = args;
+ }
+
+ m->set_property ("symbol", symbol);
+
+ if (val != SCM_UNDEFINED)
+ m->set_property ("value", val);
+ if (grob_val != SCM_UNDEFINED)
+ m->set_property ("grob-value", grob_val);
+ if (grob_path != SCM_UNDEFINED)
+ m->set_property ("grob-property-path", grob_path);
+
+ return m;
+}
+
+SCM
+context_spec_music (SCM type, SCM id, SCM m, SCM ops, bool create_new)
+{
+ Music *csm = MY_MAKE_MUSIC ("ContextSpeccedMusic");
+
+ csm->set_property ("element", m);
+
+ csm->set_property ("context-type",
+ scm_is_symbol (type) ? type : scm_string_to_symbol (type));
+ csm->set_property ("property-operations", ops);
+ if (create_new)
+ csm->set_property ("create-new", SCM_BOOL_T);
+
+ if (scm_is_string (id))
+ csm->set_property ("context-id", id);
+ return csm->unprotect ();
+}
+
SCM
get_next_unique_context_id ()
{
}
-SCM
+Music *
run_music_function (Lily_parser *parser, SCM expr)
{
SCM func = scm_car (expr);
SCM sig = scm_object_property (func, ly_symbol2scm ("music-function-signature"));
SCM type_check_proc = ly_lily_module_constant ("type-check-list");
+ bool ok = true;
if (!to_boolean (scm_call_3 (type_check_proc, scm_cadr (expr), sig, args)))
{
parser->error_level_ = 1;
- return LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("void-music"), scm_list_2 (parser->self_scm (), make_input (*loc)));
+ ok = false;
}
- SCM syntax_args = scm_list_4 (parser->self_scm (), make_input (*loc), func, args);
- return LOWLEVEL_MAKE_SYNTAX (ly_lily_module_constant ("music-function"), syntax_args);
+ SCM m = SCM_EOL;
+ if (ok)
+ m = scm_apply_0 (func, scm_cons (parser->self_scm(),
+ scm_cdr (expr)));
+
+
+ Music* retval = 0;
+ if (unsmob_music (m))
+ {
+ retval = unsmob_music (m);
+ retval->protect ();
+ }
+ else
+ {
+ if (ok)
+ loc->error (_ ("music head function must return Music object"));
+ retval = MY_MAKE_MUSIC ("Music");
+ }
+ retval->set_spot (*loc);
+ return retval;
}
bool
set_music_properties (Music *p, SCM a)
{
for (SCM k = a; scm_is_pair (k); k = scm_cdr (k))
- p->set_property (scm_caar (k), scm_cdar (k));
+ p->internal_set_property (scm_caar (k), scm_cdar (k));
}
SCM
-make_chord_elements (SCM pitch, SCM dur, SCM modification_list)
+make_chord (SCM pitch, SCM dur, SCM modification_list)
{
- SCM chord_ctor = ly_lily_module_constant ("construct-chord-elements");
- return scm_call_3 (chord_ctor, pitch, dur, modification_list);
+ SCM chord_ctor = ly_lily_module_constant ("construct-chord");
+ SCM ch = scm_call_3 (chord_ctor, pitch, dur, modification_list);
+
+ unsmob_music (ch)->protect();
+ return ch;
}
|| (scm_is_pair (x) && ly_is_procedure (scm_car (x)));
}
+Music*
+set_property_music (SCM sym, SCM value)
+{
+ Music *p = MY_MAKE_MUSIC ("PropertySet");
+ p->set_property ("symbol", sym);
+ p->set_property ("value", value);
+ return p;
+}
+
SCM
make_music_relative (Pitch start, SCM music)
{
return relative->unprotect ();
}
+SCM
+make_lyric_combine_music (SCM name, SCM music)
+{
+ Music *combine = MY_MAKE_MUSIC ("LyricCombineMusic");
+ combine->set_property ("element", music);
+ combine->set_property ("associated-context", name);
+ return combine->unprotect ();
+}
+
+
int
yylex (YYSTYPE *s, YYLTYPE *loc, void *v)
{
*/
#include "engraver.hh"
-#include "multi-measure-rest.hh"
+#include "text-interface.hh"
#include "note-head.hh"
-#include "side-position-interface.hh"
#include "stem.hh"
-#include "stream-event.hh"
-#include "text-interface.hh"
-
-#include "translator.icc"
+#include "side-position-interface.hh"
+#include "multi-measure-rest.hh"
class Part_combine_engraver : public Engraver
{
DECLARE_ACKNOWLEDGER (note_head);
DECLARE_ACKNOWLEDGER (stem);
- DECLARE_TRANSLATOR_LISTENER (part_combine);
void process_music ();
void stop_translation_timestep ();
+ virtual bool try_music (Music *);
private:
Item *text_;
- Stream_event *event_;
+ Music *event_;
};
-IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, part_combine);
-void
-Part_combine_engraver::listen_part_combine (Stream_event *ev)
+bool
+Part_combine_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ event_ = m;
+ return true;
}
Part_combine_engraver::Part_combine_engraver ()
if (event_
&& to_boolean (get_property ("printPartCombineTexts")))
{
- SCM what = event_->get_property ("class");
+ SCM what = event_->get_property ("part-combine-status");
SCM text = SCM_EOL;
- if (what == ly_symbol2scm ("solo-one-event"))
+ if (what == ly_symbol2scm ("solo1"))
text = get_property ("soloText");
- else if (what == ly_symbol2scm ("solo-two-event"))
+ else if (what == ly_symbol2scm ("solo2"))
text = get_property ("soloIIText");
- else if (what == ly_symbol2scm ("unisono-event"))
+ else if (what == ly_symbol2scm ("unisono"))
text = get_property ("aDueText");
if (Text_interface::is_markup (text))
event_ = 0;
}
+#include "translator.icc"
ADD_ACKNOWLEDGER (Part_combine_engraver, note_head);
ADD_ACKNOWLEDGER (Part_combine_engraver, stem);
ADD_TRANSLATOR (Part_combine_engraver,
#include "music-sequence.hh"
#include "warn.hh"
-typedef enum Outlet_type
- {
- CONTEXT_ONE, CONTEXT_TWO,
- CONTEXT_SHARED, CONTEXT_SOLO,
- CONTEXT_NULL, NUM_OUTLETS
- };
-
-static const char *outlet_names_[NUM_OUTLETS] =
- {"one", "two", "shared", "solo", "null"};
-
class Part_combine_iterator : public Music_iterator
{
public:
/*
TODO: this is getting of hand...
*/
- Context_handle handles_[NUM_OUTLETS];
+ Context_handle one_;
+ Context_handle two_;
+ Context_handle null_;
+ Context_handle shared_;
+ Context_handle solo_;
- void substitute_both (Outlet_type to1,
- Outlet_type to2);
+ void substitute_both (Context *to1,
+ Context *to2);
- /* parameter is really Outlet_type */
- void kill_mmrest (int in);
+ void kill_mmrest (Context *);
void chords_together ();
void solo1 ();
void solo2 ();
if (second_iter_)
second_iter_->quit ();
- // Add listeners to all contexts except Devnull.
- for (int i = 0; i < NUM_OUTLETS; i++)
- {
- Context *c = handles_[i].get_outlet ();
- if (c->is_alias (ly_symbol2scm ("Voice")))
- c->event_source ()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event"));
- handles_[i].set_context (0);
- }
+ null_.set_context (0);
+ one_.set_context (0);
+ two_.set_context (0);
+ shared_.set_context (0);
+ solo_.set_context (0);
}
Part_combine_iterator::Part_combine_iterator ()
playing_state_ = TOGETHER;
state_ = TOGETHER;
- substitute_both (CONTEXT_SHARED, CONTEXT_SHARED);
+ substitute_both (shared_.get_outlet (), shared_.get_outlet ());
}
}
void
-Part_combine_iterator::kill_mmrest (int in)
+Part_combine_iterator::kill_mmrest (Context *tg)
{
- static Stream_event *mmrest;
+ static Music *mmrest;
if (!mmrest)
{
- mmrest = new Stream_event (ly_symbol2scm ("multi-measure-rest-event"));
+ mmrest = make_music_by_name (ly_symbol2scm ("MultiMeasureRestEvent"));
mmrest->set_property ("duration", SCM_EOL);
}
- handles_[in].get_outlet ()->event_source ()->broadcast (mmrest);
+ mmrest->send_to_context (tg);
}
void
else
{
state_ = SOLO1;
- substitute_both (CONTEXT_SOLO, CONTEXT_NULL);
+ substitute_both (solo_.get_outlet (),
+ null_.get_outlet ());
- kill_mmrest (CONTEXT_TWO);
- kill_mmrest (CONTEXT_SHARED);
+ kill_mmrest (two_.get_outlet ());
+ kill_mmrest (shared_.get_outlet ());
if (playing_state_ != SOLO1)
{
- static Stream_event *event;
+ static Music *event;
if (!event)
- event = new Stream_event (ly_symbol2scm ("solo-one-event"));
+ event = make_music_by_name (ly_symbol2scm ("SoloOneEvent"));
- first_iter_->get_outlet ()->event_source ()->broadcast (event);
+ event->send_to_context (first_iter_->get_outlet ());
}
playing_state_ = SOLO1;
}
}
void
-Part_combine_iterator::substitute_both (Outlet_type to1,
- Outlet_type to2)
+Part_combine_iterator::substitute_both (Context *to1,
+ Context *to2)
{
- Outlet_type tos[] = {to1, to2};
-
+ Context *tos[] = {to1, to2};
Music_iterator *mis[] = {first_iter_, second_iter_};
+ Context_handle *hs[]
+ = {
+ &null_,
+ &one_, &two_,
+ &shared_, &solo_,
+ 0
+ };
for (int i = 0; i < 2; i++)
{
- for (int j = 0; j < NUM_OUTLETS; j++)
- if (j != tos[i])
- mis[i]->substitute_outlet (handles_[j].get_outlet (), handles_[tos[i]].get_outlet ());
+ for (int j = 0; hs[j]; j++)
+ if (hs[j]->get_outlet () != tos[i])
+ mis[i]->substitute_outlet (hs[j]->get_outlet (), tos[i]);
}
- for (int j = 0; j < NUM_OUTLETS; j++)
+ for (int j = 0; hs[j]; j++)
{
- if (j != to1 && j != to2)
- kill_mmrest (j);
+ Context *t = hs[j]->get_outlet ();
+ if (t != to1 && t != to2)
+ kill_mmrest (t);
}
}
in the 1st voice, so in that case, we use the second voice
as a basis for events.
*/
- Outlet_type c1 = (last_playing_ == SOLO2) ? CONTEXT_NULL : CONTEXT_SHARED;
- Outlet_type c2 = (last_playing_ == SOLO2) ? CONTEXT_SHARED : CONTEXT_NULL;
+ Context *c1 = (last_playing_ == SOLO2) ? null_.get_outlet () : shared_.get_outlet ();
+ Context *c2 = (last_playing_ == SOLO2) ? shared_.get_outlet () : null_.get_outlet ();
substitute_both (c1, c2);
kill_mmrest ((last_playing_ == SOLO2)
- ? CONTEXT_ONE : CONTEXT_TWO);
- kill_mmrest (CONTEXT_SHARED);
+ ? one_.get_outlet () : two_.get_outlet ());
+ kill_mmrest (shared_.get_outlet ());
if (playing_state_ != UNISONO
&& newstate == UNISONO)
{
- static Stream_event *event;
+ static Music *event;
if (!event)
- event = new Stream_event (ly_symbol2scm ("unisono-event"));
-
+ event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
->get_outlet ();
- out->event_source ()->broadcast (event);
+ event->send_to_context (out);
playing_state_ = UNISONO;
}
state_ = newstate;
{
state_ = SOLO2;
- substitute_both (CONTEXT_NULL, CONTEXT_SOLO);
+ substitute_both (null_.get_outlet (), solo_.get_outlet ());
if (playing_state_ != SOLO2)
{
- static Stream_event *event;
+ static Music *event;
if (!event)
- event = new Stream_event (ly_symbol2scm ("solo-two-event"));
+ event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent"));
- second_iter_->get_outlet ()->event_source ()->broadcast (event);
+ event->send_to_context (second_iter_->get_outlet ());
playing_state_ = SOLO2;
}
}
else
{
state_ = APART;
- substitute_both (CONTEXT_ONE, CONTEXT_TWO);
+ substitute_both (one_.get_outlet (), two_.get_outlet ());
}
}
{
start_moment_ = get_outlet ()->now_mom ();
split_list_ = get_music ()->get_property ("split-list");
+ SCM lst = get_music ()->get_property ("elements");
- Context *c = get_outlet ();
+ SCM props = scm_list_n (/*
+ used to have tweaks here.
+ */
- for (int i = 0; i < NUM_OUTLETS; i++)
- {
- SCM type = (i == CONTEXT_NULL) ? ly_symbol2scm ("Devnull") : ly_symbol2scm ("Voice");
- /* find context below c: otherwise we may create new staff for each voice */
- c = c->find_create_context (type, outlet_names_[i], SCM_EOL);
- handles_[i].set_context (c);
- if (c->is_alias (ly_symbol2scm ("Voice")))
- c->event_source ()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("music-event"));
- }
+ SCM_UNDEFINED);
+
+ Context *tr
+ = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"),
+ "shared", props);
+
+ shared_.set_context (tr);
+
+ /*
+ If we don't, we get a new staff for every Voice.
+ */
+ set_context (tr);
+
+ Context *solo_tr
+ = get_outlet ()->find_create_context (ly_symbol2scm ("Voice"),
+ "solo", props);
+
+ solo_.set_context (solo_tr);
+
+ Context *null
+ = get_outlet ()->find_create_context (ly_symbol2scm ("Devnull"),
+ "", SCM_EOL);
+
+ if (!null)
+ programming_error ("no Devnull found");
+
+ null_.set_context (null);
+
+ Context *one = tr->find_create_context (ly_symbol2scm ("Voice"),
+ "one", props);
+
+ one_.set_context (one);
- SCM lst = get_music ()->get_property ("elements");
- Context *one = handles_[CONTEXT_ONE].get_outlet ();
set_context (one);
first_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_car (lst))));
- Context *two = handles_[CONTEXT_TWO].get_outlet ();
+
+ Context *two = tr->find_create_context (ly_symbol2scm ("Voice"),
+ "two", props);
+ two_.set_context (two);
set_context (two);
second_iter_ = unsmob_iterator (get_iterator (unsmob_music (scm_cadr (lst))));
+ set_context (tr);
+
char const *syms[]
= {
"Stem",
0
};
+ // Add listeners to all contexts except Devnull.
+ Context *contexts[] = {one, two, solo_tr, tr, 0};
+ for (int i = 0; contexts[i]; i++)
+ {
+ contexts[i]->event_source ()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+ }
+
for (char const **p = syms; *p; p++)
{
SCM sym = ly_symbol2scm (*p);
return;
Stream_event *e = unsmob_stream_event (se);
+ SCM mus = e->get_property ("music");
+ Music *m = unsmob_music (mus);
+ assert (m);
- if (e->in_event_class ("note-event") || e->in_event_class ("cluster-note-event"))
+ if (m->is_mus_type ("note-event") || m->is_mus_type ("cluster-note-event"))
busy_ = true;
}
Moment now = get_outlet ()->now_mom ();
Moment *splitm = 0;
- /* This is needed if construct_children was called before iteration
- started */
- if (start_moment_.main_part_.is_infinity () && start_moment_ < 0)
- start_moment_ = now;
-
for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_))
{
splitm = unsmob_moment (scm_caar (split_list_));
#include "international.hh"
#include "item.hh"
#include "misc.hh"
+#include "percent-repeat-iterator.hh"
#include "repeated-music.hh"
+#include "score-context.hh"
#include "side-position-interface.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
#include "translator.icc"
TRANSLATOR_DECLARATIONS (Percent_repeat_engraver);
protected:
- Stream_event *percent_event_;
+ Music *percent_event_;
/// moment (global time) where percent started.
Moment stop_mom_;
Spanner *percent_;
Spanner *percent_counter_;
-
- Grob *first_command_column_;
- Moment command_moment_;
-
protected:
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (percent);
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void start_translation_timestep ();
{
percent_ = 0;
percent_counter_ = 0;
- percent_event_ = 0;
-
- first_command_column_ = 0;
- command_moment_ = Moment (-1);
-}
-
-void
-Percent_repeat_engraver::start_translation_timestep ()
-{
- if (now_mom ().main_part_ != command_moment_.main_part_)
- {
- first_command_column_ = unsmob_grob (get_property ("currentCommandColumn"));
- command_moment_ = now_mom ();
- }
- if (stop_mom_.main_part_ == now_mom ().main_part_)
- {
- if (percent_)
- typeset_perc ();
- percent_event_ = 0;
- repeat_sign_type_ = UNKNOWN;
- }
+ percent_event_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Percent_repeat_engraver, percent);
-void
-Percent_repeat_engraver::listen_percent (Stream_event *ev)
+bool
+Percent_repeat_engraver::try_music (Music *m)
{
- if (!percent_event_)
+ if (m->is_mus_type ("percent-event")
+ && !percent_event_)
{
- Moment body_length = get_event_length (ev);
+ Moment body_length = m->get_length ();
Moment meas_len (robust_scm2moment (get_property ("measureLength"),
Moment (1)));
+
if (meas_len == body_length)
- {
- repeat_sign_type_ = MEASURE;
- start_mom_ = now_mom ();
- stop_mom_ = now_mom () + body_length;
- get_global_context ()->add_moment_to_process (stop_mom_);
- }
+ {
+ repeat_sign_type_ = MEASURE;
+ start_mom_ = now_mom ();
+ stop_mom_ = now_mom () + body_length;
+ get_global_context ()->add_moment_to_process (stop_mom_);
+ }
else if (Moment (2) * meas_len == body_length)
- {
- repeat_sign_type_ = DOUBLE_MEASURE;
- start_mom_ = now_mom () + meas_len;
- stop_mom_ = now_mom () + body_length; /* never used */
- get_global_context ()->add_moment_to_process (start_mom_);
- }
+ {
+ repeat_sign_type_ = DOUBLE_MEASURE;
+ start_mom_ = now_mom () + meas_len;
+ stop_mom_ = now_mom () + body_length; /* never used */
+ get_global_context ()->add_moment_to_process (start_mom_);
+ }
else
- {
- /*
- don't warn about percent repeats: slash repeats are not
- exactly 1 or 2 measures long.
- */
- return;
- }
- percent_event_ = ev;
+ return false;
+
+ percent_event_ = m;
+
+ return true;
}
- else
- /* print a warning: no assignment happens because
- percent_event_ != 0 */
- ASSIGN_EVENT_ONCE (percent_event_, ev);
+
+ return false;
}
void
{
if (percent_)
typeset_perc ();
-
percent_ = make_spanner ("PercentRepeat", percent_event_->self_scm ());
- Grob *col = first_command_column_;
+ Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
percent_->set_bound (LEFT, col);
SCM count = percent_event_->get_property ("repeat-count");
{
if (percent_)
{
- Grob *col = first_command_column_;
+ Grob *col = unsmob_grob (get_property ("currentCommandColumn"));
percent_->set_bound (RIGHT, col);
percent_ = 0;
}
}
-
+void
+Percent_repeat_engraver::start_translation_timestep ()
+{
+ if (stop_mom_.main_part_ == now_mom ().main_part_)
+ {
+ if (percent_)
+ typeset_perc ();
+ percent_event_ = 0;
+ repeat_sign_type_ = UNKNOWN;
+ }
+}
void
Percent_repeat_engraver::stop_translation_timestep ()
Erik Sandberg <mandolaerik@gmail.com>
*/
+#include "percent-repeat-iterator.hh"
#include "input.hh"
#include "music.hh"
#include "repeated-music.hh"
-#include "sequential-iterator.hh"
-
-class Percent_repeat_iterator : public Sequential_iterator
-{
-public:
- DECLARE_CLASSNAME(Percent_repeat_iterator);
- DECLARE_SCHEME_CALLBACK (constructor, ());
- Percent_repeat_iterator ();
-protected:
- virtual SCM get_music_list () const;
-};
IMPLEMENT_CTOR_CALLBACK (Percent_repeat_iterator);
percent->set_spot (*mus->origin ());
percent->set_property ("length", length);
if (repeats > 1)
- percent->set_property ("repeat-count", scm_int2num (i));
-
+ percent->set_property ("repeat-count", scm_int2num (i - 1));
child_list = scm_cons (percent->unprotect (), child_list);
}
-
child_list = scm_cons (child->self_scm (), child_list);
return child_list;
void
Performance::output (Midi_stream &midi_stream)
{
- int tracks_ = audio_staffs_.size ();
+ int tracks_i = audio_staffs_.size () + 1;
// ugh
- int clocks_per_4 = 384;
+ int clocks_per_4_i = 384;
- midi_stream << Midi_header (1, tracks_, clocks_per_4);
+ midi_stream << Midi_header (1, tracks_i, clocks_per_4_i);
+ output_header_track (midi_stream);
message (_ ("Track...") + " ");
int channel = 0;
for (vsize i = 0; i < audio_staffs_.size (); i++)
Huh? Why does each staff also have a separate channel? We
should map channels to voices, not staves. --hwn.
*/
- if (channel > 15)
+ if (s->channel_ < 0)
{
- warning (_ ("MIDI channel wrapped around"));
- warning (_ ("remapping modulo 16"));
+ s->channel_ = channel % 16;
+ if (channel > 15)
+ {
+ warning (_ ("MIDI channel wrapped around"));
+ warning (_ ("remapping modulo 16"));
+ }
}
- s->output (midi_stream, channel);
- channel ++;
+ s->output (midi_stream, channel++);
if (be_verbose_global)
progress_indication ("]");
}
}
+void
+Performance::output_header_track (Midi_stream &midi_stream)
+{
+ Midi_track midi_track;
+
+ midi_track.channel_ = 9;
+
+ // perhaps multiple text events?
+ string id_string;
+ string str = string (_ ("Creator: "));
+ id_string = String_convert::pad_to (gnu_lilypond_version_string (), 30);
+ str += id_string;
+
+ /*
+ This seems silly, but in fact the audio elements should
+ be generated elsewhere: not midi-specific.
+ */
+ Audio_text creator_a (Audio_text::TEXT, str);
+ Midi_text creator (&creator_a);
+ midi_track.add (Moment (0), &creator);
+
+ /* Better not translate this */
+ str = "Generated automatically by: ";
+ str += id_string;
+
+ Audio_text generate_a (Audio_text::TEXT, str);
+ Midi_text generate (&generate_a);
+ midi_track.add (Moment (0), &generate);
+
+ str = _ ("at ");
+ time_t t (time (0));
+ str += ctime (&t);
+ str = str.substr (0, str.length () - 1);
+ str = String_convert::pad_to (str, 60);
+
+ Audio_text at_a (Audio_text::TEXT, str);
+ Midi_text at (&at_a);
+ midi_track.add (Moment (0), &at);
+
+ // TODO:
+ // str = _f ("from musical definition: %s", origin_string_);
+
+ Audio_text from_a (Audio_text::TEXT, str);
+ Midi_text from (&from_a);
+ midi_track.add (Moment (0), &from);
+
+ Audio_text track_name_a (Audio_text::TRACK_NAME, "Track "
+ + String_convert::int2dec (0, 0, '0'));
+ Midi_text track_name (&track_name_a);
+
+ midi_track.add (Moment (0), &track_name);
+
+ // Some sequencers read track 0 last.
+ // Audio_tempo tempo_a (midi_->get_tempo (Moment (Rational (1, 4))));
+ // Midi_tempo tempo (&tempo_a);
+ // midi_track.add (Moment (0), &tempo);
+
+ midi_stream << midi_track;
+}
+
void
Performance::add_element (Audio_element *p)
{
+ if (Audio_staff *s = dynamic_cast<Audio_staff *> (p))
+ audio_staffs_.push_back (s);
+
audio_elements_.push_back (p);
}
progress_indication ("\n");
}
-
announce_infos_.clear ();
}
}
+
+void
+Performer_group::play_element (Audio_element *e)
+{
+ Context *c = context_->get_parent_context ();
+ if (c)
+ {
+ Performer_group *pgp = dynamic_cast<Performer_group *> (c->implementation ());
+ pgp->play_element (e);
+ }
+}
+
+int
+Performer_group::get_tempo () const
+{
+ Context *c = context_->get_parent_context ();
+ if (c)
+ {
+ Performer_group *pgp = dynamic_cast<Performer_group *> (c->implementation ());
+ return pgp->get_tempo ();
+ }
+ return 60;
+}
+
#include "performer-group.hh"
#include "warn.hh"
+void
+Performer::play_element (Audio_element *p)
+{
+ get_daddy_performer ()->play_element (p);
+}
+
+int
+Performer::get_tempo () const
+{
+ return get_daddy_performer ()->get_tempo ();
+}
Performer_group *
Performer::get_daddy_performer () const
SCM_ARG1, __FUNCTION__, "string");
string file_name = ly_scm2string (pfb_file_name);
+ int len = -1;
if (be_verbose_global)
progress_indication ("[" + file_name);
- vector<char> pfb_string = gulp_file (file_name, 0);
- char *pfa = pfb2pfa ((Byte *) &pfb_string[0], pfb_string.size ());
-
+ char *str = gulp_file (file_name, &len);
+ char *pfa = pfb2pfa ((Byte *)str, len);
+
SCM pfa_scm = scm_makfrom0str (pfa);
free (pfa);
-
+ delete str;
if (be_verbose_global)
progress_indication ("]");
#include "note-column.hh"
#include "slur.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
/*
It is possible that a slur starts and ends on the same note. At
least, it is for phrasing slurs: a note can be both beginning and
ending of a phrase.
-
*/
-/*
- NOTE NOTE NOTE
-
- This is largely similar to Slur_engraver. Check if fixes apply there too.
-
- (on principle, engravers don't use inheritance for code sharing)
-
- */
class Phrasing_slur_engraver : public Engraver
{
- Drul_array<Stream_event *> events_;
- Stream_event *running_slur_start_;
+ Drul_array<Music *> events_;
+ Music *running_slur_start_;
vector<Grob*> slurs_;
vector<Grob*> end_slurs_;
protected:
+ virtual bool try_music (Music *);
+
void acknowledge_extra_object (Grob_info);
DECLARE_ACKNOWLEDGER (accidental);
DECLARE_ACKNOWLEDGER (dynamic_line_spanner);
DECLARE_ACKNOWLEDGER (slur);
DECLARE_ACKNOWLEDGER (text_script);
DECLARE_ACKNOWLEDGER (tie);
- DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
void stop_translation_timestep ();
virtual void finalize ();
events_[START] = events_[STOP] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur);
-void
-Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev)
+bool
+Phrasing_slur_engraver::try_music (Music *m)
{
- /*
- Let's not start more than one slur per moment.
- */
- Direction d = to_dir (ev->get_property ("span-direction"));
- if (d == START)
- ASSIGN_EVENT_ONCE (events_[START], ev);
- else if (d == STOP && !slurs_.empty ())
- ASSIGN_EVENT_ONCE (events_[STOP], ev);
+ if (m->is_mus_type ("phrasing-slur-event"))
+ {
+ /*
+ Let's not start more than one slur per moment.
+ */
+ Direction d = to_dir (m->get_property ("span-direction"));
+ if (d == START)
+ {
+ events_[START] = m;
+ return true;
+ }
+ else if (d == STOP)
+ {
+ if (slurs_.empty ())
+ return false;
+
+ events_[STOP] = m;
+ return true;
+ }
+ }
+ return false;
}
void
void
Phrasing_slur_engraver::acknowledge_script (Grob_info info)
{
- if (!info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface")))
- acknowledge_extra_object (info);
+ acknowledge_extra_object (info);
}
void
if (events_[START] && slurs_.empty ())
{
- Stream_event *ev = events_[START];
+ Music *ev = events_[START];
Grob *slur = make_spanner ("PhrasingSlur", events_[START]->self_scm ());
Direction updown = to_dir (ev->get_property ("direction"));
events_[START] = events_[STOP] = 0;
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, accidental);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, dynamic_line_spanner);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, fingering)
-ADD_ACKNOWLEDGER (Phrasing_slur_engraver, note_column);
+ ADD_ACKNOWLEDGER (Phrasing_slur_engraver, note_column);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, script);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, slur);
ADD_ACKNOWLEDGER (Phrasing_slur_engraver, text_script);
source file of the GNU LilyPond music typesetter
- (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>,
- Erik Sandberg <mandolaerik@gmail.com>
+ (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
Chris Jackson <chris@fluffhouse.org.uk> - extended to support
bracketed pedals.
#include "note-column.hh"
#include "side-position-interface.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
-#include "string-convert.hh"
#include "warn.hh"
-#include "protected-scm.hh"
-#include "translator.icc"
/*
Urgh. This engraver is too complex. rewrite. --hwn
*/
-/* Ugh: This declaration is duplicated in piano-pedal-performer */
-typedef enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES};
-
-/*
- Static precalculated data (symbols and strings) for the different
- pedal types
-*/
-struct Pedal_type_info
-{
- string base_name_;
- SCM event_class_sym_;
- SCM style_sym_;
- SCM strings_sym_;
-
- const char *pedal_line_spanner_c_str_;
- const char *pedal_c_str_;
-
- Pedal_type_info ()
- {
- event_class_sym_ = SCM_EOL;
- style_sym_ = SCM_EOL;
- strings_sym_ = SCM_EOL;
- pedal_line_spanner_c_str_ = 0;
- pedal_c_str_ = 0;
- }
- void protect ()
- {
- scm_gc_protect_object (event_class_sym_);
- scm_gc_protect_object (style_sym_);
- scm_gc_protect_object (strings_sym_);
- }
-};
-
struct Pedal_info
{
- const Pedal_type_info *type_;
+ char const *name_;
/*
Event for currently running pedal.
*/
- Stream_event *current_bracket_ev_;
+ Music *current_bracket_ev_;
/*
Event for currently starting pedal, (necessary?
distinct from current_bracket_ev_, since current_bracket_ev_ only
necessary for brackets, not for text style.
*/
- Stream_event *start_ev_;
+ Music *start_ev_;
/*
Events that were found in this timestep.
*/
- Drul_array<Stream_event *> event_drul_;
+ Drul_array<Music *> event_drul_;
Item *item_;
Spanner *bracket_; // A single portion of a pedal bracket
Spanner *finished_bracket_;
Spanner *finished_line_spanner_;
};
-static Pedal_type_info pedal_types_[NUM_PEDAL_TYPES];
-
class Piano_pedal_engraver : public Engraver
{
public:
protected:
virtual void initialize ();
virtual void finalize ();
- DECLARE_TRANSLATOR_LISTENER (sustain);
- DECLARE_TRANSLATOR_LISTENER (una_corda);
- DECLARE_TRANSLATOR_LISTENER (sostenuto);
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
DECLARE_ACKNOWLEDGER (note_column);
void process_music ();
private:
- Pedal_info info_list_[NUM_PEDAL_TYPES + 1];
+
+ Pedal_info *info_list_;
/*
Record a stack of the current pedal spanners, so if more than one pedal
void typeset_all (Pedal_info *p);
};
-static void
-init_pedal_types ()
-{
- const char *names [NUM_PEDAL_TYPES];
- names[SOSTENUTO] = "Sostenuto";
- names[SUSTAIN] = "Sustain";
- names[UNA_CORDA] = "UnaCorda";
-
- for (int i = 0; i < NUM_PEDAL_TYPES; i++)
- {
- const char *name = names[i];
- /* FooBar */
- string base_name = name;
- /* foo-bar */
- string base_ident = "";
- int prev_pos=0;
- int cur_pos;
- for (cur_pos = 1; name[cur_pos]; cur_pos++)
- if (isupper (name[cur_pos]))
- {
- base_ident = base_ident + String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos)) + "-";
- prev_pos = cur_pos;
- }
- base_ident += String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos));
-
- /*
- be careful, as we don't want to loose references to the _sym_ members.
- */
- Pedal_type_info info;
- info.event_class_sym_ = scm_str2symbol ((base_ident + "-event").c_str ());
- info.style_sym_ = scm_str2symbol (("pedal" + base_name + "Style").c_str ());
- info.strings_sym_ = scm_str2symbol (("pedal" + base_name + "Strings").c_str ());
-
- info.pedal_line_spanner_c_str_ = strdup ((base_name + "PedalLineSpanner").c_str ());
- info.base_name_ = name;
- info.pedal_c_str_ = strdup ((base_name + "Pedal").c_str ());
-
- info.protect ();
-
- pedal_types_[i] = info;
- }
-}
-ADD_SCM_INIT_FUNC (Piano_pedal_engraver_init_pedal_types_, init_pedal_types);
-
Piano_pedal_engraver::Piano_pedal_engraver ()
{
+ info_list_ = 0;
}
void
Piano_pedal_engraver::initialize ()
{
- for (int i = 0; i < NUM_PEDAL_TYPES; i++)
+ char *names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 };
+
+ info_list_ = new Pedal_info[sizeof (names) / sizeof (char const *)];
+ Pedal_info *p = info_list_;
+
+ char **np = names;
+ do
{
- Pedal_type_info *s = &pedal_types_[i];
- Pedal_info *info = &info_list_[i];
-
- info->type_ = s;
- info->item_ = 0;
- info->bracket_ = 0;
- info->finished_bracket_ = 0;
- info->line_spanner_ = 0;
- info->finished_line_spanner_ = 0;
- info->current_bracket_ev_ = 0;
- info->event_drul_[START] = 0;
- info->event_drul_[STOP] = 0;
- info->start_ev_ = 0;
+ p->name_ = *np;
+ p->item_ = 0;
+ p->bracket_ = 0;
+ p->finished_bracket_ = 0;
+ p->line_spanner_ = 0;
+ p->finished_line_spanner_ = 0;
+ p->current_bracket_ev_ = 0;
+ p->event_drul_[START] = 0;
+ p->event_drul_[STOP] = 0;
+ p->start_ev_ = 0;
+
+ p++;
}
- info_list_[NUM_PEDAL_TYPES].type_ = 0;
+ while (* (np++));
}
Piano_pedal_engraver::~Piano_pedal_engraver ()
{
+ delete[] info_list_;
}
/*
void
Piano_pedal_engraver::acknowledge_note_column (Grob_info info)
{
- for (Pedal_info *p = info_list_; p->type_; p++)
+ for (Pedal_info *p = info_list_; p && p->name_; p++)
{
if (p->line_spanner_)
{
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sostenuto);
-void
-Piano_pedal_engraver::listen_sostenuto (Stream_event *ev)
+bool
+Piano_pedal_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (info_list_[SOSTENUTO].event_drul_[d], ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sustain);
-void
-Piano_pedal_engraver::listen_sustain (Stream_event *ev)
-{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (info_list_[SUSTAIN].event_drul_[d], ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, una_corda);
-void
-Piano_pedal_engraver::listen_una_corda (Stream_event *ev)
-{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (info_list_[UNA_CORDA].event_drul_[d], ev);
+ if (m->is_mus_type ("pedal-event"))
+ {
+ for (Pedal_info *p = info_list_; p->name_; p++)
+ {
+ string nm = p->name_ + string ("Event");
+ if (ly_is_equal (m->get_property ("name"),
+ scm_str2symbol (nm.c_str ())))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ p->event_drul_[d] = m;
+ return true;
+ }
+ }
+ }
+ return false;
}
void
Piano_pedal_engraver::process_music ()
{
- for (Pedal_info *p = info_list_; p->type_; p++)
+ for (Pedal_info *p = info_list_; p && p->name_; p++)
{
if (p->event_drul_[STOP] || p->event_drul_[START])
{
if (!p->line_spanner_)
{
- const char *name = p->type_->pedal_line_spanner_c_str_;
- Stream_event *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]);
- p->line_spanner_ = make_spanner (name, rq->self_scm ());
+ string name = string (p->name_) + "PedalLineSpanner";
+ Music *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]);
+ p->line_spanner_ = make_spanner (name.c_str (), rq->self_scm ());
}
/* Choose the appropriate grobs to add to the line spanner
mixed: Ped. _____/\____|
*/
- SCM style = internal_get_property (p->type_->style_sym_);
+ string prop = string ("pedal") + p->name_ + "Style";
+ SCM style = get_property (prop.c_str ());
bool mixed = style == ly_symbol2scm ("mixed");
bool bracket = (mixed
Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed)
{
SCM s = SCM_EOL;
- SCM strings = internal_get_property (p->type_->strings_sym_);
+ SCM strings = get_property (("pedal" + string (p->name_) + "Strings").c_str ());
if (scm_ilength (strings) < 3)
{
- Stream_event *m = p->event_drul_[START];
+ Music *m = p->event_drul_[START];
if (!m) m = p->event_drul_ [STOP];
string msg = _f ("expect 3 strings for piano pedals, found: %ld",
if (!mixed)
{
if (!p->start_ev_)
- p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ()));
+ p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
else
s = scm_cadr (strings);
p->start_ev_ = p->event_drul_[START];
if (!mixed)
{
if (!p->start_ev_)
- p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ()));
+ p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
else
s = scm_caddr (strings);
p->start_ev_ = 0;
if (scm_is_string (s))
{
- const char *propname = p->type_->pedal_c_str_;
+ string propname = string (p->name_) + "Pedal";
- p->item_ = make_item (propname, (p->event_drul_[START]
- ? p->event_drul_[START]
- : p->event_drul_[STOP])->self_scm ());
+ p->item_ = make_item (propname.c_str (), (p->event_drul_[START]
+ ? p->event_drul_[START]
+ : p->event_drul_[STOP])->self_scm ());
p->item_->set_property ("text", s);
Axis_group_interface::add_element (p->line_spanner_, p->item_);
{
if (!p->bracket_ && p->event_drul_[STOP])
{
- string msg = _f ("can't find start of piano pedal bracket: `%s'", p->type_->base_name_.c_str ());
+ string msg = _f ("can't find start of piano pedal bracket: `%s'", p->name_);
p->event_drul_[STOP]->origin ()->warning (msg);
p->event_drul_[STOP] = 0;
}
void
Piano_pedal_engraver::finalize ()
{
- for (Pedal_info *p = info_list_; p->type_; p++)
+ for (Pedal_info *p = info_list_; p && p->name_; p++)
{
/*
suicide?
void
Piano_pedal_engraver::stop_translation_timestep ()
{
- for (Pedal_info *p = info_list_; p->type_; p++)
+ for (Pedal_info *p = info_list_; p && p->name_; p++)
{
if (!p->bracket_)
{
typeset_all (p);
}
- for (Pedal_info *p = info_list_; p->type_; p++)
+ for (Pedal_info *p = info_list_; p->name_; p++)
{
p->event_drul_[STOP] = 0;
p->event_drul_[START] = 0;
}
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Piano_pedal_engraver, note_column);
ADD_TRANSLATOR (Piano_pedal_engraver,
#include "audio-item.hh"
#include "international.hh"
-#include "stream-event.hh"
-#include "warn.hh"
-
-#include "translator.icc"
-
-typedef enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES};
+#include "music.hh"
/**
perform Piano pedals
{
struct Pedal_info
{
- Stream_event *start_event_;
- Drul_array<Stream_event *> event_drul_;
+ char const *name_;
+ Music *start_event_;
+ Drul_array<Music *> event_drul_;
};
public:
TRANSLATOR_DECLARATIONS (Piano_pedal_performer);
+ ~Piano_pedal_performer ();
protected:
virtual void initialize ();
- static const char *pedal_type_str (int t);
+ virtual bool try_music (Music *);
void process_music ();
void stop_translation_timestep ();
void start_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (sustain);
- DECLARE_TRANSLATOR_LISTENER (una_corda);
- DECLARE_TRANSLATOR_LISTENER (sostenuto);
+
private:
vector<Audio_piano_pedal*> audios_;
- Pedal_info info_alist_[NUM_PEDAL_TYPES];
+ Pedal_info *info_alist_;
};
Piano_pedal_performer::Piano_pedal_performer ()
{
+ info_alist_ = 0;
}
-const char *
-Piano_pedal_performer::pedal_type_str (int t)
+Piano_pedal_performer::~Piano_pedal_performer ()
{
- switch (t)
- {
- case SOSTENUTO:
- return "Sostenuto";
- case SUSTAIN:
- return "Sustain";
- case UNA_CORDA:
- return "UnaCorda";
- default:
- programming_error ("Unknown pedal type");
- return 0;
- }
+ delete[] info_alist_;
}
void
Piano_pedal_performer::initialize ()
{
+ info_alist_ = new Pedal_info[4];
Pedal_info *p = info_alist_;
- for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
+ char *names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 };
+ char **np = names;
+ do
{
+ p->name_ = *np;
p->event_drul_[START] = 0;
p->event_drul_[STOP] = 0;
p->start_event_ = 0;
+
+ p++;
}
+ while (* (np++));
}
void
Piano_pedal_performer::process_music ()
{
- Pedal_info *p = info_alist_;
+ for (Pedal_info *p = info_alist_; p && p->name_; p++)
- for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
{
- string pedal_type = pedal_type_str (i);
if (p->event_drul_[STOP])
{
if (!p->start_event_)
- p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", pedal_type));
+ p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", string (p->name_)));
else
{
Audio_piano_pedal *a = new Audio_piano_pedal;
- a->type_string_ = pedal_type;
+ a->type_string_ = string (p->name_);
a->dir_ = STOP;
audios_.push_back (a);
Audio_element_info info(a, p->event_drul_[STOP]);
{
p->start_event_ = p->event_drul_[START];
Audio_piano_pedal *a = new Audio_piano_pedal;
- a->type_string_ = pedal_type;
+ a->type_string_ = string (p->name_);
a->dir_ = START;
audios_.push_back (a);
Audio_element_info info(a, p->event_drul_[START]);
void
Piano_pedal_performer::stop_translation_timestep ()
{
+ for (vsize i = 0; i < audios_.size (); i++)
+ play_element (audios_[i]);
audios_.clear ();
}
void
Piano_pedal_performer::start_translation_timestep ()
{
- Pedal_info *p = info_alist_;
- for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
+ for (Pedal_info *p = info_alist_; p && p->name_; p++)
{
p->event_drul_[STOP] = 0;
p->event_drul_[START] = 0;
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sostenuto);
-void
-Piano_pedal_performer::listen_sostenuto (Stream_event *r)
-{
- Direction d = to_dir (r->get_property ("span-direction"));
- info_alist_[SOSTENUTO].event_drul_[d] = r;
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sustain);
-void
-Piano_pedal_performer::listen_sustain (Stream_event *r)
+bool
+Piano_pedal_performer::try_music (Music *r)
{
- Direction d = to_dir (r->get_property ("span-direction"));
- info_alist_[SUSTAIN].event_drul_[d] = r;
+ if (r->is_mus_type ("pedal-event"))
+ {
+ for (Pedal_info *p = info_alist_; p->name_; p++)
+ {
+ string nm = p->name_ + string ("Event");
+ if (ly_is_equal (r->get_property ("name"),
+ scm_str2symbol (nm.c_str ())))
+ {
+ Direction d = to_dir (r->get_property ("span-direction"));
+ p->event_drul_[d] = r;
+ return true;
+ }
+ }
+ }
+ return false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, una_corda);
-void
-Piano_pedal_performer::listen_una_corda (Stream_event *r)
-{
- Direction d = to_dir (r->get_property ("span-direction"));
- info_alist_[UNA_CORDA].event_drul_[d] = r;
-}
+#include "translator.icc"
ADD_TRANSLATOR (Piano_pedal_performer, "", "",
"pedal-event",
notename_ = n;
alteration_ = a;
octave_ = o;
- scale_ = default_global_scale;
normalise ();
}
{
notename_ = 0;
alteration_ = 0;
- scale_ = default_global_scale;
octave_ = 0;
}
int
Pitch::steps () const
{
- return notename_ + octave_ * scale_->step_semitones_.size ();
+ return notename_ + octave_ * 7;
}
/* Should be settable from input? */
-// static Byte diatonic_scale_semitones[ ] = { 0, 2, 4, 5, 7, 9, 11 };
-
-
+static Byte diatonic_scale_semitones[ ] = { 0, 2, 4, 5, 7, 9, 11 };
/* Calculate pitch height in 12th octave steps. Don't assume
normalised pitch as this function is used to normalise the pitch. */
int n = notename_;
while (n < 0)
{
- n += scale_->step_semitones_.size ();
+ n += 7;
o--;
}
if (alteration_ % 2)
programming_error ("semitone_pitch () called on quarter tone alteration.");
- return ((o + n / scale_->step_semitones_.size ()) * 12
- + scale_->step_semitones_[n % scale_->step_semitones_.size ()]
+ return ((o + n / 7) * 12
+ + diatonic_scale_semitones[n % 7]
+ (alteration_ / 2));
}
int n = notename_;
while (n < 0)
{
- n += scale_->step_semitones_.size ();
+ n += 7;
o--;
}
- return ((o + n / scale_->step_semitones_.size ()) * 24
- + 2 * scale_->step_semitones_[n % scale_->step_semitones_.size ()]
+ return ((o + n / 7) * 24
+ + 2 * diatonic_scale_semitones[n % 7]
+ alteration_);
}
Pitch::normalise ()
{
int pitch = quartertone_pitch ();
- while (notename_ >= (int) scale_->step_semitones_.size ())
+ while (notename_ >= 7)
{
- notename_ -= scale_->step_semitones_.size ();
+ notename_ -= 7;
octave_++;
alteration_ -= quartertone_pitch () - pitch;
}
while (notename_ < 0)
{
- notename_ += scale_->step_semitones_.size ();
+ notename_ += 7;
octave_--;
alteration_ -= quartertone_pitch () - pitch;
}
string
Pitch::to_string () const
{
- int n = (notename_ + 2) % scale_->step_semitones_.size ();
+ int n = (notename_ + 2) % 7;
string s = ::to_string (char (n + 'a'));
if (alteration_)
s += string (accname[alteration_ - DOUBLE_FLAT]);
}
IMPLEMENT_TYPE_P (Pitch, "ly:pitch?");
+
SCM
-Pitch::mark_smob (SCM x)
+Pitch::mark_smob (SCM)
{
- Pitch *p = (Pitch*) SCM_CELL_WORD_1 (x);
- return p->scale_->self_scm ();
+ return SCM_EOL;
}
IMPLEMENT_SIMPLE_SMOBS (Pitch);
#include "engraver.hh"
+#include "dots.hh"
+#include "pointer-group-interface.hh"
#include "axis-group-interface.hh"
#include "context.hh"
-#include "dots.hh"
-#include "item.hh"
#include "note-head.hh"
-#include "pitch.hh"
-#include "pointer-group-interface.hh"
+#include "item.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
+#include "pitch.hh"
#include "warn.hh"
class Pitched_trill_engraver : public Engraver
vector<Grob*> heads_;
- void make_trill (Stream_event *);
+ void make_trill (Music *);
};
Pitched_trill_engraver::Pitched_trill_engraver ()
void
Pitched_trill_engraver::acknowledge_text_spanner (Grob_info info)
{
- Stream_event *ev = info.event_cause ();
- if (ev
- && ev->in_event_class ("trill-span-event")
- && to_dir (ev->get_property ("span-direction")) == START
- && unsmob_pitch (ev->get_property ("pitch")))
- make_trill (ev);
+ Music *mus = info.music_cause ();
+ if (mus
+ && mus->is_mus_type ("trill-span-event")
+ && to_dir (mus->get_property ("span-direction")) == START
+ && unsmob_pitch (mus->get_property ("pitch")))
+ make_trill (mus);
}
void
-Pitched_trill_engraver::make_trill (Stream_event *ev)
+Pitched_trill_engraver::make_trill (Music *mus)
{
- SCM scm_pitch = ev->get_property ("pitch");
+ SCM scm_pitch = mus->get_property ("pitch");
Pitch *p = unsmob_pitch (scm_pitch);
SCM keysig = get_property ("localKeySignature");
SCM handle = scm_assoc (key, keysig);
bool print_acc
- = (handle == SCM_BOOL_F) || p->get_alteration () == 0;
+ = (handle == SCM_BOOL_F)
+ || p->get_alteration () == 0;
if (trill_head_)
{
trill_head_ = 0;
}
- trill_head_ = make_item ("TrillPitchHead", ev->self_scm ());
+ trill_head_ = make_item ("TrillPitchHead", mus->self_scm ());
SCM c0scm = get_property ("middleCPosition");
int c0 = scm_is_number (c0scm) ? scm_to_int (c0scm) : 0;
scm_from_int (unsmob_pitch (scm_pitch)->steps ()
+ c0));
- trill_group_ = make_item ("TrillPitchGroup", ev->self_scm ());
- trill_group_->set_parent (trill_head_, Y_AXIS);
+ trill_group_ = make_item ("TrillPitchGroup", mus->self_scm ());
Axis_group_interface::add_element (trill_group_, trill_head_);
if (print_acc)
{
- trill_accidental_ = make_item ("TrillPitchAccidental", ev->self_scm ());
+ trill_accidental_ = make_item ("TrillPitchAccidental", mus->self_scm ());
// fixme: naming -> alterations
trill_accidental_->set_property ("accidentals", scm_list_1 (scm_from_int (p->get_alteration ())));
Side_position_interface::add_support (trill_accidental_, trill_head_);
trill_head_->set_object ("accidental-grob", trill_accidental_->self_scm ());
- trill_accidental_->set_parent (trill_head_, Y_AXIS);
+ trill_group_->set_parent (trill_head_, Y_AXIS);
Axis_group_interface::add_element (trill_group_, trill_accidental_);
+ trill_accidental_->set_parent (trill_head_, Y_AXIS);
}
}
ADD_ACKNOWLEDGER (Pitched_trill_engraver, text_spanner);
ADD_TRANSLATOR (Pitched_trill_engraver,
- /* doc */
- "Print the bracketed notehead after a notehead with trill.",
-
+ /* doc */ "Print the bracketed notehead after a notehead with trill.",
/* create */
"TrillPitchHead "
"TrillPitchAccidental "
- "TrillPitchGroup ",
-
+ "TrillPitchGroup",
/* accept */ "",
-
/* read */ "",
-
/* write */ "");
{
scm_arr = Grob_array::make_array ();
arr = unsmob_grob_array (scm_arr);
- me->set_object (sym, scm_arr);
+ me->internal_set_object (sym, scm_arr);
}
return arr;
}
SCM_ASSERT_TYPE (ps, obj, SCM_ARG1, __FUNCTION__, "Prob");
SCM_ASSERT_TYPE (scm_is_symbol (sym), sym, SCM_ARG2, __FUNCTION__, "symbol");
- ps->set_property (sym, value);
+ ps->internal_set_property (sym, value);
return SCM_UNSPECIFIED;
}
SCM sym = scm_car (s);
SCM val = scm_cadr (s);
- pr->set_property (sym, val);
+ pr->internal_set_property (sym, val);
}
return pr->unprotect ();
smobify_self ();
}
-
Prob::~Prob ()
{
}
}
void
-Prob::internal_set_property (SCM sym, SCM val
-#ifndef NDEBUG
- , char const *file, int line, char const *fun
-#endif
- )
+Prob::internal_set_property (SCM sym, SCM val)
{
if (do_internal_type_checking_global)
type_check_assignment (sym, val);
profile_property_accesses = to_boolean (val);
val = scm_from_bool (to_boolean (val));
}
- else if (var == ly_symbol2scm ("debug-midi"))
+ else if (var == ly_symbol2scm ("midi-debug"))
{
do_midi_debugging_global = to_boolean (val);
val = scm_from_bool (to_boolean (val));
point_and_click_global = to_boolean (val);
val = scm_from_bool (to_boolean (val));
}
- else if (var == ly_symbol2scm ("protected-scheme-parsing"))
+ else if (var == ly_symbol2scm ("parse-protect"))
{
parse_protect_global = to_boolean (val);
val = scm_from_bool (to_boolean (val));
}
- else if (var == ly_symbol2scm ("check-internal-types"))
+ else if (var == ly_symbol2scm ("internal-type-checking"))
{
do_internal_type_checking_global = to_boolean (val);
val = scm_from_bool (to_boolean (val));
}
string help ("Options supported by ly:set-option\n\n");
- vector_sort (opts, less<string> ());
+ vector_sort (opts, string_compare);
for (vsize i = 0; i < opts.size (); i++)
help += opts[i];
void
Property_iterator::process (Moment m)
{
- send_stream_event (get_outlet (), "SetProperty", get_music ()->origin (),
- ly_symbol2scm ("symbol"), get_music ()->get_property ("symbol"),
- ly_symbol2scm ("value"), get_music ()->get_property ("value"));
-
+ SCM sym = get_music ()->get_property ("symbol");
+ if (scm_is_symbol (sym))
+ {
+ SCM val = get_music ()->get_property ("value");
+ bool ok = true;
+ if (val != SCM_EOL)
+ ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"));
+ if (ok)
+ get_outlet ()->internal_set_property (sym, val);
+ }
Simple_music_iterator::process (m);
}
Property_unset_iterator::process (Moment m)
{
SCM sym = get_music ()->get_property ("symbol");
- send_stream_event (get_outlet (), "UnsetProperty", get_music ()->origin (),
- ly_symbol2scm ("symbol"), sym);
+ type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?"));
+ get_outlet ()->unset_property (sym);
Simple_music_iterator::process (m);
}
MAKE_SCHEME_CALLBACK (Property_iterator, once_finalization, 2);
SCM
-Property_iterator::once_finalization (SCM ctx, SCM music)
+Property_iterator::once_finalization (SCM translator, SCM music)
{
Music *m = unsmob_music (music);
- Context *c = unsmob_context (ctx);
+ Context *tg
+ = dynamic_cast<Context *> (unsmob_context (translator));
+ SCM sym = m->get_property ("symbol");
- send_stream_event (c, "UnsetProperty", m->origin (),
- ly_symbol2scm ("symbol"), m->get_property ("symbol"));
+ tg->unset_property (sym);
return SCM_UNSPECIFIED;
}
if (to_boolean (get_music ()->get_property ("pop-first"))
&& !to_boolean (get_music ()->get_property ("once")))
- send_stream_event (get_outlet (), "Revert", get_music ()->origin (),
- ly_symbol2scm ("symbol"), sym,
- ly_symbol2scm ("property-path"), grob_property_path);
-
- send_stream_event (get_outlet (), "Override", get_music ()->origin (),
- ly_symbol2scm ("symbol"), sym,
- ly_symbol2scm ("property-path"), grob_property_path,
- ly_symbol2scm ("value"), val);
+
+ execute_general_pushpop_property (get_outlet (), sym, grob_property_path, SCM_UNDEFINED);
+
+ execute_general_pushpop_property (get_outlet (), sym, grob_property_path, val);
}
Simple_music_iterator::process (m);
}
MAKE_SCHEME_CALLBACK (Push_property_iterator, once_finalization, 2);
SCM
-Push_property_iterator::once_finalization (SCM ctx, SCM music)
+Push_property_iterator::once_finalization (SCM trans, SCM music)
{
Music *mus = unsmob_music (music);
- Context *c = unsmob_context (ctx);
+ Context *tg = dynamic_cast<Context *> (unsmob_context (trans));
SCM sym = mus->get_property ("symbol");
if (check_grob (mus, sym))
{
SCM grob_property_path = get_property_path (mus);
- send_stream_event (c, "Revert", mus->origin (),
- ly_symbol2scm ("symbol"), sym,
- ly_symbol2scm ("property-path"), grob_property_path);
+ execute_general_pushpop_property (tg, sym, grob_property_path, SCM_UNDEFINED);
}
return SCM_UNSPECIFIED;
}
if (check_grob (get_music (), sym))
{
SCM grob_property_path = get_property_path (get_music ());
-
- send_stream_event (get_outlet (), "Revert", get_music ()->origin (),
- ly_symbol2scm ("symbol"), sym,
- ly_symbol2scm ("property-path"), grob_property_path);
+ execute_general_pushpop_property (get_outlet (), sym, grob_property_path, SCM_UNDEFINED);
}
Simple_music_iterator::process (m);
}
IMPLEMENT_CTOR_CALLBACK (Push_property_iterator);
IMPLEMENT_CTOR_CALLBACK (Property_iterator);
IMPLEMENT_CTOR_CALLBACK (Property_unset_iterator);
+
#include "music-wrapper-iterator.hh"
#include "context.hh"
-#include "dispatcher.hh"
#include "input.hh"
#include "international.hh"
#include "lily-guile.hh"
#include "music-sequence.hh"
#include "music.hh"
-#include "stream-event.hh"
#include "warn.hh"
class Quote_iterator : public Music_wrapper_iterator
DECLARE_SCHEME_CALLBACK (constructor, ());
bool quote_ok () const;
- bool accept_music_type (Stream_event *) const;
+ bool accept_music_type (Music *) const;
protected:
virtual void derived_mark () const;
}
bool
-Quote_iterator::accept_music_type (Stream_event *ev) const
+Quote_iterator::accept_music_type (Music *mus) const
{
- for (SCM accept = get_outlet ()->get_property ("quotedEventTypes");
- scm_is_pair (accept); accept = scm_cdr (accept))
+ SCM accept = get_outlet ()->get_property ("quotedEventTypes");
+ for (SCM s = mus->get_property ("types");
+ scm_is_pair (s); s = scm_cdr (s))
{
- if (ev->internal_in_event_class (scm_car (accept)))
+ if (scm_memq (scm_car (s), accept) != SCM_BOOL_F)
return true;
}
+
return false;
}
{
SCM ev_acc = scm_car (s);
- Stream_event *ev = unsmob_stream_event (scm_car (ev_acc));
- if (!ev)
+ Music *mus = unsmob_music (scm_car (ev_acc));
+ if (!mus)
programming_error ("no music found in quote");
- else if (accept_music_type (ev))
+ else if (accept_music_type (mus))
{
- /* create a transposed copy if necessary */
if (quote_pitch || me_pitch)
{
Pitch qp, mp;
Pitch diff = pitch_interval (qp, mp);
- SCM props = transpose_mutable (ev->get_property_alist (true), diff);
- ev = new Stream_event (ev->get_property ("class"), props);
- transposed_musics_ = scm_cons (ev->unprotect (), transposed_musics_);
+ SCM copy = ly_music_deep_copy (mus->self_scm ());
+ mus = unsmob_music (copy);
+
+ transposed_musics_ = scm_cons (copy, transposed_musics_);
+ mus->transpose (diff);
}
- quote_outlet_.get_outlet ()->event_source ()->broadcast (ev);
+
+ quote_outlet_.get_outlet ()->try_music (mus);
}
}
source file of the GNU LilyPond music typesetter
(c) 2003--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
-TODO: junk this file
*/
#include "recording-group-engraver.hh"
#include "context.hh"
-#include "music.hh"
-/*
- TODO: Junk this class, extract events directly instead.
-*/
void
Recording_group_engraver::derived_mark () const
{
bool
Recording_group_engraver::try_music (Music *m)
{
- bool retval = true;//Translator_group::try_music (m);
+ bool retval = Translator_group::try_music (m);
add_music (m->self_scm (), ly_bool2scm (retval));
return retval;
else if (command == "prependdir")
prepend_env_path (variable.c_str (), value);
else
- error (_f ("Unknown relocation command %s", command));
+ error ( _f("Unknown relocation command %s", command));
}
fclose (f);
void
read_relocation_dir (string dirname)
{
- if (DIR *dir = opendir (dirname.c_str ()))
- while (struct dirent *ent = readdir (dir))
- {
- File_name name (ent->d_name);
- if (name.ext_ == "reloc")
- read_relocation_file (dirname + "/" + name.to_string ());
- }
+ DIR *dir = opendir (dirname.c_str ());
+
+ while (struct dirent *ent = readdir (dir))
+ {
+ File_name name (ent->d_name);
+ if (name.ext_ == "reloc")
+ {
+ read_relocation_file (dirname + "/" + name.to_string ());
+ }
+ }
}
#include "engraver.hh"
#include "item.hh"
#include "pointer-group-interface.hh"
-#include "stream-event.hh"
#include "translator.icc"
class Repeat_tie_engraver : public Engraver
{
- Stream_event *event_;
+ Music *event_;
Grob *semi_tie_column_;
vector<Grob*> semi_ties_;
void stop_translation_timestep ();
DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_TRANSLATOR_LISTENER (repeat_tie);
+ virtual bool try_music (Music *);
public:
TRANSLATOR_DECLARATIONS (Repeat_tie_engraver);
};
semi_ties_.clear ();
}
-IMPLEMENT_TRANSLATOR_LISTENER (Repeat_tie_engraver, repeat_tie);
-void
-Repeat_tie_engraver::listen_repeat_tie (Stream_event *ev)
+bool
+Repeat_tie_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ event_ = m;
+ return true;
}
void
semi_ties_.push_back (semi_tie);
}
+
+
ADD_ACKNOWLEDGER (Repeat_tie_engraver, note_head);
ADD_TRANSLATOR (Repeat_tie_engraver,
/* doc */ "Create Laissez vibrer items.",
return scm_from_double (0.0);
}
-MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Rest_collision, force_shift_callback_rest, 2, 1);
+MAKE_SCHEME_CALLBACK (Rest_collision, force_shift_callback_rest, 2);
SCM
Rest_collision::force_shift_callback_rest (SCM rest, SCM offset)
{
translate REST; we need the result of this translation later on,
while the offset probably still is 0/calculation-in-progress.
*/
- if (scm_is_number (offset))
- rest_grob->translate_axis (scm_to_double (offset), Y_AXIS);
+ rest_grob->translate_axis (scm_to_double (offset), Y_AXIS);
if (Note_column::has_interface (parent))
force_shift_callback (parent->self_scm ());
Direction d = LEFT;
do
- vector_sort (ordered_rests[d], Note_column::shift_less);
+ vector_sort (ordered_rests[d], Note_column::shift_compare);
while (flip (&d) != LEFT)
;
for (vsize i = rests.size (); !rcol && i--;)
if (Note_column::dir (rests[i]))
{
+ dir = Note_column::dir (rests[i]);
rcol = rests[i];
- dir = Note_column::dir (rcol);
}
if (!rcol)
return SCM_UNSPECIFIED;
- Grob *rest = Note_column::get_rest (rcol);
Grob *common = common_refpoint_of_array (notes, rcol, Y_AXIS);
Interval restdim = rcol->extent (common, Y_AXIS);
for (vsize i = 0; i < notes.size (); i++)
notedim.unite (notes[i]->extent (common, Y_AXIS));
+ Real dist
+ = minimum_dist + dir * max (notedim[dir] - restdim[-dir], 0.0);
- Real y = dir * max (0.0,
- -dir * restdim[-dir] + dir * notedim[dir] + minimum_dist);
-
int stafflines = Staff_symbol_referencer::line_count (me);
if (!stafflines)
{
}
// move discretely by half spaces.
- int discrete_y = dir * int (ceil (y / (0.5 * dir * staff_space)));
+ int discrete_dist = int (ceil (dist / (0.5 * staff_space)));
// move by whole spaces inside the staff.
- if (fabs (Staff_symbol_referencer::get_position (rest)
- + discrete_y) < stafflines + 1)
- {
- discrete_y = dir * int (ceil (dir * discrete_y / 2.0) * 2.0);
- }
+ if (discrete_dist < stafflines + 1)
+ discrete_dist = int (ceil (discrete_dist / 2.0) * 2.0);
- Note_column::translate_rests (rcol, discrete_y);
+ Note_column::translate_rests (rcol, dir * discrete_dist);
}
return SCM_UNSPECIFIED;
}
#include "engraver.hh"
-#include "dots.hh"
#include "duration.hh"
#include "item.hh"
-#include "pitch.hh"
-#include "rhythmic-head.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
+#include "dots.hh"
+#include "rhythmic-head.hh"
+#include "music.hh"
class Rest_engraver : public Engraver
{
- Stream_event *rest_event_;
+ Music *rest_event_;
Item *dot_;
Grob *rest_;
protected:
+ virtual bool try_music (Music *);
void start_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (rest);
+
public:
TRANSLATOR_DECLARATIONS (Rest_engraver);
};
if (rest_event_ && !rest_)
{
rest_ = make_item ("Rest", rest_event_->self_scm ());
+
+ int durlog = unsmob_duration (rest_event_->get_property ("duration"))->duration_log ();
+
+ rest_->set_property ("duration-log",
+ scm_from_int (durlog));
+
+ int dots = unsmob_duration (rest_event_->get_property ("duration"))->dot_count ();
+
+ if (dots)
+ {
+ dot_ = make_item ("Dots", SCM_EOL);
+
+ Rhythmic_head::set_dots (rest_, dot_);
+ dot_->set_parent (rest_, Y_AXIS);
+ dot_->set_property ("dot-count", scm_from_int (dots));
+ }
+
Pitch *p = unsmob_pitch (rest_event_->get_property ("pitch"));
+ /*
+ This is ridiculous -- rests don't have pitch, but we act as if
+ our nose is bleeding.
+ */
if (p)
{
int pos = p->steps ();
}
}
-IMPLEMENT_TRANSLATOR_LISTENER (Rest_engraver, rest);
-void
-Rest_engraver::listen_rest (Stream_event *ev)
+bool
+Rest_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (rest_event_, ev);
+ if (m->is_mus_type ("rest-event"))
+ {
+ rest_event_ = m;
+ return true;
+ }
+ return false;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Rest_engraver,
/* doc */ "",
- /* create */ "Rest ",
+ /* create */ "Rest Dots",
/* accept */ "rest-event",
/* read */ "middleCPosition",
/* write */ "");
int line_count = Staff_symbol_referencer::line_count (me);
Real ss = Staff_symbol_referencer::staff_space (me);
- bool position_override = scm_is_number (me->get_property ("staff-position"));
Real amount = robust_scm2double (me->get_property ("staff-position"), 0)
* 0.5 * ss;
+ bool position_override = amount;
if (line_count % 2)
{
+++ /dev/null
-/*
- scale.cc -- implement Scale
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
-
-*/
-
-#include "pitch.hh"
-
-#include "ly-smobs.icc"
-
-LY_DEFINE (ly_make_scale, "ly:make-scale",
- 1, 0, 0, (SCM steps),
- "Create a scale. Takes a vector of ints as argument")
-{
- bool type_ok = scm_is_vector (steps);
-
- vector<int> semitones;
- if (type_ok)
- {
- int len = scm_c_vector_length (steps);
- for (int i = 0 ; i < len; i++)
- {
- SCM step = scm_c_vector_ref (steps, i);
- type_ok = type_ok && scm_is_integer (step);
- if (type_ok)
- semitones.push_back (scm_to_int (step));
- }
- }
-
-
- SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of int");
-
-
- Scale *s = new Scale;
- s->step_semitones_ = semitones;
-
- SCM retval = s->self_scm ();
-
- s->unprotect ();
-
- return retval;
-}
-
-LY_DEFINE (ly_default_scale, "ly:default-scale",
- 0, 0, 0, (),
- "Get the global default scale.")
-{
- return default_global_scale
- ? SCM_BOOL_F
- : default_global_scale->self_scm ();
-}
-
-
-Scale * default_global_scale = 0;
-
-LY_DEFINE (ly_set_default_scale, "ly:set-default-scale",
- 1, 0, 0, (SCM scale),
- "Set the global default scale.")
-{
- Scale *s = Scale::unsmob (scale);
- SCM_ASSERT_TYPE (s, scale, SCM_ARG1, __FUNCTION__, "scale");
-
- if (default_global_scale)
- default_global_scale->unprotect ();
- default_global_scale = s;
- s->protect ();
-
- return SCM_UNSPECIFIED;
-}
-
-
-int
-Scale::print_smob (SCM x, SCM port, scm_print_state *)
-{
- (void) x;
-
- scm_puts ("#<Scale>", port);
- return 1;
-}
-
-
-SCM
-Scale::mark_smob (SCM x)
-{
- (void) x;
- return SCM_UNSPECIFIED;
-}
-
-Scale::Scale ()
-{
- smobify_self ();
-}
-
-Scale::Scale (Scale const &src)
-{
- step_semitones_ = src.step_semitones_;
- smobify_self ();
-}
-
-
-Scale::~Scale ()
-{
-}
-
-IMPLEMENT_SMOBS(Scale);
-IMPLEMENT_DEFAULT_EQUAL_P(Scale);
--- /dev/null
+/*
+ score-context.cc -- implement Score_context
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "score-context.hh"
+
+#include "score-translator.hh"
+
+void
+Score_context::prepare (Moment w)
+{
+ Translator_group *t = implementation ();
+ Score_translator *s = dynamic_cast<Score_translator *> (t);
+
+ s->prepare (w);
+}
+
+void
+Score_context::finish ()
+{
+ Translator_group *t = implementation ();
+ Score_translator *s = dynamic_cast<Score_translator *> (t);
+
+ s->finish ();
+}
+
+void
+Score_context::one_time_step ()
+{
+ Translator_group *t = implementation ();
+ Score_translator *s = dynamic_cast<Score_translator *> (t);
+ s->one_time_step ();
+}
+
+SCM
+Score_context::get_output ()
+{
+ Translator_group *t = implementation ();
+ Score_translator *s = dynamic_cast<Score_translator *> (t);
+ return s->get_output ();
+}
+
+Score_context::Score_context (Object_key const *key)
+ : Context (key)
+{
+}
#include "all-font-metrics.hh"
#include "axis-group-interface.hh"
#include "context-def.hh"
-#include "dispatcher.hh"
#include "global-context.hh"
#include "international.hh"
#include "main.hh"
#include "paper-column-engraver.hh"
#include "paper-column.hh"
#include "paper-score.hh"
-#include "stream-event.hh"
#include "system.hh"
#include "warn.hh"
{
if (pscore_)
scm_gc_mark (pscore_->self_scm ());
+ Score_translator::derived_mark ();
Engraver_group::derived_mark ();
}
-IMPLEMENT_LISTENER (Score_engraver, prepare);
void
-Score_engraver::prepare (SCM)
+Score_engraver::prepare (Moment m)
{
+ (void) m;
+
precomputed_recurse_over_translators (context (), START_TRANSLATION_TIMESTEP, DOWN);
}
-IMPLEMENT_LISTENER (Score_engraver, finish);
void
-Score_engraver::finish (SCM)
+Score_engraver::finish ()
{
recurse_over_translators (context (), &Translator::finalize,
&Translator_group::finalize,
pscore_ = new Paper_score (dynamic_cast<Output_def *> (context ()->get_output_def ()));
pscore_->unprotect ();
- context ()->set_property ("output", pscore_->self_scm ());
SCM props = updated_grob_properties (context (), ly_symbol2scm ("System"));
Engraver_group::initialize ();
}
-void
-Score_engraver::connect_to_context (Context *c)
-{
- Engraver_group::connect_to_context (c);
-
- Dispatcher *d = c->get_global_context ()->event_source ();
- d->add_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep"));
- d->add_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare"));
- d->add_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish"));
-}
-
-void
-Score_engraver::disconnect_from_context ()
-{
- Dispatcher *d = context ()->get_global_context ()->event_source ();
- d->remove_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep"));
- d->remove_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare"));
- d->remove_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish"));
-
- Engraver_group::disconnect_from_context ();
-}
-
void
Score_engraver::finalize ()
{
- Engraver_group::finalize ();
+ Score_translator::finalize ();
typeset_all ();
}
-IMPLEMENT_LISTENER(Score_engraver, one_time_step);
void
-Score_engraver::one_time_step (SCM)
+Score_engraver::one_time_step ()
{
if (!to_boolean (context ()->get_property ("skipTypesetting")))
{
elems_.clear ();
}
+SCM
+Score_engraver::get_output ()
+{
+ Music_output *o = pscore_;
+ return o->self_scm ();
+}
+
+bool
+Score_engraver::try_music (Music *m)
+{
+ if (Engraver_group::try_music (m))
+ return true;
+
+ return false;
+}
+
ADD_TRANSLATOR_GROUP (Score_engraver,
/* doc */ "Top level engraver. Takes care of generating columns and the complete system (ie. System) "
"\n\n "
"System ",
/* accept */
- "",
+ "break-event",
/* read */
"currentMusicalColumn "
(c) 1996--2006 Jan Nieuwenhuizen <janneke@gnu.org>
*/
+#include "moment.hh"
#include "score-performer.hh"
#include "audio-column.hh"
#include "audio-item.hh"
-#include "context-def.hh"
-#include "context.hh"
-#include "dispatcher.hh"
-#include "global-context.hh"
#include "performance.hh"
#include "midi-stream.hh"
-#include "moment.hh"
-#include "output-def.hh"
#include "string-convert.hh"
#include "warn.hh"
-#include "audio-staff.hh"
-#include "audio-item.hh"
+#include "context-def.hh"
+#include "output-def.hh"
+#include "context.hh"
ADD_TRANSLATOR_GROUP (Score_performer,
/* doc */ "",
{
performance_ = 0;
skipping_ = false;
- audio_column_ = 0;
}
Score_performer::~Score_performer ()
}
void
-Score_performer::announce_element (Audio_element_info info)
-{
- announce_infos_.push_back (info);
- if (Audio_staff *s = dynamic_cast<Audio_staff*> (info.elem_))
- {
- performance_->audio_staffs_.push_back (s);
- }
-
- performance_->add_element (info.elem_);
-}
-
-void
-Score_performer::acknowledge_audio_elements ()
-{
- for (vsize i = 0; i < announce_infos_.size (); i++)
- {
- if (Audio_item *ai = dynamic_cast<Audio_item *> (announce_infos_[i].elem_))
- audio_column_->add_audio_item (ai);
- }
- Performer_group::acknowledge_audio_elements ();
-}
-
-
-void
-Score_performer::connect_to_context (Context *c)
+Score_performer::play_element (Audio_element *p)
{
- Performer_group::connect_to_context (c);
-
- Dispatcher *d = c->get_global_context ()->event_source ();
- d->add_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep"));
- d->add_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare"));
- d->add_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish"));
+ if (Audio_item *i = dynamic_cast<Audio_item *> (p))
+ audio_column_->add_audio_item (i);
+ performance_->add_element (p);
}
void
-Score_performer::disconnect_from_context ()
+Score_performer::announce_element (Audio_element_info info)
{
- Dispatcher *d = context ()->get_global_context ()->event_source ();
- d->remove_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep"));
- d->remove_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare"));
- d->remove_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish"));
-
- Performer_group::disconnect_from_context ();
+ announce_infos_.push_back (info);
}
-IMPLEMENT_LISTENER (Score_performer, prepare);
void
-Score_performer::prepare (SCM sev)
+Score_performer::prepare (Moment m)
{
- Stream_event *ev = unsmob_stream_event (sev);
- SCM sm = ev->get_property ("moment");
- Moment *m = unsmob_moment (sm);
- audio_column_ = new Audio_column (*m);
+ audio_column_ = new Audio_column (m);
+ play_element (audio_column_);
precomputed_recurse_over_translators (context (), START_TRANSLATION_TIMESTEP, UP);
}
-IMPLEMENT_LISTENER (Score_performer, finish);
void
-Score_performer::finish (SCM)
+Score_performer::finish ()
{
recurse_over_translators (context (),
&Translator::finalize,
UP);
}
-IMPLEMENT_LISTENER (Score_performer, one_time_step);
void
-Score_performer::one_time_step (SCM)
+Score_performer::one_time_step ()
{
if (to_boolean (context ()->get_property ("skipTypesetting")))
{
precomputed_recurse_over_translators (context (), STOP_TRANSLATION_TIMESTEP, UP);
}
+int
+Score_performer::get_tempo () const
+{
+ return ::get_tempo (performance_->midi_, Moment (Rational (1, 4)));
+}
+
+SCM
+Score_performer::get_output ()
+{
+ Music_output *o = performance_;
+ performance_ = 0;
+ return o->self_scm ();
+}
+
void
Score_performer::derived_mark () const
{
if (performance_)
scm_gc_mark (performance_->self_scm ());
+ Score_translator::derived_mark ();
Performer_group::derived_mark ();
}
{
performance_ = new Performance;
performance_->unprotect ();
- context ()->set_property ("output", performance_->self_scm ());
performance_->midi_ = context ()->get_output_def ();
-
Translator_group::initialize ();
}
-
-
--- /dev/null
+/*
+ score-translator.cc -- implement Score_translator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "score-translator.hh"
+#include "moment.hh"
+
+void
+Score_translator::prepare (Moment)
+{
+}
+
+SCM
+Score_translator::get_output ()
+{
+ return SCM_EOL;
+}
+
+void
+Score_translator::finish ()
+{
+}
+
+void
+Score_translator::one_time_step ()
+{
+}
#include "ly-smobs.icc"
-Input *
-Score::origin () const
-{
- return unsmob_input (input_location_);
-}
-
-
Score::Score ()
+ : Input ()
{
header_ = SCM_EOL;
music_ = SCM_EOL;
error_found_ = false;
- input_location_ = SCM_EOL;
smobify_self ();
- input_location_ = make_input (Input ());
}
Score::~Score ()
scm_gc_mark (sc->header_);
for (vsize i = sc->defs_.size (); i--;)
scm_gc_mark (sc->defs_[i]->self_scm ());
-
- scm_gc_mark (sc->input_location_);
return sc->music_;
}
}
Score::Score (Score const &s)
+ : Input (s)
{
header_ = SCM_EOL;
music_ = SCM_EOL;
error_found_ = s.error_found_;
- input_location_ = SCM_EOL;
smobify_self ();
- input_location_ = make_input (*s.origin ());
Music *m = unsmob_music (s.music_);
if (m)
#include "slur.hh"
#include "staff-symbol-referencer.hh"
#include "stem.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
struct Script_tuple
{
- Stream_event *event_;
+ Music *event_;
Grob *script_;
Script_tuple ()
{
class Script_engraver : public Engraver
{
vector<Script_tuple> scripts_;
+ Spanner *slur_;
protected:
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (articulation);
+ DECLARE_ACKNOWLEDGER (slur);
DECLARE_ACKNOWLEDGER (rhythmic_head);
DECLARE_ACKNOWLEDGER (stem);
DECLARE_ACKNOWLEDGER (stem_tremolo);
Script_engraver::Script_engraver ()
{
+ slur_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Script_engraver, articulation);
-void
-Script_engraver::listen_articulation (Stream_event *ev)
+bool
+Script_engraver::try_music (Music *m)
{
- /* Discard double articulations for part-combining. */
- int script_count = scripts_.size ();
- for (int i = 0; i < script_count; i++)
- if (ly_is_equal (scripts_[i].event_
- ->get_property ("articulation-type"),
- ev->get_property ("articulation-type")))
- return;
-
- Script_tuple t;
- t.event_ = ev;
- scripts_.push_back (t);
+ if (m->is_mus_type ("articulation-event"))
+ {
+ /* Discard double articulations for part-combining. */
+ int script_count = scripts_.size ();
+ for (int i = 0; i < script_count; i++)
+ if (ly_is_equal (scripts_[i].event_
+ ->get_property ("articulation-type"),
+ m->get_property ("articulation-type")))
+ return true;
+
+ Script_tuple t;
+ t.event_ = m;
+ scripts_.push_back (t);
+ return true;
+ }
+ return false;
}
void
{
SCM entry = scm_assoc (sym, alist);
if (scm_is_pair (entry))
- g->set_property (sym, scm_cdr (entry));
+ g->internal_set_property (sym, scm_cdr (entry));
}
}
could be saved by tacking the props onto the Script grob (i.e. make
ScriptStaccato , ScriptMarcato, etc. ).
*/
-void
-make_script_from_event (Grob *p, Context *tg,
- SCM art_type, int index)
+void make_script_from_event (Grob *p, Context *tg,
+ SCM art_type, int index)
{
SCM alist = tg->get_property ("scriptDefinitions");
SCM art = scm_assoc (art_type, alist);
SCM preset = p->get_property_data (sym);
if (val == SCM_EOL
|| scm_call_1 (type, preset) == SCM_BOOL_F)
- p->set_property (sym, val);
+ p->internal_set_property (sym, val);
}
if (!priority_found)
{
for (vsize i = 0; i < scripts_.size (); i++)
{
- Stream_event *ev = scripts_[i].event_;
+ Music *music = scripts_[i].event_;
- Grob *p = make_item ("Script", ev->self_scm ());
+ Grob *p = make_item ("Script", music->self_scm ());
make_script_from_event (p, context (),
- ev->get_property ("articulation-type"),
+ music->get_property ("articulation-type"),
i);
scripts_[i].script_ = p;
- SCM force_dir = ev->get_property ("direction");
+ SCM force_dir = music->get_property ("direction");
if (is_direction (force_dir) && to_dir (force_dir))
p->set_property ("direction", force_dir);
}
void
Script_engraver::acknowledge_rhythmic_head (Grob_info info)
{
- if (info.event_cause ())
+ if (info.music_cause ())
{
for (vsize i = 0; i < scripts_.size (); i++)
{
}
}
+void
+Script_engraver::acknowledge_slur (Grob_info info)
+{
+ slur_ = info.spanner ();
+}
+
void
Script_engraver::stop_translation_timestep ()
{
scripts_.clear ();
}
+#include "translator.icc"
+
+ADD_ACKNOWLEDGER (Script_engraver, slur);
ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head);
ADD_ACKNOWLEDGER (Script_engraver, stem);
ADD_ACKNOWLEDGER (Script_engraver, note_column);
extract_grob_set (me, "ties", lv_ro_ties);
vector<Grob*> lv_ties (lv_ro_ties);
- vector_sort (lv_ties, Semi_tie::less);
+ vector_sort (lv_ties, &Semi_tie::compare);
Ties_configuration ties_config;
return (int) rint (Staff_symbol_referencer::get_position (h));
}
-bool
-Semi_tie::less (Grob *const &s1,
- Grob *const &s2)
+int
+Semi_tie::compare (Grob *const &s1,
+ Grob *const &s2)
{
- return get_position (s1) < get_position (s2);
+ return sign (get_position (s1) - get_position (s2));
}
SCM
Sequential_iterator::get_music_list () const
{
- Music *m = get_music ();
- SCM proc = m->get_property ("elements-callback");
- if (scm_procedure_p (proc))
- return scm_call_1 (proc, m->self_scm ());
- else
- return SCM_EOL;
+ return SCM_EOL;
}
void
in that chunk should be in len.grace_part_
*/
- last_mom_ = here_mom_;
+ last_mom_ = here_mom_;;
here_mom_ += len;
}
--- /dev/null
+/*
+ sequential-music-iterator.cc -- implement Sequential_music_iterator
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "context.hh"
+#include "sequential-music-iterator.hh"
+#include "music.hh"
+#include "warn.hh"
+
+IMPLEMENT_CTOR_CALLBACK (Sequential_music_iterator);
+
+SCM
+Sequential_music_iterator::get_music_list ()const
+{
+ return get_music ()->get_property ("elements");
+}
}
/* Put the element next to the support, optionally taking in
- account the extent of the support.
-
- Does not take into account the extent of ME.
-*/
+ account the extent of the support. */
SCM
-Side_position_interface::general_side_position (Grob *me, Axis a, bool use_extents,
- bool include_my_extent,
- bool pure, int start, int end,
- Real *current_offset)
+Side_position_interface::general_side_position (Grob *me, Axis a, bool use_extents)
{
Real ss = Staff_symbol_referencer::staff_space (me);
if (include_staff)
{
common = staff_symbol->common_refpoint (common, Y_AXIS);
- staff_extents = staff_symbol->maybe_pure_extent (common, Y_AXIS, pure, start, end);
+ staff_extents = staff_symbol->extent (common, Y_AXIS);
if (include_staff)
dim.unite (staff_extents);
Grob *e = support[i];
if (e)
if (use_extents)
- dim.unite (e->maybe_pure_extent (common, a, pure, start, end));
+ dim.unite (e->extent (common, a));
else
{
- Real x = e->maybe_pure_coordinate (common, a, pure, start, end);
+ Real x = e->relative_coordinate (common, a);
dim.unite (Interval (x, x));
}
}
Direction dir = get_grob_direction (me);
- Real off = me->get_parent (a)->maybe_pure_coordinate (common, a, pure, start, end);
+ Real off = me->get_parent (a)->relative_coordinate (common, a);
Real minimum_space = ss * robust_scm2double (me->get_property ("minimum-space"), -1);
Real total_off = dim.linear_combination (dir) - off;
&& dir
&& total_off * dir < minimum_space)
total_off = minimum_space * dir;
-
- if (include_my_extent)
- {
- Interval iv = me->maybe_pure_extent (me, a, pure, start, end);
- if (!iv.is_empty ())
- {
- if (!dir)
- {
- programming_error ("direction unknown, but aligned-side wanted");
- dir = DOWN;
- }
- total_off += -iv[-dir];
- }
- }
-
- if (current_offset)
- total_off = dir * max (dir * total_off,
- dir * (*current_offset));
-
/* FIXME: 1000 should relate to paper size. */
if (fabs (total_off) > 1000)
MAKE_SCHEME_CALLBACK (Side_position_interface, y_aligned_on_support_refpoints, 1);
+
SCM
Side_position_interface::y_aligned_on_support_refpoints (SCM smob)
{
- return general_side_position (unsmob_grob (smob), Y_AXIS, false, false, false, 0, 0, 0);
+ return general_side_position (unsmob_grob (smob), Y_AXIS, false);
}
-MAKE_SCHEME_CALLBACK (Side_position_interface, pure_y_aligned_on_support_refpoints, 3);
-SCM
-Side_position_interface::pure_y_aligned_on_support_refpoints (SCM smob, SCM start, SCM end)
-{
- return general_side_position (unsmob_grob (smob), Y_AXIS, false, false,
- true, scm_to_int (start), scm_to_int (end), 0);
-}
/*
Position next to support, taking into account my own dimensions and padding.
*/
-SCM
-axis_aligned_side_helper (SCM smob, Axis a, bool pure, int start, int end, SCM current_off_scm)
-{
- Real r;
- Real *current_off_ptr = 0;
- if (scm_is_number (current_off_scm))
- {
- r = scm_to_double (current_off_scm);
- current_off_ptr = &r;
- }
-
- return Side_position_interface::aligned_side (unsmob_grob (smob), a, pure, start, end, current_off_ptr);
-}
-
-MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Side_position_interface, x_aligned_side, 2, 1);
+MAKE_SCHEME_CALLBACK (Side_position_interface, x_aligned_side, 1);
SCM
-Side_position_interface::x_aligned_side (SCM smob, SCM current_off)
+Side_position_interface::x_aligned_side (SCM smob)
{
- return axis_aligned_side_helper (smob, X_AXIS, false, 0, 0, current_off);
+ return aligned_side (unsmob_grob (smob), X_AXIS);
}
-MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Side_position_interface, y_aligned_side, 2, 1);
+MAKE_SCHEME_CALLBACK (Side_position_interface, y_aligned_side, 1);
SCM
-Side_position_interface::y_aligned_side (SCM smob, SCM current_off)
+Side_position_interface::y_aligned_side (SCM smob)
{
- return axis_aligned_side_helper (smob, Y_AXIS, false, 0, 0, current_off);
+ return aligned_side (unsmob_grob (smob), Y_AXIS);
}
-MAKE_SCHEME_CALLBACK (Side_position_interface, pure_y_aligned_side, 3);
SCM
-Side_position_interface::pure_y_aligned_side (SCM smob, SCM start, SCM end)
-{
- return aligned_side (unsmob_grob (smob), Y_AXIS, true, scm_to_int (start), scm_to_int (end), 0);
-}
-
-SCM
-Side_position_interface::aligned_side (Grob *me, Axis a, bool pure, int start, int end,
- Real *current_off)
+Side_position_interface::aligned_side (Grob *me, Axis a)
{
Direction dir = get_grob_direction (me);
- Real o = scm_to_double (general_side_position (me, a, true, true, pure, start, end, current_off));
+ Real o = scm_to_double (general_side_position (me, a, true));
+ Interval iv = me->extent (me, a);
+
+ if (!iv.is_empty ())
+ {
+ if (!dir)
+ {
+ programming_error ("direction unknown, but aligned-side wanted");
+ dir = DOWN;
+ }
+ o += -iv[-dir];
+ }
/*
Maintain a minimum distance to the staff. This is similar to side
if (to_boolean (me->get_property ("quantize-position")))
{
Grob *common = me->common_refpoint (staff, Y_AXIS);
- Real my_off = me->get_parent (Y_AXIS)->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
- Real staff_off = staff->maybe_pure_coordinate (common, Y_AXIS, pure, start, end);
+ Real my_off = me->relative_coordinate (common, Y_AXIS);
+ Real staff_off = staff->relative_coordinate (common, Y_AXIS);
Real ss = Staff_symbol::staff_space (staff);
Real position = 2 * (my_off + o - staff_off) / ss;
Real rounded = directed_round (position, dir);
}
else if (scm_is_number (me->get_property ("staff-padding")))
{
- Interval iv = me->maybe_pure_extent (me, a, pure, start, end);
-
Real padding
= Staff_symbol_referencer::staff_space (me)
* scm_to_double (me->get_property ("staff-padding"));
Grob *common = me->common_refpoint (staff, Y_AXIS);
- Interval staff_size = staff->maybe_pure_extent (common, Y_AXIS, pure, start, end);
+ Interval staff_size = staff->extent (common, Y_AXIS);
Real diff = dir*staff_size[dir] + padding - dir * (o + iv[-dir]);
o += dir * max (diff, 0.0);
}
if (!scm_is_number (me->get_property ("side-axis")))
{
me->set_property ("side-axis", scm_from_int (a));
- chain_offset_callback (me,
- (a==X_AXIS)
- ? x_aligned_side_proc
- : y_aligned_side_proc,
- a);
+ add_offset_callback (me,
+ (a==X_AXIS)
+ ? x_aligned_side_proc
+ : y_aligned_side_proc,
+ a);
}
}
Axis
}
else
// ugh. deviation from standard. Should print error?
- return evaluate_args (delayed_argument, scm_cdr (expr));
+ return evaluate_args (delayed_argument, scm_cdr (expr));
assert (false);
return SCM_EOL;
-ADD_SCM_INIT_FUNC (simple_closure, init_simple_closure);
+ADD_SCM_INIT_FUNC(simple_closure, init_simple_closure);
Simple_spacer::Simple_spacer ()
{
- line_len_ = 0.0;
- force_ = 0.0;
+ force_ = 0.;
fits_ = true;
- ragged_ = true;
}
Real
-Simple_spacer::force () const
+Simple_spacer::force ()
{
return force_;
}
bool
-Simple_spacer::fits () const
+Simple_spacer::fits ()
{
return fits_;
}
}
Real
-Simple_spacer::configuration_length (Real force) const
+Simple_spacer::configuration_length () const
{
Real l = 0.;
for (vsize i = 0; i < springs_.size (); i++)
- l += springs_[i].length (force);
+ l += springs_[i].length (force_);
return l;
}
void
Simple_spacer::solve (Real line_len, bool ragged)
{
- Real conf = configuration_length (force_);
+ Real conf = configuration_length ();
ragged_ = ragged;
line_len_ = line_len;
- if (conf < line_len_)
+ if (ragged)
+ {
+ force_ = 0;
+ fits_ = configuration_length () <= line_len_;
+ /* we need to calculate a force here to prevent a bunch of short lines */
+ if (fits_)
+ force_ = expand_line ();
+ }
+ else if (conf < line_len_)
force_ = expand_line ();
else if (conf > line_len_)
force_ = compress_line ();
-
- if (ragged && force_ < 0)
- fits_ = false;
}
Real
Simple_spacer::expand_line ()
{
double inv_hooke = 0;
- double cur_len = configuration_length (force_);
+ double cur_len = configuration_length ();
fits_ = true;
for (vsize i=0; i < springs_.size (); i++)
Simple_spacer::compress_line ()
{
double inv_hooke = 0;
- double cur_len = configuration_length (force_);
+ double cur_len = configuration_length ();
double cur_force = force_;
fits_ = true;
break;
double block_dist = (cur_force - sp.block_force_) * inv_hooke;
- if (cur_len - block_dist < line_len_)
- {
- cur_force += (line_len_ - cur_len) / inv_hooke;
- cur_len = line_len_;
-
- /*
- Paranoia check.
- */
- assert (fabs (configuration_length (cur_force) - cur_len) < 1e-6);
- return cur_force;
- }
-
+ if (cur_len - block_dist <= line_len_)
+ return cur_force + (line_len_ - cur_len) / inv_hooke;
cur_len -= block_dist;
inv_hooke -= sp.inverse_hooke_;
cur_force = sp.block_force_;
void
Simple_spacer::add_spring (Real ideal, Real inverse_hooke)
{
- Spring_description description;
+ Spring_description desc;
- description.ideal_ = ideal;
- description.inverse_hooke_ = inverse_hooke;
- if (!description.is_sane ())
+ desc.ideal_ = ideal;
+ desc.inverse_hooke_ = inverse_hooke;
+ if (!desc.is_sane ())
{
programming_error ("insane spring found, setting to unit");
- description.inverse_hooke_ = 1.0;
- description.ideal_ = 1.0;
+ desc.inverse_hooke_ = 1.0;
+ desc.ideal_ = 1.0;
}
- description.block_force_ = -description.ideal_ / description.inverse_hooke_;
+ desc.block_force_ = -desc.ideal_ / desc.inverse_hooke_;
// block at distance 0
- springs_.push_back (description);
+ springs_.push_back (desc);
}
vector<Real>
ret.push_back (0.);
for (vsize i = 0; i < springs_.size (); i++)
- ret.push_back (ret.back () + springs_[i].length (ragged_ && force_ > 0 ? 0.0 : force_));
+ ret.push_back (ret.back () + springs_[i].length (ragged_ ? 0.0 : force_));
return ret;
}
{
return (inverse_hooke_ >= 0)
&& ideal_ > 0
- && !isinf (ideal_) && !isnan (ideal_)
- && (inverse_hooke_ == 0.0 || fabs (inverse_hooke_) > 1e-8)
- ;
+ && !isinf (ideal_) && !isnan (ideal_);
}
Real
this closely.
*/
-struct Rod_description
+struct Rod_desc
{
vsize r_;
Real dist_;
- bool operator< (const Rod_description r)
+ bool operator< (const Rod_desc r)
{
return r_ < r.r_;
}
- Rod_description ()
- {
- r_ = 0;
- dist_ = 0;
- }
-
- Rod_description (vsize r, Real d)
+ Rod_desc () {}
+ Rod_desc (vsize r, Real d)
{
r_ = r;
dist_ = d;
}
};
-struct Column_description
+struct Column_desc
{
- vector<Rod_description> rods_;
- vector<Rod_description> end_rods_; /* use these if they end at the last column of the line */
+ vector<Rod_desc> rods_;
+ vector<Rod_desc> end_rods_; /* use these if they end at the last column of the line */
Real ideal_;
Real inverse_hooke_;
Real end_ideal_;
Real end_inverse_hooke_;
- SCM break_permission_;
Interval keep_inside_line_;
-
- Column_description ()
- {
- ideal_ = 0;
- inverse_hooke_ = 0;
- end_ideal_ = 0;
- end_inverse_hooke_ = 0;
- break_permission_ = SCM_EOL;
- }
};
+static int compare_paper_column_rank (Grob *const &a, Grob *const &b);
+
static bool
is_loose (Grob *g)
{
return 0;
}
+/* this only returns non-NULL if the line-ending column is the next
+ spaceable-or-breakable column */
+static Grob*
+next_line_ending_column (vector<Grob*> const &list, vsize starting)
+{
+ vsize i = starting + 1;
+ for (; i < list.size ()
+ && is_loose (list[i])
+ && !Paper_column::is_breakable (list[i]);
+ i++)
+ ;
+ return dynamic_cast<Item*> (list[i])->find_prebroken_piece (LEFT);
+}
+
static void
get_column_spring (Grob *this_col, Grob *next_col, Real *ideal, Real *inv_hooke)
{
*inv_hooke = (spring) ? spring->inverse_strength_ : 1.0;
}
-static Column_description
-get_column_description (vector<Grob*> const &cols, vsize col_index, bool line_starter)
+static Column_desc
+get_column_desc (vector<Grob*> const &cols, vsize col_index, bool line_starter)
{
Grob *col = cols[col_index];
if (line_starter)
col = maybe_find_prebroken_piece (col, RIGHT);
- Column_description description;
+ Column_desc desc;
Grob *next_col = next_spaceable_column (cols, col_index);
if (next_col)
- get_column_spring (col, next_col, &description.ideal_, &description.inverse_hooke_);
- Grob *end_col = dynamic_cast<Item*> (cols[col_index+1])->find_prebroken_piece (LEFT);
+ get_column_spring (col, next_col, &desc.ideal_, &desc.inverse_hooke_);
+ Grob *end_col = next_line_ending_column (cols, col_index);
if (end_col)
- get_column_spring (col, end_col, &description.end_ideal_, &description.end_inverse_hooke_);
+ get_column_spring (col, end_col, &desc.end_ideal_, &desc.end_inverse_hooke_);
for (SCM s = Spaceable_grob::get_minimum_distances (col);
scm_is_pair (s); s = scm_cdr (s))
{
Grob *other = unsmob_grob (scm_caar (s));
- vsize j = binary_search (cols, other, Paper_column::less_than, col_index);
+ vsize j = binary_search (cols, other, &compare_paper_column_rank, col_index);
if (j != VPOS)
{
if (cols[j] == other)
- description.rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s))));
+ desc.rods_.push_back (Rod_desc (j, scm_to_double (scm_cdar (s))));
else /* it must end at the LEFT prebroken_piece */
- description.end_rods_.push_back (Rod_description (j, scm_to_double (scm_cdar (s))));
+ desc.end_rods_.push_back (Rod_desc (j, scm_to_double (scm_cdar (s))));
}
}
if (!line_starter && to_boolean (col->get_property ("keep-inside-line")))
- description.keep_inside_line_ = col->extent (col, X_AXIS);
- description.break_permission_ = col->get_property ("line-break-permission");
- return description;
+ desc.keep_inside_line_ = col->extent (col, X_AXIS);
+ return desc;
}
vector<Real>
-get_line_forces (vector<Grob*> const &columns,
+get_line_forces (vector<Grob*> const &icols, vector<vsize> breaks,
Real line_len, Real indent, bool ragged)
{
- vector<vsize> breaks;
vector<Real> force;
- vector<Grob*> non_loose;
- vector<Column_description> cols;
- SCM force_break = ly_symbol2scm ("force");
-
- for (vsize i = 0; i < columns.size (); i++)
- if (!is_loose (columns[i]) || Paper_column::is_breakable (columns[i]))
- non_loose.push_back (columns[i]);
-
- breaks.clear ();
- breaks.push_back (0);
- cols.push_back (Column_description ());
- for (vsize i = 1; i < non_loose.size () - 1; i++)
- {
- if (Paper_column::is_breakable (non_loose[i]))
- breaks.push_back (cols.size ());
+ force.resize (breaks.size () * breaks.size ());
- cols.push_back (get_column_description (non_loose, i, false));
+ vector<Column_desc> cols;
+ vsize b = 1;
+ cols.push_back (Column_desc ());
+ for (vsize i = 1; i < icols.size () - 1; i++)
+ {
+ if (b < breaks.size () && breaks[b] == i)
+ {
+ breaks[b] = cols.size ();
+ b++;
+ }
+ if (!is_loose (icols[i]))
+ cols.push_back (get_column_desc (icols, i, false));
}
- breaks.push_back (cols.size ());
- force.resize (breaks.size () * breaks.size (), infinity_f);
+ breaks.back () = cols.size () - 1;
for (vsize b = 0; b < breaks.size () - 1; b++)
{
- cols[breaks[b]] = get_column_description (non_loose, breaks[b], true);
+ cols[breaks[b]] = get_column_desc (icols, breaks[b], true);
vsize st = breaks[b];
for (vsize c = b+1; c < breaks.size (); c++)
for (vsize i = breaks[b]; i < end - 1; i++)
spacer.add_spring (cols[i].ideal_, cols[i].inverse_hooke_);
- spacer.add_spring (cols[end-1].end_ideal_, cols[end-1].end_inverse_hooke_);
+ spacer.add_spring (cols[end-1].end_ideal_, cols[end-1].inverse_hooke_);
for (vsize i = breaks[b]; i < end; i++)
}
}
spacer.solve ((b == 0) ? line_len - indent : line_len, ragged);
-
- /* add a (convex) penalty for compression. We do this _only_ in get_line_forces,
- not get_line_configuration. This is temporary, for backwards compatibility;
- the old line/page-breaking stuff ignores page breaks when it calculates line
- breaks, so compression penalties can result in scores (eg. wtk-fugue) blowing
- up to too many pages. */
- Real f = spacer.force ();
- force[b * breaks.size () + c] = f - (f < 0 ? f*f*f*f*4 : 0);
-
- if (end < cols.size () && cols[end].break_permission_ == force_break)
- break;
+ force[b * breaks.size () + c] = spacer.force ();
if (!spacer.fits ())
{
- if (c == b + 1)
- force[b * breaks.size () + c] = -200000;
- else
- force[b * breaks.size () + c] = infinity_f;
+ force[b * breaks.size () + c] = infinity_f;
break;
}
}
}
Column_x_positions
-get_line_configuration (vector<Grob*> const &columns,
+get_line_configuration (vector<Grob*>const &columns,
Real line_len,
Real indent,
bool ragged)
{
- vector<Column_description> cols;
+ vector<Column_desc> cols;
Simple_spacer spacer;
Column_x_positions ret;
}
ret.cols_.push_back (dynamic_cast<Item*> (columns.back ())->find_prebroken_piece (LEFT));
+ cols.resize (ret.cols_.size () - 1);
+
/* since we've already put our line-ending column in the column list, we can ignore
- the end_XXX_ fields of our column_description */
- for (vsize i = 0; i < ret.cols_.size () - 1; i++)
+ the end_XXX_ fields of our column_desc */
+ for (vsize i = 0; i < cols.size (); i++)
{
- cols.push_back (get_column_description (ret.cols_, i, i == 0));
+ cols[i] = get_column_desc (ret.cols_, i, i == 0);
spacer.add_spring (cols[i].ideal_, cols[i].inverse_hooke_);
}
for (vsize i = 0; i < cols.size (); i++)
- {
- for (vsize r = 0; r < cols[i].rods_.size (); r++)
- spacer.add_rod (i, cols[i].rods_[r].r_, cols[i].rods_[r].dist_);
-
- if (!cols[i].keep_inside_line_.is_empty ())
- {
- spacer.add_rod (i, cols.size (), cols[i].keep_inside_line_[RIGHT]);
- spacer.add_rod (0, i, cols[i].keep_inside_line_[LEFT]);
- }
- }
+ for (vsize r = 0; r < cols[i].rods_.size (); r++)
+ spacer.add_rod (i, cols[i].rods_[r].r_, cols[i].rods_[r].dist_);
spacer.solve (line_len, ragged);
ret.force_ = spacer.force ();
return ret;
}
+static int
+compare_paper_column_rank (Grob *const &a,
+ Grob *const &b)
+{
+ return Paper_column::get_rank (a) - Paper_column::get_rank (b);
+}
number number as name */
SCM name = ly_symbol2scm (get_outlet ()->context_name ().c_str ());
- Context *c = (j && create_separate_contexts_)
+ Context *t = (j && create_separate_contexts_)
? get_outlet ()->find_create_context (name, to_string (j), SCM_EOL)
: get_outlet ();
- if (!c)
- c = get_outlet ();
+ if (!t)
+ t = get_outlet ();
- mi->init_context (mus, c);
+ mi->init_translator (mus, t);
mi->construct_children ();
if (mi->ok ())
source file of the GNU LilyPond music typesetter
- (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg
- <mandolaerik@gmail.com>
+ (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg <mandolaerik@gmail.com>
*/
-#include "bar-line.hh"
+#include "repeated-music.hh"
#include "global-context.hh"
-#include "international.hh"
-#include "item.hh"
+#include "warn.hh"
#include "misc.hh"
-#include "repeated-music.hh"
-#include "score-engraver.hh"
#include "spanner.hh"
-#include "stream-event.hh"
-#include "warn.hh"
-
-#include "translator.icc"
+#include "item.hh"
+#include "percent-repeat-iterator.hh"
+#include "bar-line.hh"
+#include "score-engraver.hh"
/**
This acknowledges repeated music with "percent" style. It typesets
public:
TRANSLATOR_DECLARATIONS (Slash_repeat_engraver);
protected:
- Stream_event *slash_;
+ Music *slash_;
protected:
- DECLARE_TRANSLATOR_LISTENER (percent);
+ virtual bool try_music (Music *);
void process_music ();
};
slash_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slash_repeat_engraver, percent);
-void
-Slash_repeat_engraver::listen_percent (Stream_event *ev)
+bool
+Slash_repeat_engraver::try_music (Music *m)
{
/*todo: separate events for percent and slash */
- Moment meas_length
- = robust_scm2moment (get_property ("measureLength"), Moment (0));
-
- if (get_event_length (ev) < meas_length)
- ASSIGN_EVENT_ONCE (slash_, ev);
+ if (m->is_mus_type ("percent-event"))
+ {
+ Moment meas_length
+ = robust_scm2moment (get_property ("measureLength"), Moment (0));
+
+ if (m->get_length () < meas_length)
+ slash_ = m;
+ else
+ return false;
- /*
- don't warn if nothing happens: this can happen if there are whole
- measure repeats.
- */
+ return true;
+ }
+
+ return false;
}
void
}
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Slash_repeat_engraver,
/* doc */ "Make beat repeats.",
/* create */ "RepeatSlash",
Slur_configuration::Slur_configuration ()
{
- tags_ = 0x0;
score_ = 0.0;
index_ = -1;
};
#include "note-column.hh"
#include "slur.hh"
#include "spanner.hh"
-#include "stream-event.hh"
#include "warn.hh"
-#include "translator.icc"
-
-
-/*
- NOTE NOTE NOTE
-
- This is largely similar to Phrasing_slur_engraver. Check if fixes
- apply there too.
-
- (on principle, engravers don't use inheritance for code sharing)
-
- */
-
/*
It is possible that a slur starts and ends on the same note. At
least, it is for phrasing slurs: a note can be both beginning and
*/
class Slur_engraver : public Engraver
{
- Drul_array<Stream_event *> events_;
- Stream_event *running_slur_start_;
+ Drul_array<Music *> events_;
+ Music *running_slur_start_;
vector<Grob*> slurs_;
vector<Grob*> end_slurs_;
void set_melisma (bool);
protected:
- DECLARE_TRANSLATOR_LISTENER (slur);
+ virtual bool try_music (Music *);
+
DECLARE_ACKNOWLEDGER (accidental);
DECLARE_ACKNOWLEDGER (dynamic_line_spanner);
DECLARE_ACKNOWLEDGER (fingering);
DECLARE_ACKNOWLEDGER (text_script);
DECLARE_ACKNOWLEDGER (tie);
DECLARE_ACKNOWLEDGER (tuplet_number);
-
void acknowledge_extra_object (Grob_info);
void stop_translation_timestep ();
- void process_music ();
-
virtual void finalize ();
-
+ void process_music ();
public:
TRANSLATOR_DECLARATIONS (Slur_engraver);
events_[START] = events_[STOP] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, slur);
-void
-Slur_engraver::listen_slur (Stream_event *ev)
-{
- Direction d = to_dir (ev->get_property ("span-direction"));
- if (d == START)
- ASSIGN_EVENT_ONCE (events_[START], ev);
- else if (d == STOP)
- ASSIGN_EVENT_ONCE (events_[STOP], ev);
- else ev->origin ()->warning (_ ("Invalid direction of slur-event"));
+bool
+Slur_engraver::try_music (Music *m)
+{
+ if (m->is_mus_type ("slur-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ if (d == START)
+ {
+ events_[START] = m;
+ return true;
+ }
+ else if (d == STOP)
+ {
+ events_[STOP] = m;
+ return true;
+ }
+ }
+ return false;
}
void
if (slurs_.size () == 0)
events_[STOP]->origin ()->warning (_ ("can't end slur"));
-
end_slurs_ = slurs_;
slurs_.clear ();
}
if (events_[START] && slurs_.empty ())
{
- Stream_event *ev = events_[START];
+ Music *ev = events_[START];
bool double_slurs = to_boolean (get_property ("doubleSlurs"));
void
Slur_engraver::stop_translation_timestep ()
{
- for (vsize i = 0; i < end_slurs_.size (); i++)
- announce_end_grob (end_slurs_[i], SCM_EOL);
end_slurs_.clear ();
events_[START] = events_[STOP] = 0;
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Slur_engraver, accidental);
ADD_ACKNOWLEDGER (Slur_engraver, dynamic_line_spanner);
ADD_ACKNOWLEDGER (Slur_engraver, fingering);
#include "audio-item.hh"
#include "audio-column.hh"
#include "global-context.hh"
-#include "stream-event.hh"
#include "warn.hh"
-
-#include "translator.icc"
+#include "music.hh"
/*
this is C&P from beam_performer.
TRANSLATOR_DECLARATIONS (Slur_performer);
protected:
+ virtual bool try_music (Music *ev);
void start_translation_timestep ();
void process_music ();
void set_melisma (bool);
-
- DECLARE_TRANSLATOR_LISTENER (slur);
private:
- Stream_event *start_ev_;
- Stream_event *now_stop_ev_;
+ Music *start_ev_;
+ Music *now_stop_ev_;
bool slur_;
};
now_stop_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Slur_performer, slur);
-void
-Slur_performer::listen_slur (Stream_event *ev)
+bool
+Slur_performer::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
+ if (m->is_mus_type ("slur-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
- if (d == START)
- start_ev_ = ev;
- else if (d == STOP)
- now_stop_ev_ = ev;
+ if (d == START)
+ start_ev_ = m;
+ else if (d == STOP)
+ now_stop_ev_ = m;
+ return true;
+ }
+ return false;
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Slur_performer,
"", "",
"slur-event",
"", "");
+
bool debug_slurs = to_boolean (slur_->layout ()
->lookup_variable (ly_symbol2scm ("debug-slur-scoring")));
SCM inspect_quants = slur_->get_property ("inspect-quants");
- SCM inspect_index = slur_->get_property ("inspect-index");
if (debug_slurs
- && scm_is_integer (inspect_index))
- {
- opt_idx = scm_to_int (inspect_index);
- configurations_[opt_idx]->calculate_score (*this);
- opt = configurations_[opt_idx]->score ();
- }
- else if (debug_slurs
- && scm_is_pair (inspect_quants))
+ && scm_is_pair (inspect_quants))
{
opt_idx = get_closest_index (inspect_quants);
configurations_[opt_idx]->calculate_score (*this);
}
else
{
+ programming_error ("No optimal slur found. Guessing 0.");
total = "no sol?";
}
}
#endif
- if (opt_idx < 0)
- {
- opt_idx = 0;
- programming_error ("No optimal slur found. Guessing 0.");
- }
-
return configurations_[opt_idx]->curve_;
}
return scm_from_int (d);
}
-MAKE_SCHEME_CALLBACK (Slur, pure_height, 3);
-SCM
-Slur::pure_height (SCM smob, SCM start_scm, SCM end_scm)
-{
- Grob *me = unsmob_grob (smob);
- int start = scm_to_int (start_scm);
- int end = scm_to_int (end_scm);
- Real height = robust_scm2double (me->get_property ("height-limit"), 2.0);
-
- extract_grob_set (me, "note-columns", encompasses);
- Interval ret;
-
- Grob *parent = me->get_parent (Y_AXIS);
- if (common_refpoint_of_array (encompasses, me, Y_AXIS) != parent)
- /* this could happen if, for example, we are a cross-staff slur.
- in this case, we want to be ignored */
- return ly_interval2scm (Interval ());
-
- for (vsize i = 0; i < encompasses.size (); i++)
- {
- Interval d = encompasses[i]->pure_height (parent, start, end);
- if (!d.is_empty ())
- ret.unite (d);
- }
-
- ret.widen (height * 0.5);
- return ly_interval2scm (ret);
-}
-
MAKE_SCHEME_CALLBACK (Slur, height, 1);
SCM
Slur::height (SCM smob)
{
Bezier b;
int i = 0;
- for (SCM s = me->get_property ("control-points"); scm_is_pair (s);
+ for (SCM s = me->get_property ("control-points"); s != SCM_EOL;
s = scm_cdr (s))
b.control_[i++] = ly_scm2offset (scm_car (s));
}
-MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Slur, outside_slur_callback, 2, 1);
+MAKE_SCHEME_CALLBACK (Slur, outside_slur_callback, 2);
SCM
Slur::outside_slur_callback (SCM grob, SCM offset_scm)
{
Interval yext = robust_relative_extent (script, cy, Y_AXIS);
Interval xext = robust_relative_extent (script, cx, X_AXIS);
- Real offset = robust_scm2double (offset_scm, 0);
- yext.translate (offset);
+ yext.translate (robust_scm2double (offset_scm, 0));
+
/* FIXME: slur property, script property? */
Real slur_padding = robust_scm2double (script->get_property ("slur-padding"),
avoidance_offset = dir * (max (dir * avoidance_offset,
dir * (ys[k] - yext[-dir] + dir * slur_padding)));
- return scm_from_double (offset + avoidance_offset);
+ return scm_from_double (scm_to_double (offset_scm) + avoidance_offset);
}
/*
*/
void
Slur::auxiliary_acknowledge_extra_object (Grob_info info,
- vector<Grob*> &slurs,
- vector<Grob*> &end_slurs)
+ vector<Grob*>& slurs, vector<Grob*>& end_slurs)
{
if (slurs.empty () && end_slurs.empty ())
return;
"eccentricity "
"encompass-objects "
"height-limit "
- "inspect-quants "
- "inspect-index "
"line-thickness "
"note-columns "
"positions "
"quant-score "
"ratio "
"thickness "
+
);
/*
The CDR contains the actual protected list.
*/
-static SCM smob_protection_list = SCM_EOL;
+static SCM smob_protection_list;
void
init_smob_protection ()
{
- smob_protection_list = scm_cons (SCM_BOOL_F, SCM_EOL);
- scm_gc_protect_object (smob_protection_list);
+ smob_protection_list = scm_cons (SCM_UNDEFINED, SCM_EOL);
+ scm_permanent_object (smob_protection_list);
}
ADD_SCM_INIT_FUNC (init_smob_protection, init_smob_protection);
LY_DEFINE(ly_smob_protects, "ly:smob-protects",
- 0, 0, 0, (),
+ 0,0,0, (),
"Return lily's internal smob protection list")
{
- return scm_is_pair (smob_protection_list)
- ? scm_cdr (smob_protection_list)
- : SCM_EOL;
+ return scm_cdr (smob_protection_list);
}
+
+
+
void
protect_smob (SCM smob, SCM *prot_cons)
{
-#if 0
SCM s = scm_cdr (smob_protection_list);
- while (scm_is_pair (s) && scm_car (s) == SCM_BOOL_F)
- {
- s = scm_cdr (s);
- }
+ while (scm_is_pair (s) && scm_car (s) == SCM_UNDEFINED)
+ s = scm_cdr (s);
+
SCM prot = scm_cons (smob, s);
scm_set_cdr_x (smob_protection_list,
prot);
*prot_cons = prot;
-#else
- (void) prot_cons;
- scm_gc_protect_object (smob);
-#endif
}
void
-unprotect_smob (SCM smob, SCM *prot_cons)
+unprotect_smob (SCM *prot_cons)
{
-#if 1
- (void) prot_cons;
- scm_gc_unprotect_object (smob);
-#else
SCM next = scm_cdr (*prot_cons);
if (next == SCM_EOL)
- scm_set_car_x (*prot_cons, SCM_BOOL_F);
+ scm_set_car_x (*prot_cons, SCM_UNDEFINED);
else
{
- scm_set_car_x (*prot_cons, SCM_BOOL_F);
+ scm_set_car_x (*prot_cons, SCM_UNDEFINED);
while (scm_is_pair (next)
- && scm_car (next) == SCM_BOOL_F)
+ && scm_car (next) == SCM_UNDEFINED)
next = scm_cdr (next);
}
*prot_cons = SCM_EOL;
-#endif
}
void
Source_file::load_stdin ()
{
- characters_.clear ();
+ length_ = 0;
+ chs_.clear ();
int c;
while ((c = fgetc (stdin)) != EOF)
- characters_.push_back (c);
+ chs_.push_back (c);
+
+ chs_.push_back (0);
+ length_ = chs_.size ();
+ contents_str0_ = &chs_[0];
}
-/*
- return contents of FILENAME. *Not 0-terminated!*
- */
-vector<char>
-gulp_file (string filename, int desired_size)
+char *
+gulp_file (string filename, int *filesize)
{
/* "b" must ensure to open literally, avoiding text (CR/LF)
conversions. */
if (!f)
{
warning (_f ("can't open file: `%s'", filename.c_str ()));
-
- vector<char> cxx_arr;
- return cxx_arr;
+ return 0;
}
fseek (f, 0, SEEK_END);
int real_size = ftell (f);
int read_count = real_size;
- if (desired_size > 0)
- read_count = min (read_count, desired_size);
+ if (*filesize >= 0)
+ read_count = min (read_count, *filesize);
rewind (f);
warning (_f ("expected to read %d characters, got %d", bytes_read,
read_count));
fclose (f);
- int filesize = bytes_read;
-
- vector<char> cxx_arr;
- cxx_arr.resize (filesize);
-
- copy (str, str + filesize, cxx_arr.begin ());
-
- delete[] str;
- return cxx_arr;
-}
-
-void
-Source_file::init ()
-{
- istream_ = 0;
- line_offset_ = 0;
- str_port_ = SCM_EOL;
- self_scm_ = SCM_EOL;
- smobify_self ();
+ *filesize = bytes_read;
+ return str;
}
Source_file::Source_file (string filename, string data)
{
- init ();
-
name_ = filename;
-
- characters_.resize (data.length ());
- copy (data.begin (), data.end (), characters_.begin ());
-
- characters_.push_back (0);
-
+ istream_ = 0;
+ length_ = data.length ();
+ contents_str0_ = string_copy (data);
+ pos_str0_ = c_str ();
init_port ();
- for (vsize i = 0; i < characters_.size (); i++)
- if (characters_[i] == '\n')
- newline_locations_.push_back (&characters_[0] + i);
+ for (int i = 0; i < length_; i++)
+ if (contents_str0_[i] == '\n')
+ newline_locations_.push_back (contents_str0_ + i);
}
Source_file::Source_file (string filename_string)
{
- init ();
-
name_ = filename_string;
+ istream_ = 0;
+ contents_str0_ = 0;
if (filename_string == "-")
load_stdin ();
else
{
- characters_ = gulp_file (filename_string, -1);
+ length_ = -1;
+ contents_str0_ = gulp_file (filename_string, &length_);
}
-
- characters_.push_back (0);
+
+ pos_str0_ = c_str ();
init_port ();
- for (vsize i = 0; i < characters_.size (); i++)
- if (characters_[i] == '\n')
- newline_locations_.push_back (&characters_[0] + i);
+ for (int i = 0; i < length_; i++)
+ if (contents_str0_[i] == '\n')
+ newline_locations_.push_back (contents_str0_ + i);
}
void
Source_file::init_port ()
{
- SCM str = scm_makfrom0str (c_str ());
+ SCM str = scm_makfrom0str (contents_str0_);
str_port_ = scm_mkstrport (SCM_INUM0, str, SCM_OPN | SCM_RDNG, __FUNCTION__);
scm_set_port_filename_x (str_port_, scm_makfrom0str (name_.c_str ()));
}
+int
+Source_file::tell () const
+{
+ return pos_str0_ - contents_str0_;
+}
istream *
Source_file::get_istream ()
Source_file::~Source_file ()
{
delete istream_;
+ istream_ = 0;
+ delete[] contents_str0_;
}
Slice
if (!newline_locations_.size ())
return 1;
- /* this will find the '\n' character at the end of our line */
- vsize lo = lower_bound (newline_locations_,
- pos_str0,
- less<char const*> ());
+ vsize lo = 0;
+ vsize hi = newline_locations_.size ();
- /* the return value will be indexed from 1 */
- return lo + 1 + line_offset_;
-}
+ if (newline_locations_[lo] > pos_str0)
+ return 1;
-void
-Source_file::set_line (char const *pos_str0, int line)
-{
- int current_line = get_line (pos_str0);
- line_offset_ += line - current_line;
+ if (newline_locations_[hi - 1] < pos_str0)
+ return hi;
- assert (line == get_line (pos_str0));
+ binary_search_bounds (newline_locations_,
+ (char const*&)pos_str0,
+ default_compare,
+ &lo, &hi);
+
+ if (*pos_str0 == '\n')
+ lo--;
+ return lo + 2;
}
int
Source_file::length () const
{
- return characters_.size ();
+ return length_;
}
char const *
Source_file::c_str () const
{
- return &characters_[0];
+ return contents_str0_;
}
-SCM
-Source_file::get_port () const
+void
+Source_file::set_pos (char const *pos_str0)
{
- return str_port_;
+ if (contains (pos_str0))
+ pos_str0_ = pos_str0;
+ else
+ error (quote_input (pos_str0) + "invalid pos");
}
-/****************************************************************/
-
-#include "ly-smobs.icc"
-
-IMPLEMENT_SMOBS(Source_file);
-IMPLEMENT_DEFAULT_EQUAL_P(Source_file);
-IMPLEMENT_TYPE_P(Source_file, "ly:source-file?");
-
-SCM
-Source_file::mark_smob (SCM smob)
+char const *
+Source_file::seek_str0 (int n)
{
- Source_file *sc = (Source_file *) SCM_CELL_WORD_1 (smob);
+ char const *new_str0 = c_str () + n;
+ if (n < 0)
+ new_str0 += length ();
+ if (contains (new_str0))
+ pos_str0_ = new_str0;
+ else
+ error (quote_input (new_str0) + "seek past eof");
- return sc->str_port_;
+ return pos_str0_;
}
-
-int
-Source_file::print_smob (SCM smob, SCM port, scm_print_state *)
+char const *
+Source_file::forward_str0 (int n)
{
- Source_file *sc = (Source_file *) SCM_CELL_WORD_1 (smob);
+ char const *old_pos = pos_str0_;
+ char const *new_str0 = pos_str0_ + n;
+ if (contains (new_str0))
+ pos_str0_ = new_str0;
+ else
+ error (quote_input (new_str0) + "forward past eof");
- scm_puts ("#<Source_file ", port);
- scm_puts (sc->name_.c_str (), port);
+ return old_pos;
+}
- /* Do not print properties, that is too much hassle. */
- scm_puts (" >", port);
- return 1;
+string
+Source_file::get_string (int n)
+{
+ string str = string ((char const *)forward_str0 (n), n);
+ return str;
}
+SCM
+Source_file::get_port () const
+{
+ return str_port_;
+}
Sources::~Sources ()
{
- for (vsize i = 0; i < sourcefiles_.size (); i++)
- {
- sourcefiles_[i]->unprotect ();
- }
+ junk_pointers (sourcefiles_);
}
Source_file *
#include "spacing-spanner.hh"
#include "moment.hh"
#include "paper-column.hh"
+#include "misc.hh"
#include "warn.hh"
/*
adding subtle adjustments to that. This file does the simple-minded
spacing routines.
*/
+
+/*
+ Get the measure wide ant for arithmetic spacing.
+*/
+Real
+Spacing_options::get_duration_space (Moment d,
+ bool *expand_only) const
+{
+ Real k = shortest_duration_space_;
+
+ if (d < global_shortest_)
+ {
+ /*
+ We don't space really short notes using the log of the
+ duration, since it would disproportionally stretches the long
+ notes in a piece. In stead, we use geometric spacing with constant 0.5
+ (i.e. linear.)
+
+ This should probably be tunable, to use other base numbers.
+
+ In Mozart hrn3 by EB., we have 8th note = 3.9 mm (total), 16th note =
+ 3.6 mm (total). head-width = 2.4, so we 1.2mm for 16th, 1.5
+ mm for 8th. (white space), suggesting that we use
+
+ (1.2 / 1.5)^{-log2(duration ratio)}
+
+
+ */
+ Rational ratio = d.main_part_ / global_shortest_;
+
+ return ((k - 1) + double (ratio)) * increment_;
+ }
+ else
+ {
+ /*
+ John S. Gourlay. ``Spacing a Line of Music, '' Technical
+ Report OSU-CISRC-10/87-TR35, Department of Computer and
+ Information Science, The Ohio State University, 1987.
+ */
+ Real log = log_2 (global_shortest_);
+ k -= log;
+ Rational compdur = d.main_part_ + d.grace_part_ / Rational (3);
+ *expand_only = false;
+
+ return (log_2 (compdur) + k) * increment_;
+ }
+}
+
/*
The one-size-fits all spacing. It doesn't take into account
different spacing wishes from one to the next column.
else
{
bool dummy;
- *space = *fixed + options->get_duration_space (dt.main_part_, &dummy);
+ *space = *fixed + options->get_duration_space (dt, &dummy);
}
}
}
Spacing_options const *options,
bool *expand_only)
{
- (void) me;
-
Moment shortest_playing_len = 0;
SCM s = lc->get_property ("shortest-playing-duration");
Real dist = 0.0;
if (delta_t.main_part_ && !lwhen.grace_part_)
{
- dist = options->get_duration_space (shortest_playing_len.main_part_,
+ dist = options->get_duration_space (shortest_playing_len,
expand_only);
dist *= double (delta_t.main_part_ / shortest_playing_len.main_part_);
}
available (namely the space for the global shortest note), and
multiply that by grace-space-factor
*/
- dist = options->get_duration_space (options->global_shortest_, expand_only) / 2.0;
- Grob *grace_spacing = unsmob_grob (lc->get_object ("grace-spacing"));
- if (grace_spacing)
- {
- Spacing_options grace_opts;
- grace_opts.init_from_grob (grace_spacing);
+ dist = options->get_duration_space (options->global_shortest_, expand_only);
- bool bla;
- dist = grace_opts.get_duration_space (delta_t.grace_part_, &bla);
- }
-
+ Real grace_fact
+ = robust_scm2double (me->get_property ("grace-space-factor"), 1);
+
+ dist *= grace_fact;
}
return dist;
}
+/****************************************************************/
+
+void
+Spacing_options::init_from_grob (Grob *me)
+{
+ increment_ = robust_scm2double (me->get_property ("spacing-increment"), 1);
+
+ packed_ = to_boolean (me->get_property ("packed-spacing"));
+ stretch_uniformly_ = to_boolean (me->get_property ("uniform-stretching"));
+ float_nonmusical_columns_
+ = to_boolean (me->get_property ("strict-note-spacing"));
+ shortest_duration_space_ = robust_scm2double (me->get_property ("shortest-duration-space"), 1);
+}
+
+void
+Spacing_options::init ()
+{
+ increment_ = 1.2;
+ packed_ = false;
+ stretch_uniformly_ = false;
+ float_nonmusical_columns_ = false;
+ shortest_duration_space_ = 2.0;
+
+ global_shortest_ = Rational (1, 8);
+}
static bool
is_loose_column (Grob *l, Grob *c, Grob *r, Spacing_options const *options)
{
- if ((options->float_nonmusical_columns_
- ||options->float_grace_columns_)
+ if (options->float_nonmusical_columns_
&& Paper_column::when_mom (c).grace_part_)
return true;
(c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
+#include "paper-column.hh"
#include "engraver.hh"
-#include "moment.hh"
+#include "pqueue.hh"
#include "note-spacing.hh"
-#include "paper-column.hh"
+#include "staff-spacing.hh"
#include "pointer-group-interface.hh"
-#include "pqueue.hh"
#include "spanner.hh"
-#include "staff-spacing.hh"
-#include "stream-event.hh"
#include "translator.icc"
static int time_compare (Rhythmic_tuple const &, Rhythmic_tuple const &);
};
-inline int
-compare (Rhythmic_tuple const &a, Rhythmic_tuple const &b)
-{
- return Rhythmic_tuple::time_compare (a, b);
-}
-
-int
-Rhythmic_tuple::time_compare (Rhythmic_tuple const &h1,
- Rhythmic_tuple const &h2)
-{
- return (h1.end_ - h2.end_).main_part_.sign ();
-}
-
-/****************************************************************/
-
+/*
+ TODO: allow starting & stopping of spacing regions.
+*/
/*
Acknowledge rhythmic elements, for initializing spacing fields in
the columns.
vector<Rhythmic_tuple> stopped_durations_;
Moment now_;
Spanner *spacing_;
- Stream_event *start_section_;
-
+
TRANSLATOR_DECLARATIONS (Spacing_engraver);
protected:
DECLARE_ACKNOWLEDGER (staff_spacing);
DECLARE_ACKNOWLEDGER (note_spacing);
DECLARE_ACKNOWLEDGER (rhythmic_head);
- DECLARE_TRANSLATOR_LISTENER (spacing_section);
void start_translation_timestep ();
void stop_translation_timestep ();
void process_music ();
-
virtual void finalize ();
-
- void start_spanner ();
- void stop_spanner ();
};
-Spacing_engraver::Spacing_engraver ()
+inline int
+compare (Rhythmic_tuple const &a, Rhythmic_tuple const &b)
{
- spacing_ = 0;
- start_section_ = 0;
+ return Rhythmic_tuple::time_compare (a, b);
}
-IMPLEMENT_TRANSLATOR_LISTENER (Spacing_engraver, spacing_section);
-void
-Spacing_engraver::listen_spacing_section (Stream_event *ev)
+int
+Rhythmic_tuple::time_compare (Rhythmic_tuple const &h1,
+ Rhythmic_tuple const &h2)
{
- ASSIGN_EVENT_ONCE (start_section_, ev);
+ return (h1.end_ - h2.end_).main_part_.sign ();
}
-void
-Spacing_engraver::process_music ()
+Spacing_engraver::Spacing_engraver ()
{
- if (start_section_ && spacing_)
- stop_spanner ();
-
- if (!spacing_)
- start_spanner ();
+ spacing_ = 0;
}
void
-Spacing_engraver::start_spanner ()
+Spacing_engraver::process_music ()
{
- assert (!spacing_);
-
-
- spacing_ = make_spanner ("SpacingSpanner", SCM_EOL);
- spacing_->set_bound (LEFT,
- unsmob_grob (get_property ("currentCommandColumn")));
+ if (!spacing_)
+ {
+ spacing_ = make_spanner ("SpacingSpanner", SCM_EOL);
+ spacing_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
+ }
}
void
Spacing_engraver::finalize ()
-{
- stop_spanner ();
-}
-
-void
-Spacing_engraver::stop_spanner ()
{
if (spacing_)
{
*/
if (!now_.grace_part_)
{
- Stream_event *r = i.event_cause ();
- if (r && r->in_event_class ("rhythmic-event"))
+ Music *r = i.music_cause ();
+ if (r && r->is_mus_type ("rhythmic-event"))
{
- Moment len = get_event_length (r);
+ Moment len = r->get_length ();
Rhythmic_tuple t (i, now_mom () + len);
now_durations_.push_back (t);
}
Paper_column *musical_column
= dynamic_cast<Paper_column *> (unsmob_grob (get_property ("currentMusicalColumn")));
-
- if (!spacing_)
- start_spanner ();
-
- musical_column->set_object ("spacing", spacing_->self_scm ());
- unsmob_grob (get_property ("currentCommandColumn"))
- ->set_object ("spacing", spacing_->self_scm ());
-
SCM proportional = get_property ("proportionalNotationDuration");
if (unsmob_moment (proportional))
{
shortest_playing.set_infinite (1);
for (vsize i = 0; i < playing_durations_.size (); i++)
{
- Stream_event *ev = playing_durations_[i].info_.event_cause ();
- if (ev)
+ Music *mus = playing_durations_[i].info_.music_cause ();
+ if (mus)
{
- Moment m = get_event_length (ev);
+ Moment m = mus->get_length ();
shortest_playing = min (shortest_playing, m);
}
}
for (vsize i = 0; i < now_durations_.size (); i++)
{
- Moment m = get_event_length (now_durations_[i].info_.event_cause ());
+ Moment m = now_durations_[i].info_.music_cause ()->get_length ();
if (m.to_bool ())
{
starter = min (starter, m);
musical_column->set_property ("shortest-starter-duration", st);
}
-
-
void
Spacing_engraver::start_translation_timestep ()
{
- start_section_ = 0;
-
now_ = now_mom ();
stopped_durations_.clear ();
-
while (playing_durations_.size () && playing_durations_.front ().end_ < now_)
playing_durations_.delmin ();
while (playing_durations_.size () && playing_durations_.front ().end_ == now_)
"bookkeeping of shortest starting and playing notes ",
/* create */ "SpacingSpanner",
- /* accept */
- "spacing-section-event ",
+ /* accept */ "",
/* read */
"currentMusicalColumn "
"currentCommandColumn "
#include "staff-spacing.hh"
#include "note-spacing.hh"
#include "spacing-spanner.hh"
-#include "warn.hh"
+
#include "moment.hh"
/* Find the loose columns in POSNS, and drape them around the columns
if (!loose_col_count)
return;
+ Real default_padding = 1.0;
for (int i = 0; i < loose_col_count; i++)
{
int divide_over = 1;
if (!right->get_system ())
right = right->find_prebroken_piece (LEFT);
- Grob *common = right->common_refpoint (left, X_AXIS);
-
clique.push_back (right);
- vector<Real> clique_spacing;
- clique_spacing.push_back (0.0);
- for (vsize j = 1; j < clique.size () - 1; j ++)
- {
- Grob *clique_col = clique[j];
+ Grob *common = right->common_refpoint (left, X_AXIS);
+ Item *finished_right_column = clique.back ();
- Paper_column *loose_col = dynamic_cast<Paper_column *> (clique[j]);
- Paper_column *next_col = dynamic_cast<Paper_column *> (clique[j + 1]);
+ for (vsize j = clique.size () - 2; j > 0; j--)
+ {
+ int count = 0;
+ Real total_space = 0.0;
+ Real total_fixed = 0.0;
- Grob *spacing = unsmob_grob (clique_col->get_object ("spacing"));
- if (Grob *grace_spacing = unsmob_grob (clique_col->get_object ("grace-spacing")))
+ extract_grob_set (col, "spacing-wishes", wishes);
+ for (vsize i = 0; i < wishes.size (); i++)
{
- spacing = grace_spacing;
+ Grob *spacing = wishes[i];
+ Real space = 0.0;
+ Real fixed = 0.0;
+
+ if (Staff_spacing::has_interface (spacing))
+ Staff_spacing::get_spacing_params (spacing, &space, &fixed);
+ else if (Note_spacing::has_interface (spacing))
+ {
+ Spacing_options options;
+ options.init ();
+
+ fixed = robust_relative_extent (col, col, X_AXIS)[RIGHT];
+
+ Moment dt = Paper_column::when_mom (right) - Paper_column::when_mom (col);
+ bool expand;
+ space = options.get_duration_space (dt, &expand);
+ Note_spacing::get_spacing (spacing, right, space, options.increment_,
+ &space, &fixed);
+ }
+ else
+ continue;
+
+ count++;
+
+ total_space += space;
+ total_fixed += fixed;
}
-
- Spacing_options options;
- if (spacing)
- options.init_from_grob (spacing);
- else
- programming_error ("Column without spacing object");
- bool expand_only = false;
- Real base_note_space = 0.0;
+ Real distance_to_next = 0.0;
+ Real right_point = 0.0;
+ if (count)
+ {
+ total_space /= count;
+ total_fixed /= count;
- if (Paper_column::is_musical (next_col)
- && Paper_column::is_musical (loose_col))
- base_note_space = Spacing_spanner::note_spacing (spacing, loose_col, next_col,
- &options, &expand_only);
+ distance_to_next = total_space;
+ right_point
+ = finished_right_column->relative_coordinate (common, X_AXIS);
+ }
else
{
- Real fixed, space;
-
- Spacing_spanner::standard_breakable_column_spacing (spacing,
- loose_col, next_col,
- &fixed, &space,
- &options);
-
- base_note_space = space;
+ Interval my_extent = robust_relative_extent (col, col, X_AXIS);
+ distance_to_next = my_extent[RIGHT] + default_padding;
+ right_point = robust_relative_extent (finished_right_column, common, X_AXIS)[LEFT];
}
- base_note_space = max (base_note_space,
- robust_relative_extent (loose_col, loose_col, X_AXIS)[RIGHT]
- - robust_relative_extent (next_col, next_col, X_AXIS)[LEFT]);
-
- clique_spacing.push_back (base_note_space);
- }
-
- Real default_padding = 1.0;
- clique_spacing.push_back (default_padding);
-
- Real right_point = robust_relative_extent (clique.back (), common, X_AXIS)[LEFT];
-
-
- Grob *finished_right_column = clique.back ();
-
- for (vsize j = clique.size () - 2; j > 0; j--)
- {
- Paper_column *clique_col = dynamic_cast<Paper_column *> (clique[j]);
-
- right_point = finished_right_column->relative_coordinate (common, X_AXIS);
-
- Real distance_to_next = clique_spacing[j];
-
Real my_offset = right_point - distance_to_next;
- clique_col->set_system (which);
- clique_col->translate_axis (my_offset - clique_col->relative_coordinate (common, X_AXIS), X_AXIS);
+ col->system_ = which;
+ col->translate_axis (my_offset - col->relative_coordinate (common, X_AXIS), X_AXIS);
- finished_right_column = clique_col;
+ finished_right_column = col;
}
-
}
}
+++ /dev/null
-/*
- spacing-options.cc -- implement Spacing_options
-
- source file of the GNU LilyPond music typesetter
-
- (c) 2006 Han-Wen Nienhuys <hanwen@lilypond.org>
-
-*/
-
-#include "spacing-spanner.hh"
-#include "grob.hh"
-#include "misc.hh"
-#include "moment.hh"
-
-void
-Spacing_options::init_from_grob (Grob *me)
-{
- increment_ = robust_scm2double (me->get_property ("spacing-increment"), 1);
-
- packed_ = to_boolean (me->get_property ("packed-spacing"));
- stretch_uniformly_ = to_boolean (me->get_property ("uniform-stretching"));
- float_nonmusical_columns_
- = to_boolean (me->get_property ("strict-note-spacing"));
- float_grace_columns_
- = to_boolean (me->get_property ("strict-grace-spacing"));
- shortest_duration_space_ = robust_scm2double (me->get_property ("shortest-duration-space"), 1);
-
-
- Moment shortest_dur = robust_scm2moment (me->get_property ("common-shortest-duration"),
- Moment (Rational (1,8), Rational (1,16)));
-
- if (shortest_dur.main_part_)
- global_shortest_ = shortest_dur.main_part_;
- else
- global_shortest_ = shortest_dur.grace_part_;
-
-}
-
-Spacing_options::Spacing_options ()
-{
- packed_ = false;
- stretch_uniformly_ = false;
- float_nonmusical_columns_ = false;
- float_grace_columns_ = false;
-
- shortest_duration_space_ = 2.0;
- increment_ = 1.2;
-
- global_shortest_ = Rational (1, 8);
-}
-
-
-
-/*
- Get the measure wide ant for arithmetic spacing.
-*/
-Real
-Spacing_options::get_duration_space (Rational d,
- bool *expand_only) const
-{
- Real k = shortest_duration_space_;
-
- if (d < global_shortest_)
- {
- /*
- We don't space really short notes using the log of the
- duration, since it would disproportionally stretches the long
- notes in a piece. In stead, we use geometric spacing with constant 0.5
- (i.e. linear.)
-
- This should probably be tunable, to use other base numbers.
-
- In Mozart hrn3 by EB., we have 8th note = 3.9 mm (total), 16th note =
- 3.6 mm (total). head-width = 2.4, so we 1.2mm for 16th, 1.5
- mm for 8th. (white space), suggesting that we use
-
- (1.2 / 1.5)^{-log2(duration ratio)}
-
-
- */
- Rational ratio = d / global_shortest_;
-
- return ((k - 1) + double (ratio)) * increment_;
- }
- else
- {
- /*
- John S. Gourlay. ``Spacing a Line of Music, '' Technical
- Report OSU-CISRC-10/87-TR35, Department of Computer and
- Information Science, The Ohio State University, 1987.
- */
- Real log = log_2 (global_shortest_);
- k -= log;
- *expand_only = false;
-
- return (log_2 (d) + k) * increment_;
- }
-}
-
#include "system.hh"
#include "warn.hh"
-vector<Grob*>
-Spacing_spanner::get_columns (Spanner *me)
+
+/*
+ TODO:
+
+ use callback instead?
+
+*/
+Rational
+Spacing_spanner::effective_shortest_duration (Grob *me,
+ vector<Grob*> const &all)
{
- vector<Grob*> all (get_root_system (me)->columns ());
- vsize start = binary_search (all, (Grob*)me->get_bound (LEFT),
- &Paper_column::less_than);
- vsize end = binary_search (all, (Grob*) me->get_bound (RIGHT),
- &Paper_column::less_than);
-
- all = vector<Grob*>::vector<Grob*> (all.begin () + start,
- all.begin () + end + 1);
- return all;
+ SCM preset_shortest = me->get_property ("common-shortest-duration");
+ Rational global_shortest;
+ if (unsmob_moment (preset_shortest))
+ global_shortest = unsmob_moment (preset_shortest)->main_part_;
+ else
+ {
+ global_shortest = Spacing_spanner::find_shortest (me, all);
+ if (be_verbose_global)
+ message (_f ("Global shortest duration is %s", global_shortest.to_string ()) + "\n");
+ }
+
+ return global_shortest;
}
+
MAKE_SCHEME_CALLBACK (Spacing_spanner, set_springs, 1);
SCM
Spacing_spanner::set_springs (SCM smob)
{
- Spanner *me = unsmob_spanner (smob);
+ Grob *me = unsmob_grob (smob);
/*
can't use get_system() ? --hwn.
*/
- vector<Grob*> all (get_columns (me));
+ vector<Grob*> all (get_root_system (me)->columns ());
+
set_explicit_neighbor_columns (all);
Spacing_options options;
options.init_from_grob (me);
+ options.global_shortest_ = effective_shortest_duration (me, all);
prune_loose_columns (me, &all, &options);
set_implicit_neighbor_columns (all);
note has a different duration, but hey, don't write that kind of
stuff, then.
*/
-
-MAKE_SCHEME_CALLBACK (Spacing_spanner, calc_common_shortest_duration, 1);
-SCM
-Spacing_spanner::calc_common_shortest_duration (SCM grob)
+Rational
+Spacing_spanner::find_shortest (Grob *me, vector<Grob*> const &cols)
{
- Spanner *me = unsmob_spanner (grob);
-
- vector<Grob*> cols (get_columns (me));
-
/*
ascending in duration
*/
if (max_idx >= 0)
d = min (d, durations[max_idx]);
- return Moment (d).smobbed_copy ();
+ return d;
}
void
if (!lext.is_empty ())
compound_note_space += -lext[LEFT];
}
+
}
else
{
int wish_count = 0;
-
+
extract_grob_set (left_col, "right-neighbors", neighbors);
/*
if (compound_note_space < 0 || wish_count == 0)
{
-
- if (!Paper_column::is_musical (right_col))
- {
- Real left_col_stick_out = robust_relative_extent (left_col, left_col, X_AXIS)[RIGHT];
- compound_fixed_note_space = max (left_col_stick_out, options->increment_);
-
- compound_note_space = max (base_note_space,
- base_note_space - options->increment_ + left_col_stick_out);
- }
- else
- {
- /*
- Fixed should be 0.0. If there are no spacing wishes, we're
- likely dealing with polyphonic spacing of hemiolas.
-
- We used to have compound_fixed_note_space = options->increment_
-
- but this can lead to numeric instability problems when we
- do
-
- inverse_strength = (compound_note_space - compound_fixed_note_space)
-
- */
-
- compound_note_space = base_note_space;
- compound_fixed_note_space = 0.0;
- }
+ compound_note_space = base_note_space;
+ compound_fixed_note_space = options->increment_;
}
else if (to_boolean (me->get_property ("average-spacing-wishes")))
{
"head width) A 16th note is followed by 0.5 note head width. The\n"
"quarter note is followed by 3 NHW, the half by 4 NHW, etc.\n",
-
"average-spacing-wishes "
- "base-shortest-duration "
- "common-shortest-duration "
- "packed-spacing "
- "shortest-duration-space "
+ "grace-space-factor "
"spacing-increment "
- "strict-grace-spacing "
+ "base-shortest-duration "
"strict-note-spacing "
+ "shortest-duration-space "
+ "common-shortest-duration "
"uniform-stretching "
-
+ "packed-spacing "
);
ADD_INTERFACE (Spacing_interface, "spacing-interface",
"Something to do with line breaking and spacing. "
"Kill this one after determining line breaks.",
-
"");
SCM vissym = ly_symbol2scm ("break-visibility");
SCM vis = bars_[0]->internal_get_property (vissym);
if (ly_is_equal (spanbar_->internal_get_property (vissym), vis))
- spanbar_->set_property (vissym, vis);
+ spanbar_->internal_set_property (vissym, vis);
spanbar_ = 0;
}
if (!model_bar)
model_bar = me;
- vector_sort (extents, Interval::left_less);
+ vector_sort (extents, Interval::left_comparison);
Stencil span_bar;
for (vsize i = 1; i < extents.size (); i++)
#include "audio-item.hh"
#include "international.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
+#include "music.hh"
/*
TODO: fold this into 1 engraver: \< and \> should also stop when
TRANSLATOR_DECLARATIONS (Span_dynamic_performer);
protected:
+ virtual bool try_music (Music *);
virtual void acknowledge_audio_element (Audio_element_info);
void process_music ();
void stop_translation_timestep ();
- DECLARE_TRANSLATOR_LISTENER (decrescendo);
- DECLARE_TRANSLATOR_LISTENER (crescendo);
private:
Audio_dynamic *audio_;
Real last_volume_;
- Stream_event *span_start_event_;
- Drul_array<Stream_event *> span_events_;
+ Music *span_start_event_;
+ Drul_array<Music *> span_events_;
vector<Audio_dynamic_tuple> dynamic_tuples_;
vector<Audio_dynamic_tuple> finished_dynamic_tuples_;
Direction dir_;
if (span_events_[START])
{
- dir_ = (span_events_[START]->in_event_class ("crescendo-event"))
+ dir_ = (span_events_[START]->is_mus_type ("crescendo-event"))
? RIGHT : LEFT;
span_start_event_ = span_events_[START];
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
span_events_[START] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Span_dynamic_performer, decrescendo);
-void
-Span_dynamic_performer::listen_decrescendo (Stream_event *r)
-{
- Direction d = to_dir (r->get_property ("span-direction"));
- span_events_[d] = r;
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Span_dynamic_performer, crescendo);
-void
-Span_dynamic_performer::listen_crescendo (Stream_event *r)
+bool
+Span_dynamic_performer::try_music (Music *r)
{
- Direction d = to_dir (r->get_property ("span-direction"));
- span_events_[d] = r;
+ if (r->is_mus_type ("crescendo-event")
+ || r->is_mus_type ("decrescendo-event"))
+ {
+ Direction d = to_dir (r->get_property ("span-direction"));
+ span_events_[d] = r;
+ return true;
+ }
+ return false;
}
+#include "translator.icc"
ADD_TRANSLATOR (Span_dynamic_performer,
"", "",
}
}
}
- vector_sort (broken_intos_, Spanner::less);
+ vector_sort (broken_intos_, Spanner::compare);
for (vsize i = broken_intos_.size (); i--;)
broken_intos_[i]->break_index_ = i;
}
Grob *
Spanner::find_broken_piece (System *l) const
{
- vsize idx = binary_search (broken_intos_, (Spanner *)l, Spanner::less);
+ vsize idx = binary_search (broken_intos_, (Spanner *)l, Spanner::compare);
if (idx != VPOS)
return broken_intos_ [idx];
return 0;
return p1->get_system ()->get_rank () - p2->get_system ()->get_rank ();
}
-bool
-Spanner::less (Spanner *const &a, Spanner *const &b)
-{
- return a->get_system ()->get_rank () < b->get_system ()->get_rank ();
-}
-
bool
Spanner::is_broken () const
{
Spanner *sp = dynamic_cast<Spanner *> (me);
r.item_drul_[LEFT] = sp->get_bound (LEFT);
r.item_drul_[RIGHT] = sp->get_bound (RIGHT);
+ r.distance_
+ = robust_scm2double (me->get_property ("minimum-length"), 0);
- SCM num_length = me->get_property ("minimum-length");
- if (scm_is_number (num_length))
- {
- r.distance_ = robust_scm2double (num_length, 0);
- r.add_to_cols ();
- }
-
+ r.add_to_cols ();
return SCM_UNSPECIFIED;
}
public:
TRANSLATOR_DECLARATIONS (Staff_collecting_engraver);
DECLARE_ACKNOWLEDGER (staff_symbol);
- DECLARE_END_ACKNOWLEDGER (staff_symbol);
};
Staff_collecting_engraver::Staff_collecting_engraver ()
context ()->set_property ("stavesFound", staffs);
}
-void
-Staff_collecting_engraver::acknowledge_end_staff_symbol (Grob_info gi)
-{
- SCM staffs = get_property ("stavesFound");
- staffs = scm_delq (gi.grob ()->self_scm (), staffs);
-
- context ()->set_property ("stavesFound", staffs);
-}
-
#include "translator.icc"
-
ADD_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
-ADD_END_ACKNOWLEDGER (Staff_collecting_engraver, staff_symbol);
ADD_TRANSLATOR (Staff_collecting_engraver,
/* doc */ "Maintain the stavesFound variable",
{
audio_staff_ = new Audio_staff;
name_ = new Audio_text (Audio_text::TRACK_NAME, context ()->id_string ());
+ tempo_ = new Audio_tempo (get_tempo ());
audio_staff_->add_audio_item (name_);
+ audio_staff_->add_audio_item (tempo_);
announce_element (Audio_element_info (audio_staff_, 0));
announce_element (Audio_element_info (name_, 0));
+ announce_element (Audio_element_info (tempo_, 0));
}
void
/*
Have to be here before notes arrive into the staff.
*/
+ play_element (instrument_);
+ play_element (instrument_name_);
}
}
audio_staff_->channel_ = (drums == SCM_BOOL_T ? 9 : -1);
if (name_)
{
+ play_element (name_);
name_ = 0;
}
if (tempo_)
{
+ play_element (tempo_);
tempo_ = 0;
}
instrument_name_ = 0;
void
Staff_performer::finalize ()
{
+ Performer::play_element (audio_staff_);
audio_staff_ = 0;
}
(c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "engraver.hh"
-#include "international.hh"
+#include "staff-symbol-engraver.hh"
#include "spanner.hh"
-#include "stream-event.hh"
-#include "warn.hh"
-
-#include "translator.icc"
-
-class Staff_symbol_engraver : public Engraver
-{
-public:
- TRANSLATOR_DECLARATIONS (Staff_symbol_engraver);
-
-protected:
- Drul_array<Stream_event *> span_events_;
- Spanner *span_;
- Spanner *finished_span_;
- bool first_start_;
-
-protected:
- virtual void start_spanner ();
- virtual void stop_spanner ();
-
- void stop_translation_timestep ();
- virtual ~Staff_symbol_engraver ();
- DECLARE_ACKNOWLEDGER (grob);
- DECLARE_TRANSLATOR_LISTENER (staff_span);
- virtual void finalize ();
- void process_music ();
-};
Staff_symbol_engraver::~Staff_symbol_engraver ()
{
span_events_[RIGHT] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Staff_symbol_engraver, staff_span);
-void
-Staff_symbol_engraver::listen_staff_span (Stream_event *ev)
+bool
+Staff_symbol_engraver::try_music (Music *music)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
+ Direction d = to_dir (music->get_property ("span-direction"));
if (d)
- ASSIGN_EVENT_ONCE (span_events_[d], ev);
- else
- programming_error (_ ("staff-span event has no direction"));
+ {
+ span_events_[d] = music;
+ return true;
+ }
+
+ return false;
}
void
Staff_symbol_engraver::start_spanner ()
{
if (!span_)
- {
- span_ = make_spanner ("StaffSymbol", SCM_EOL);
- span_->set_bound (LEFT,
- unsmob_grob (get_property ("currentCommandColumn")));
- }
+ span_ = make_spanner ("StaffSymbol", SCM_EOL);
}
void
Staff_symbol_engraver::stop_spanner ()
{
- if (!finished_span_)
- return;
-
- if (!finished_span_->get_bound (RIGHT))
+ if (finished_span_ && !finished_span_->get_bound (RIGHT))
finished_span_->set_bound (RIGHT, unsmob_grob (get_property ("currentCommandColumn")));
-
- announce_end_grob (finished_span_,
- span_events_[STOP]
- ? span_events_[STOP]->self_scm ()
- : SCM_EOL);
-
finished_span_ = 0;
}
Staff_symbol_engraver::stop_translation_timestep ()
{
if ((span_events_[START] || first_start_)
- && span_)
+ && span_
+ && !span_->get_bound (LEFT))
{
+ span_->set_bound (LEFT, unsmob_grob (get_property ("currentCommandColumn")));
first_start_ = false;
}
}
}
+#include "translator.icc"
ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob);
-
ADD_TRANSLATOR (Staff_symbol_engraver,
/* doc */ "Create the constellation of five (default) "
"staff lines.",
{
Real space = Staff_symbol_referencer::staff_space (me);
off = scm_to_double (pos) * space / 2.0;
+ me->set_property ("staff-position", scm_from_int (0));
}
return scm_from_double (off);
- Staff_symbol_referencer::get_position ((Grob *) b));
}
-bool
-position_less (Grob *const &a, Grob *const &b)
-{
- return Staff_symbol_referencer::get_position (a)
- < Staff_symbol_referencer::get_position (b);
-}
-
ADD_INTERFACE (Staff_symbol_referencer, "staff-symbol-referencer-interface",
"An object whose Y position is meant relative to a staff "
"symbol. "
#include "staff-symbol-referencer.hh"
#include "stem-tremolo.hh"
#include "stem.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
/**
Make stems upon receiving noteheads.
{
Grob *stem_;
Grob *tremolo_;
- Stream_event *rhythmic_ev_;
- Stream_event *tremolo_ev_;
+ Music *rhythmic_ev_;
+ Music *tremolo_ev_;
TRANSLATOR_DECLARATIONS (Stem_engraver);
protected:
void make_stem (Grob_info);
- DECLARE_TRANSLATOR_LISTENER (tremolo);
DECLARE_ACKNOWLEDGER (rhythmic_head);
void stop_translation_timestep ();
+ virtual bool try_music (Music *);
};
Stem_engraver::Stem_engraver ()
stem needs a rhythmic structure to fit it into a beam. */
stem_ = make_item ("Stem", gi.grob ()->self_scm ());
+ /*
+ we take the duration log from the Event, since the duration-log
+ for a note head is always <= 2.
+ */
+ Music *music = gi.music_cause ();
+ Duration *dur = unsmob_duration (music->get_property ("duration"));
+
+ stem_->set_property ("duration-log", dur ? scm_from_int (dur->duration_log ()) : 0);
+
if (tremolo_ev_)
{
/* Stem tremolo is never applied to a note by default,
else
context ()->set_property ("tremoloFlags", scm_from_int (requested_type));
-
- /*
- we take the duration log from the Event, since the duration-log
- for a note head is always <= 2.
- */
- Stream_event *ev = gi.event_cause ();
- Duration *dur = unsmob_duration (ev->get_property ("duration"));
-
int tremolo_flags = intlog2 (requested_type) - 2
- (dur->duration_log () > 2 ? dur->duration_log () - 2 : 0);
if (tremolo_flags <= 0)
if (Rhythmic_head::get_stem (gi.grob ()))
return;
- Stream_event *cause = gi.event_cause ();
+ Music *cause = gi.music_cause ();
if (!cause)
return;
Duration *d = unsmob_duration (cause->get_property ("duration"));
if (Stem::duration_log (stem_) != d->duration_log ())
{
// FIXME:
- gi.event_cause ()->origin ()->warning (_f ("adding note head to incompatible stem (type = %d)",
+ gi.music_cause ()->origin ()->warning (_f ("adding note head to incompatible stem (type = %d)",
1 << Stem::duration_log (stem_)));
- gi.event_cause ()->origin ()->warning (_f ("maybe input should specify polyphonic voices"));
+ gi.music_cause ()->origin ()->warning (_f ("maybe input should specify polyphonic voices"));
}
Stem::add_head (stem_, gi.grob ());
tremolo_ev_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tremolo);
-void
-Stem_engraver::listen_tremolo (Stream_event *ev)
+bool
+Stem_engraver::try_music (Music *m)
{
- ASSIGN_EVENT_ONCE (tremolo_ev_, ev);
+ if (m->is_mus_type ("tremolo-event"))
+ {
+ tremolo_ev_ = m;
+ return true;
+ }
+ return false;
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Stem_engraver, rhythmic_head);
ADD_TRANSLATOR (Stem_engraver,
-
/* doc */ "Create stems and single-stem tremolos. It also works together with "
"the beam engraver for overriding beaming.",
-
/* create */
"Stem "
"StemTremolo ",
-
- /* accept */
- "tremolo-event",
-
+ /* accept */ "tremolo-event",
/* read */
"tremoloFlags "
"stemLeftBeamCount "
"stemRightBeamCount ",
-
/* write */ "");
Grob *stem = unsmob_grob (me->get_object ("stem"));
Spanner *beam = Stem::get_beam (stem);
- return (beam && beam->is_live ())
- ? Beam::get_beam_translation (beam) : 0.81;
+ return beam ? Beam::get_beam_translation (beam) : 0.81;
}
Stencil
return Stencil ();
}
- Real beam_translation = get_beam_translation (me);
+ Real beam_translation = get_beam_translation(me);
Stencil mol;
for (int i = 0; i < tremolo_flags; i++)
/*
Cannot use the real slope, since it looks at the Beam.
*/
- Stencil s1 (translated_stencil (me, 0.35));
+ Stencil s1 (raw_stencil (me, 0.35, UP));
return ly_interval2scm (s1.extent (Y_AXIS));
}
-Stencil
-Stem_tremolo::translated_stencil (Grob *me, Real slope)
+
+MAKE_SCHEME_CALLBACK (Stem_tremolo, print, 1);
+SCM
+Stem_tremolo::print (SCM grob)
{
+ Grob *me = unsmob_grob (grob);
Grob *stem = unsmob_grob (me->get_object ("stem"));
if (!stem)
{
programming_error ("no stem for stem-tremolo");
- return Stencil();
+ return SCM_EOL;
}
Spanner *beam = Stem::get_beam (stem);
Direction stemdir = get_grob_direction (stem);
+ bool whole_note = Stem::duration_log (stem) <= 0;
if (stemdir == 0)
stemdir = UP;
- bool whole_note = Stem::duration_log (stem) <= 0;
-
- Real beam_translation = get_beam_translation (me);
+ Real beam_translation
+ = (beam && beam->is_live ())
+ ? Beam::get_beam_translation (beam)
+ : 0.81;
/* for a whole note, we position relative to the notehead, so we want the
stencil aligned on the flag closest to the head */
Direction stencil_dir = whole_note ? -stemdir : stemdir;
- Stencil mol = raw_stencil (me, slope, stencil_dir);
+ Stencil mol = raw_stencil (me, robust_scm2double (me->get_property ("slope"),
+ 0.25), stencil_dir);
Interval mol_ext = mol.extent (Y_AXIS);
Real ss = Staff_symbol_referencer::staff_space (me);
}
mol.translate_axis (end_y, Y_AXIS);
- return mol;
-}
-
-MAKE_SCHEME_CALLBACK (Stem_tremolo, print, 1);
-SCM
-Stem_tremolo::print (SCM grob)
-{
- Grob *me = unsmob_grob (grob);
-
- Stencil s = translated_stencil (me, robust_scm2double (me->get_property ("slope"), 0.25));
- return s.smobbed_copy ();
+ return mol.smobbed_copy ();
}
ADD_INTERFACE (Stem_tremolo, "stem-tremolo-interface",
return 0;
SCM lst = index_get_cell (pair, d);
-
- int len = scm_ilength (lst);
- return max (len, 0);
+ return scm_ilength (lst);
}
Interval
return exthead;
}
+static int
+integer_compare (int const &a, int const &b)
+{
+ return a - b;
+}
+
/* The positions, in ascending order. */
vector<int>
Stem::note_head_positions (Grob *me)
ps.push_back (p);
}
- vector_sort (ps, less<int> ());
+ vector_sort (ps, integer_compare);
return ps;
}
&& scm_to_int (me->get_property ("duration-log")) >= 1);
}
-MAKE_SCHEME_CALLBACK (Stem, pure_height, 3)
-SCM
-Stem::pure_height (SCM smob, SCM start, SCM end)
-{
- (void) start;
- (void) end;
-
-
- Grob *me = unsmob_grob (smob);
- Real ss = Staff_symbol_referencer::staff_space (me);
- Real len = scm_to_double (calc_length (smob)) * ss / 2;
- Direction dir = get_grob_direction (me);
-
- Interval iv;
- Interval hp = head_positions (me);
- if (dir == UP)
- iv = Interval (0, len);
- else
- iv = Interval (-len, 0);
-
- if (!hp.is_empty ())
- iv.translate (hp[dir] * ss / 2);
-
- return ly_interval2scm (iv);
-}
-
MAKE_SCHEME_CALLBACK (Stem, calc_stem_end_position, 1)
SCM
Stem::calc_stem_end_position (SCM smob)
if (!head_count (me))
return scm_from_double (0.0);
- if (Grob *beam = get_beam (me))
- {
- (void) beam->get_property ("quantized-positions");
- return me->get_property ("stem-end-position");
- }
Real ss = Staff_symbol_referencer::staff_space (me);
int durlog = duration_log (me);
extract_grob_set (me, "note-heads", ro_heads);
vector<Grob*> heads (ro_heads);
- vector_sort (heads, position_less);
+ vector_sort (heads, compare_position);
Direction dir = get_grob_direction (me);
if (dir < 0)
Stem::print (SCM smob)
{
Grob *me = unsmob_grob (smob);
- Grob *beam = get_beam (me);
-
Stencil mol;
Direction d = get_grob_direction (me);
= to_boolean (me->get_property ("avoid-note-head"))
? last_head (me)
: first_head (me);
+ Grob *beam = get_beam (me);
if (!lh && !stemlet)
return SCM_EOL;
}
LY_DEFINE (ly_make_stencil, "ly:make-stencil",
- 1, 2, 0, (SCM expr, SCM xext, SCM yext),
+ 3, 0, 0, (SCM expr, SCM xext, SCM yext),
" \n"
"Stencils are a device independent output expressions."
"They carry two pieces of information: \n\n"
"1: a specification of how to print this object. "
"This specification is processed by the output backends, "
" for example @file{scm/output-ps.scm}.\n\n"
- "2: the vertical and horizontal extents of the object.\n\n"
- "If the extents are unspecified, they are taken to be empty."
- )
+ "2: the vertical and horizontal extents of the object.\n\n")
{
SCM_ASSERT_TYPE (!scm_is_pair (expr)
|| is_stencil_head (scm_car (expr)),
expr, SCM_ARG1, __FUNCTION__, "registered stencil expression");
+ SCM_ASSERT_TYPE (is_number_pair (xext), xext, SCM_ARG2, __FUNCTION__, "number pair");
+ SCM_ASSERT_TYPE (is_number_pair (yext), yext, SCM_ARG3, __FUNCTION__, "number pair");
- Interval x;
- if (xext != SCM_UNDEFINED)
- {
- SCM_ASSERT_TYPE (is_number_pair (xext), xext, SCM_ARG2, __FUNCTION__, "number pair");
- x = ly_scm2interval (xext);
- }
-
- Interval y;
- if (yext != SCM_UNDEFINED)
- {
- SCM_ASSERT_TYPE (is_number_pair (yext), yext, SCM_ARG3, __FUNCTION__, "number pair");
- y = ly_scm2interval (yext);
- }
-
- Box b (x, y);
+ Box b (ly_scm2interval (xext), ly_scm2interval (yext));
Stencil s (b, expr);
return s.smobbed_copy ();
}
#include "main.hh"
#include "font-metric.hh"
-#include "input.hh"
+#include "input-smob.hh"
#include "string-convert.hh"
#include "warn.hh"
{
programming_error ("Stencil::moved_to_edge: adding empty stencil.");
his_extent = 0.0;
+ // SCM_ASSERT_TYPE (0, s.expr (), SCM_ARG1, __FUNCTION__, "non-empty stencil");
}
else
his_extent = i[-d];
#include "stream-event.hh"
LY_DEFINE (ly_make_stream_event, "ly:make-stream-event",
- 1, 1, 0, (SCM cl, SCM proplist),
- "Creates a stream event of class @var{cl} with the given mutable property list.\n" )
+ 1, 0, 0, (SCM proplist),
+ "Creates a stream event, with the given property list.\n" )
{
- SCM_ASSERT_TYPE (scm_is_symbol (cl), cl, SCM_ARG1, __FUNCTION__, "symbol");
- if (proplist != SCM_UNDEFINED)
- {
- SCM_ASSERT_TYPE (scm_list_p (proplist), proplist, SCM_ARG2, __FUNCTION__, "association list");
- }
- else
- proplist = SCM_EOL;
- Stream_event *e = new Stream_event (cl, proplist);
+ SCM_ASSERT_TYPE (scm_list_p (proplist), proplist, SCM_ARG1, __FUNCTION__, "association list");
+ Stream_event *e = new Stream_event (proplist);
return e->unprotect ();
}
-LY_DEFINE (ly_event_property, "ly:event-property",
+LY_DEFINE (ly_stream_event_property, "ly:stream-event-property",
2, 0, 0, (SCM sev, SCM sym),
"Get the property @var{sym} of stream event @var{mus}.\n"
"If @var{sym} is undefined, return @code{' ()}.\n")
return e->internal_get_property (sym);
}
-
-LY_DEFINE (ly_event_set_property, "ly:event-set-property!",
- 3, 0, 0, (SCM ev, SCM sym, SCM val),
- "Set property @var{sym} in event @var{ev} to @var{val}."){
- Stream_event *sc = unsmob_stream_event (ev);
- SCM_ASSERT_TYPE (sc, ev, SCM_ARG1, __FUNCTION__, "event");
- return ly_prob_set_property_x (ev, sym, val);
-}
#include "ly-smobs.icc"
#include "context.hh"
#include "input.hh"
-#include "input.hh"
+#include "input-smob.hh"
+
+// ES todo: Add stuff to lily-proto.hh: Stream_event and its subclasses, Stream_creator, etc.
+
+Stream_event::~Stream_event ()
+{
+}
-/* TODO: Rename Stream_event -> Event */
+void
+Stream_event::init ()
+{
+ self_scm_ = SCM_EOL;
+ property_alist_ = SCM_EOL;
+ origin_ = 0;
+
+ smobify_self ();
+}
Stream_event::Stream_event ()
- : Prob (ly_symbol2scm ("Stream_event"), SCM_EOL)
{
+ init ();
}
-Stream_event::Stream_event (SCM event_class, SCM mutable_props)
- : Prob (ly_symbol2scm ("Stream_event"),
- scm_list_1 (scm_cons (ly_symbol2scm ("class"), event_class)))
+Stream_event::Stream_event (Context *c, Input *origin)
{
- mutable_property_alist_ = mutable_props;
+ init ();
+ set_property ("context", scm_int2num (c->get_unique()));
+ origin_ = origin;
}
-Stream_event::Stream_event (SCM class_name, Input *origin)
- : Prob (ly_symbol2scm ("Stream_event"),
- scm_list_1 (scm_cons (ly_symbol2scm ("class"), class_name)))
+Stream_event::Stream_event (SCM property_alist)
{
- if (origin)
- set_spot (origin);
+ init ();
+ property_alist_ = property_alist;
+ origin_ = &dummy_input_global;
+}
+
+Stream_event::Stream_event (Context *c, SCM class_name)
+{
+ init ();
+ set_property ("context", scm_int2num (c->get_unique()));
+ set_property ("class", class_name);
+ origin_ = &dummy_input_global;
}
Stream_event::Stream_event (Stream_event *ev)
- : Prob (ly_symbol2scm ("Stream_event"), SCM_EOL)
{
- mutable_property_alist_ = scm_copy_tree (ev->mutable_property_alist_);
- immutable_property_alist_ = ev->immutable_property_alist_;
+ init ();
+ property_alist_ = scm_copy_tree (ev->property_alist_);
+ origin_ = ev->origin_;
}
Input *
Stream_event::origin () const
{
- Input *i = unsmob_input (get_property ("origin"));
- return i ? i : &dummy_input_global;
+ return origin_;
}
-void
-Stream_event::set_spot (Input *i)
+SCM
+Stream_event::mark_smob (SCM sm)
{
- set_property ("origin", make_input (*i));
+ Stream_event *me = (Stream_event *) SCM_CELL_WORD_1 (sm);
+ return me->property_alist_;
}
-bool
-Stream_event::internal_in_event_class (SCM class_name)
+int
+Stream_event::print_smob (SCM s, SCM port, scm_print_state *)
{
- SCM cl = get_property ("class");
- cl = scm_call_1 (ly_lily_module_constant ("ly:make-event-class"), cl);
- return scm_c_memq (class_name, cl) != SCM_BOOL_F;
+ scm_puts ("#<Stream_event ", port);
+ scm_write (dump (s), port);
+ scm_puts (" >", port);
+ return 1;
}
+IMPLEMENT_SMOBS (Stream_event);
+IMPLEMENT_DEFAULT_EQUAL_P (Stream_event);
IMPLEMENT_TYPE_P (Stream_event, "ly:stream-event?");
MAKE_SCHEME_CALLBACK (Stream_event, undump, 1);
{
Stream_event *ev = unsmob_stream_event (self);
// Reversed alists look prettier.
- return scm_cons (scm_reverse (ev->immutable_property_alist_),
- scm_reverse (ev->mutable_property_alist_));
+ return scm_reverse (ev->property_alist_);
}
SCM
Stream_event::undump (SCM data)
{
Stream_event *obj = new Stream_event ();
- obj->immutable_property_alist_ = scm_reverse (scm_car (data));
- obj->mutable_property_alist_ = scm_reverse (scm_cdr (data));
+ obj->property_alist_ = scm_reverse (data);
return obj->unprotect ();
}
-Stream_event *
-unsmob_stream_event (SCM m)
+SCM
+Stream_event::internal_get_property (SCM sym) const
+{
+ SCM s = scm_sloppy_assq (sym, property_alist_);
+ if (s != SCM_BOOL_F)
+ return scm_cdr (s);
+ return SCM_EOL;
+}
+
+void
+Stream_event::internal_set_property (SCM prop, SCM val)
{
- return dynamic_cast<Stream_event*> (unsmob_prob (m));
+ property_alist_ = scm_assq_set_x (property_alist_, prop, val);
}
bool
Swallow_performer::try_music (Music *m)
{
- if (m->is_mus_type ("melisma-playing-event"))
+ if (m->is_mus_type ("busy-playing-event")
+ || m->is_mus_type ("melisma-playing-event"))
return false;
else
return true;
Bracket_nesting_group::create_grobs (Engraver *engraver, SCM default_type)
{
SCM type = scm_is_symbol (symbol_) ? symbol_ : default_type;
- delimiter_ = engraver->make_spanner (ly_symbol2string (type).c_str (), SCM_EOL);
+ delimiter_ = make_spanner_from_properties (engraver, type,
+ SCM_EOL, ly_symbol2string (type).c_str ());
for (vsize i = 0 ; i < children_.size (); i++)
{
#include "font-interface.hh"
#include "spanner.hh"
#include "stencil.hh"
-#include "item.hh"
class System_start_text
{
{
Spanner *me = unsmob_spanner (smob);
- if (!me->get_bound (LEFT)->break_status_dir ())
- {
- me->suicide ();
- return SCM_EOL;
- }
-
extract_grob_set (me, "elements", all_elts);
vector<Grob*> elts;
for (vsize i = 0; i < all_elts.size (); i++)
}
Stencil m = get_stencil (me);
- if (!ext.is_empty ())
- m.translate_axis (ext.center (), Y_AXIS);
+ m.translate_axis (ext.center (), Y_AXIS);
return m.smobbed_copy ();
}
#include "staff-symbol-referencer.hh"
#include "tweak-registration.hh"
#include "warn.hh"
+#include "warn.hh"
System::System (System const &src, int count)
: Spanner (src, count)
progress_indication ("[");
System *system = dynamic_cast<System *> (broken_intos_[i]);
-
system->post_processing ();
scm_vector_set_x (lines, scm_from_int (i),
system->get_paper_system ());
vector<Grob*> c (breaking[i].cols_);
pscore_->typeset_system (system);
- int st = Paper_column::get_rank (c[0]);
- int end = Paper_column::get_rank (c.back ());
- Interval iv (pure_height (this, st, end));
- system->set_property ("pure-Y-extent", ly_interval2scm (iv));
-
system->set_bound (LEFT, c[0]);
system->set_bound (RIGHT, c.back ());
for (vsize j = 0; j < c.size (); j++)
c[j]->translate_axis (breaking[i].config_[j], X_AXIS);
dynamic_cast<Paper_column *> (c[j])->system_ = system;
}
-
set_loose_columns (system, &breaking[i]);
broken_intos_.push_back (system);
}
anyway. */
vector<Grob*> all_elts_sorted (all_elements_->array ());
- vector_sort (all_elts_sorted, std::less<Grob*> ());
+ vector_sort (all_elts_sorted, default_compare);
uniq (all_elts_sorted);
this->get_stencil ();
for (vsize i = all_elts_sorted.size (); i--;)
entries.push_back (e);
}
- vector_sort (entries, std::less<Layer_entry> ());
+ vector_sort (entries, default_compare);
for (vsize j = 0; j < entries.size (); j++)
{
Grob *g = entries[j].grob_;
Prob *pl = make_paper_system (prop_init);
paper_system_set_stencil (pl, sys_stencil);
- /* information that the page breaker might need */
- Grob *right_bound = this->get_bound (RIGHT);
- pl->set_property ("page-break-permission", right_bound->get_property ("page-break-permission"));
- pl->set_property ("page-turn-permission", right_bound->get_property ("page-turn-permission"));
- pl->set_property ("page-break-penalty", right_bound->get_property ("page-break-penalty"));
- pl->set_property ("page-turn-penalty", right_bound->get_property ("page-turn-penalty"));
+ /* backwards-compatibility hack for the old page-breaker */
+ SCM turn_perm = left_bound->get_property ("page-break-permission");
+ if (!scm_is_symbol (turn_perm))
+ pl->set_property ("penalty", scm_from_double (10001.0));
+ else if (turn_perm == ly_symbol2scm ("force"))
+ pl->set_property ("penalty", scm_from_double (-10001.0));
+ else
+ pl->set_property ("penalty", scm_from_double (0.0));
if (!scm_is_pair (pl->get_property ("refpoint-Y-extent")))
{
/* properties */
"all-elements "
"columns "
- "pure-Y-extent "
"spaceable-staves "
)
#include <cstdio>
using namespace std;
-#include "dot-column.hh"
+#include "rhythmic-head.hh"
+#include "output-def.hh"
+#include "music.hh"
#include "dots.hh"
-#include "duration.hh"
+#include "dot-column.hh"
+#include "staff-symbol-referencer.hh"
#include "item.hh"
-#include "output-def.hh"
-#include "pitch.hh"
-#include "rhythmic-head.hh"
#include "score-engraver.hh"
-#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "warn.hh"
-
-#include "translator.icc"
+#include "duration.hh"
/**
make (guitar-like) tablature note
{
vector<Item*> notes_;
- vector<Stream_event*> note_events_;
- vector<Stream_event*> tabstring_events_;
+ vector<Item*> dots_;
+ vector<Music*> note_events_;
+ vector<Music*> tabstring_events_;
public:
TRANSLATOR_DECLARATIONS (Tab_note_heads_engraver);
protected:
- DECLARE_TRANSLATOR_LISTENER (note);
- DECLARE_TRANSLATOR_LISTENER (string_number);
+ virtual bool try_music (Music *event);
void process_music ();
void stop_translation_timestep ();
{
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, note);
-void
-Tab_note_heads_engraver::listen_note (Stream_event *ev)
+bool
+Tab_note_heads_engraver::try_music (Music *m)
{
- note_events_.push_back (ev);
-}
+ if (m->is_mus_type ("note-event"))
+ {
+ note_events_.push_back (m);
+ return true;
+ }
+ else if (m->is_mus_type ("string-number-event"))
+ {
+ tabstring_events_.push_back (m);
+ return true;
+ }
+ else if (m->is_mus_type ("busy-playing-event"))
+ return note_events_.size ();
-IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, string_number);
-void
-Tab_note_heads_engraver::listen_string_number (Stream_event *ev)
-{
- tabstring_events_.push_back (ev);
+ return false;
}
void
int number_of_strings = ((int) ly_length (stringTunings));
bool high_string_one = to_boolean (get_property ("highStringOne"));
- Stream_event *event = note_events_[i];
+ Music *event = note_events_[i];
Item *note = make_item ("TabNoteHead", event->self_scm ());
- Stream_event *tabstring_event = 0;
+ Music *tabstring_event = 0;
for (SCM s = event->get_property ("articulations");
!tabstring_event && scm_is_pair (s); s = scm_cdr (s))
{
- Stream_event *art = unsmob_stream_event (scm_car (s));
+ Music *art = unsmob_music (scm_car (s));
- if (art->in_event_class ("string-number-event"))
+ if (art->is_mus_type ("string-number-event"))
tabstring_event = art;
}
}
Duration dur = *unsmob_duration (event->get_property ("duration"));
+ note->set_property ("duration-log",
+ scm_from_int (dur.duration_log ()));
+
+ if (dur.dot_count ())
+ {
+ Item *d = make_item ("Dots", event->self_scm ());
+ Rhythmic_head::set_dots (note, d);
+
+ if (dur.dot_count ()
+ != scm_to_int (d->get_property ("dot-count")))
+ d->set_property ("dot-count", scm_from_int (dur.dot_count ()));
+
+ d->set_parent (note, Y_AXIS);
+
+ dots_.push_back (d);
+ }
SCM scm_pitch = event->get_property ("pitch");
SCM proc = get_property ("tablatureFormat");
Tab_note_heads_engraver::stop_translation_timestep ()
{
notes_.clear ();
+ dots_.clear ();
note_events_.clear ();
tabstring_events_.clear ();
}
-ADD_TRANSLATOR (Tab_note_heads_engraver,
- /* doc */ "Generate one or more tablature noteheads from event of type NoteEvent.",
- /* create */
- "TabNoteHead "
- ,
-
- /* accept */
- "note-event "
- "string-number-event ",
-
- /* read */
- "middleCPosition "
- "stringTunings "
- "minimumFret "
- "tablatureFormat "
- "highStringOne "
- "stringOneTopmost ",
+#include "translator.icc"
+ADD_TRANSLATOR (Tab_note_heads_engraver,
+ /* doc */ "Generate one or more tablature noteheads from Music of type NoteEvent.",
+ /* create */ "TabNoteHead Dots",
+ /* accept */ "note-event string-number-event busy-playing-event",
+ /* read */ "middleCPosition stringTunings minimumFret tablatureFormat highStringOne stringOneTopmost",
/* write */ "");
(c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
-#include "engraver.hh"
+#include "staff-symbol-engraver.hh"
#include "spanner.hh"
-class Tab_staff_symbol_engraver : public Engraver
+class Tab_staff_symbol_engraver : public Staff_symbol_engraver
{
public:
TRANSLATOR_DECLARATIONS (Tab_staff_symbol_engraver);
protected:
- DECLARE_ACKNOWLEDGER(staff_symbol);
+ virtual void start_spanner ();
};
void
-Tab_staff_symbol_engraver::acknowledge_staff_symbol (Grob_info gi)
+Tab_staff_symbol_engraver::start_spanner ()
{
- int k = scm_ilength (get_property ("stringTunings"));
- if (k >= 0)
- gi.grob ()->set_property ("line-count", scm_from_int (k));
+ bool init = !span_;
+ Staff_symbol_engraver::start_spanner ();
+ if (init)
+ {
+ int k = scm_ilength (get_property ("stringTunings"));
+ if (k >= 0)
+ span_->set_property ("line-count", scm_from_int (k));
+ }
}
Tab_staff_symbol_engraver::Tab_staff_symbol_engraver ()
#include "translator.icc"
-ADD_ACKNOWLEDGER (Tab_staff_symbol_engraver, staff_symbol);
+ADD_ACKNOWLEDGER (Tab_staff_symbol_engraver, grob);
ADD_TRANSLATOR (Tab_staff_symbol_engraver,
- /* doc */
- "Create a staff-symbol, but look at "
- "stringTunings for the number of lines. "
- ,
+ /* doc */ "Create a staff-symbol, but look at stringTunings for the number of lines."
+ "staff lines.",
/* create */ "StaffSymbol",
/* accept */ "staff-span-event",
/* read */ "stringTunings",
#include "performer.hh"
#include "audio-item.hh"
+#include "music.hh"
#include "duration.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
class Tempo_performer : public Performer
{
protected:
- virtual void derived_mark () const;
+ virtual bool try_music (Music *event);
void stop_translation_timestep ();
void process_music ();
+
private:
+ Music *tempo_event_;
Audio_tempo *audio_;
- SCM last_tempo_;
};
-void
-Tempo_performer::derived_mark () const
-{
- scm_gc_mark (last_tempo_);
-}
-
Tempo_performer::Tempo_performer ()
{
- last_tempo_ = SCM_EOL;
+ tempo_event_ = 0;
audio_ = 0;
}
void
Tempo_performer::process_music ()
{
- SCM w = get_property ("tempoWholesPerMinute");
- if (unsmob_moment (w)
- && !ly_is_equal (w, last_tempo_))
+ if (tempo_event_)
{
- Rational r = unsmob_moment (w)->main_part_;
- r *= Rational (4, 1);
+ SCM met = tempo_event_->get_property ("metronome-count");
+ Duration *d = unsmob_duration (tempo_event_->get_property ("tempo-unit"));
+
+ Rational r = (d->get_length () / Moment (Rational (1, 4)) * Moment (scm_to_int (met))).main_part_;
audio_ = new Audio_tempo (r.to_int ());
- Audio_element_info info (audio_, 0);
+ Audio_element_info info (audio_, tempo_event_);
announce_element (info);
-
- last_tempo_ = w;
+ tempo_event_ = 0;
}
}
{
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
}
+bool
+Tempo_performer::try_music (Music *event)
+{
+ if (tempo_event_)
+ return false;
+
+ tempo_event_ = event;
+ return true;
+}
+
+#include "translator.icc"
+
ADD_TRANSLATOR (Tempo_performer, "", "",
- "",
- "tempoWholesPerMinute ",
- "");
+ "metronome-change-event",
+ "", "");
#include "directional-element-interface.hh"
#include "engraver.hh"
-#include "rhythmic-head.hh"
#include "side-position-interface.hh"
#include "stem.hh"
-#include "stream-event.hh"
+#include "rhythmic-head.hh"
#include "text-interface.hh"
-#include "translator.icc"
-
/**
typeset directions that are plain text.
*/
class Text_engraver : public Engraver
{
- vector<Stream_event *> evs_;
+ vector<Music*> evs_;
vector<Item*> texts_;
public:
TRANSLATOR_DECLARATIONS (Text_engraver);
protected:
+ virtual bool try_music (Music *m);
void stop_translation_timestep ();
void process_acknowledged ();
- DECLARE_TRANSLATOR_LISTENER (text_script);
DECLARE_ACKNOWLEDGER (stem_tremolo);
DECLARE_ACKNOWLEDGER (stem);
DECLARE_ACKNOWLEDGER (rhythmic_head);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Text_engraver, text_script);
-void
-Text_engraver::listen_text_script (Stream_event *ev)
+bool
+Text_engraver::try_music (Music *m)
{
- evs_.push_back (ev);
+ if (m->is_mus_type ("text-script-event"))
+ {
+ evs_.push_back (m);
+ return true;
+ }
+ return false;
}
void
return;
for (vsize i = 0; i < evs_.size (); i++)
{
- Stream_event *r = evs_[i];
+ Music *r = evs_[i];
// URG: Text vs TextScript
Item *text = make_item ("TextScript", r->self_scm ());
{
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Text_engraver, stem);
ADD_ACKNOWLEDGER (Text_engraver, stem_tremolo);
ADD_ACKNOWLEDGER (Text_engraver, rhythmic_head);
string str = ly_scm2string (markup);
Font_metric *fm = select_encoded_font (layout, props);
- return fm->word_stencil (str).smobbed_copy ();
+ return fm->text_stencil (str).smobbed_copy ();
}
MAKE_SCHEME_CALLBACK (Text_interface, interpret_markup, 3);
#include "international.hh"
#include "note-column.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
-
-#include "translator.icc"
class Text_spanner_engraver : public Engraver
{
protected:
virtual void finalize ();
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (text_span);
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
private:
Spanner *span_;
Spanner *finished_;
- Stream_event *current_event_;
- Drul_array<Stream_event *> event_drul_;
+ Music *current_event_;
+ Drul_array<Music *> event_drul_;
void typeset_all ();
};
event_drul_[STOP] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Text_spanner_engraver, text_span);
-void
-Text_spanner_engraver::listen_text_span (Stream_event *ev)
+bool
+Text_spanner_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (event_drul_[d], ev);
+ if (m->is_mus_type ("text-span-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ event_drul_[d] = m;
+ return true;
+ }
+
+ return false;
}
void
}
}
+#include "translator.icc"
ADD_ACKNOWLEDGER (Text_spanner_engraver, note_column);
ADD_TRANSLATOR (Text_spanner_engraver,
- /* doc */ "Create text spanner from an event.",
+ /* doc */ "Create text spanner from a Music.",
/* create */ "TextSpanner",
/* accept */ "text-span-event",
/* read */ "",
--- /dev/null
+/*
+ tfm-reader.cc -- implement Tex_font_metric_reader
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+
+
+ some code shamelessly copied from GNU fontutils-0.6/tfm/tfm_input.c
+*/
+
+#include "tfm-reader.hh"
+
+#include "international.hh"
+#include "string-convert.hh"
+#include "warn.hh"
+
+#define format_string String_convert::form_string
+#define FIX_UNITY \
+ (1 << 20)
+static const Real fix_to_real (Fix f);
+
+Tex_font_metric_reader::Tex_font_metric_reader (string name)
+ : input_ (name)
+{
+
+ for (vsize i = 0; i < TFM_SIZE; i++)
+ ascii_to_metric_idx_.push_back (VPOS);
+
+ read_header ();
+ read_params ();
+ read_char_metrics ();
+}
+
+static const Real
+fix_to_real (Fix f)
+{
+ Real r = f / FIX_UNITY + ((Real) (f % FIX_UNITY) / (Real) FIX_UNITY);
+ return r;
+}
+
+/* Most quantities are fixed-point fractions. */
+
+Real
+Tex_font_metric_reader::get_U32_fix ()
+{
+ return fix_to_real (input_.get_U32 ());
+}
+
+/* Dimensions are a `Fix' scaled by the design size. */
+
+Real
+Tex_font_metric_reader::get_U32_fix_scaled ()
+{
+ return get_U32_fix () * info_.design_size;
+}
+
+string
+Tex_font_metric_reader::get_bcpl_string ()
+{
+ U8 length_u8 = input_.get_U8 ();
+ string str = input_.get_string (length_u8);
+ return str;
+}
+
+/* Here we read the information at the beginning of the file. We store
+ the result into the static variables `global_info' and
+ `tfm_header'. */
+void
+Tex_font_metric_reader::read_header ()
+{
+ U16 file_length = input_.get_U16 ();
+ (void) file_length;
+ U16 header_length = input_.get_U16 ();
+
+ info_.first_charcode = input_.get_U16 ();
+ info_.last_charcode = input_.get_U16 ();
+ U16 width_word_count = input_.get_U16 ();
+ U16 height_word_count = input_.get_U16 ();
+ U16 depth_word_count = input_.get_U16 ();
+ U16 italic_correction_word_count = input_.get_U16 ();
+ U16 lig_kern_word_count = input_.get_U16 ();
+ U16 kern_word_count = input_.get_U16 ();
+ (void)kern_word_count;
+ U16 extensible_word_count = input_.get_U16 ();
+ (void)extensible_word_count;
+
+ header_.param_word_count = input_.get_U16 ();
+ info_.parameter_count = header_.param_word_count;
+
+ header_.char_info_pos = (6 + header_length) * 4;
+ header_.width_pos = header_.char_info_pos
+ + (info_.last_charcode
+ - info_.first_charcode + 1) * 4;
+ header_.height_pos = header_.width_pos + width_word_count * 4;
+ header_.depth_pos = header_.height_pos + height_word_count * 4;
+ header_.italic_correction_pos = header_.depth_pos
+ + depth_word_count * 4;
+ header_.lig_kern_pos = header_.italic_correction_pos
+ + italic_correction_word_count * 4;
+ header_.kern_pos = header_.lig_kern_pos + lig_kern_word_count * 4;
+ /* We don't care about the extensible table. */
+
+ if (header_length < 2)
+ /* Not using ngettext's plural feature here, as this message is
+ more of a programming error. */
+ error (_f ("TFM header of `%s' has only %u word (s)",
+ input_.name_string ().c_str (), header_length));
+
+ info_.checksum = input_.get_U32 ();
+ info_.design_size = get_U32_fix ();
+
+ /* Although the coding scheme might be interesting to the caller, the
+ font family and face byte probably aren't. So we don't read them. */
+ info_.coding_scheme = header_length > 2
+ ? get_bcpl_string () : "unspecified";
+}
+
+/* Although TFM files are only usable by TeX if they have at least seven
+ parameters, that is not a requirement of the file format itself, so
+ we don't impose it. And they can have many more than seven, of
+ course. We do impose a limit of TFM_MAX_FONT_PARAMETERS. We assume
+ that `tfm_header' has already been filled in. */
+
+void
+Tex_font_metric_reader::read_params ()
+{
+ /* If we have no font parameters at all, we're done. */
+ if (header_.param_word_count == 0)
+ return;
+
+ //brrr
+ /* Move to the beginning of the parameter table in the file. */
+ input_.seek_str0 (-4 * header_.param_word_count);
+
+ /* It's unlikely but possible that this TFM file has more fontdimens
+ than we can deal with. */
+ if (header_.param_word_count > TFM_MAX_FONTDIMENS)
+ {
+ warning (_f ("%s: TFM file has %u parameters, which is more than the %u I can handle",
+ input_.name_string ().c_str (),
+ header_.param_word_count,
+ TFM_MAX_FONTDIMENS));
+ header_.param_word_count = TFM_MAX_FONTDIMENS;
+ }
+
+ /* The first parameter is different than all the rest, because it
+ isn't scaled by the design size. */
+ info_.parameters[ (TFM_SLANT_PARAMETER) - 1] = get_U32_fix ();
+
+ for (Char_code i = 2; i <= header_.param_word_count; i++)
+ info_.parameters[i - 1] = get_U32_fix_scaled ();
+}
+
+/* Read every character in the TFM file, storing the result in the
+ static `tfm_char_table'. We return a copy of that variable. */
+
+void
+Tex_font_metric_reader::read_char_metrics ()
+{
+ for (int i = info_.first_charcode; i <= info_.last_charcode; i++)
+ {
+ Tex_font_char_metric tfm_char = read_char_metric (i);
+ if (tfm_char.exists_)
+ ascii_to_metric_idx_[tfm_char.code_] = char_metrics_.size ();
+ char_metrics_.push_back (tfm_char);
+ }
+}
+
+/* Read the character CODE. If the character doesn't exist, return
+ NULL. If it does, save the information in `tfm_char_table', as well
+ as returning it. */
+
+Tex_font_char_metric
+Tex_font_metric_reader::read_char_metric (Char_code code)
+{
+ Tex_font_char_metric tfm_char;
+
+ /* If the character is outside the declared bounds in the file, don't
+ try to read it. */
+ if (code < info_.first_charcode || code > info_.last_charcode)
+ return tfm_char;
+
+ //brr
+ /* Move to the appropriate place in the `char_info' array. */
+ input_.seek_str0 (header_.char_info_pos + (code - info_.first_charcode) * 4);
+
+ /* Read the character. */
+ tfm_char = read_char ();
+
+ if (tfm_char.exists_)
+ tfm_char.code_ = code;
+
+ return tfm_char;
+}
+
+/* We assume we are positioned at the beginning of a `char_info' word.
+ We read that word to get the indexes into the dimension tables; then
+ we go read the tables to get the values (if the character exists). */
+
+Tex_font_char_metric
+Tex_font_metric_reader::read_char ()
+{
+ /* Read the char_info word. */
+ U8 width_index = input_.get_U8 ();
+
+ U8 packed;
+ packed = input_.get_U8 ();
+ U8 height_index = (packed & 0xf0) >> 4;
+ U8 depth_index = packed & 0x0f;
+
+ packed = input_.get_U8 ();
+ U8 italic_correction_index = (packed & 0xfc) >> 6;
+ U8 tag = packed & 0x3;
+
+ U8 remainder = input_.get_U8 ();
+
+ Tex_font_char_metric tfm_char;
+
+#define GET_CHAR_DIMEN(d) \
+ if (d##_index != 0) \
+ { \
+ input_.seek_str0 (header_.d##_pos + d##_index * 4); \
+ tfm_char.d##_fix_ = input_.get_U32 (); \
+ tfm_char.d##_ = fix_to_real (tfm_char.d##_fix_) \
+ * info_.design_size; \
+ }
+
+ GET_CHAR_DIMEN (width);
+ GET_CHAR_DIMEN (height);
+ GET_CHAR_DIMEN (depth);
+ GET_CHAR_DIMEN (italic_correction);
+
+ /* The other condition for a character existing is that it be between
+ the first and last character codes given in the header. We've
+ already assumed that's true (or we couldn't be positioned at a
+ `char_info_word'). */
+ tfm_char.exists_ = width_index != 0;
+
+ if (tag == 1)
+ {
+ input_.seek_str0 (header_.lig_kern_pos + remainder * 4);
+ read_lig_kern_program (&tfm_char.ligatures_, &tfm_char.kerns_);
+ }
+
+ /* We don't handle the other tags. */
+ return tfm_char;
+}
+
+/* Read a ligature/kern program at the current position, storing the
+ result into *LIGATURE and *KERN. We don't distinguish all the kinds
+ of ligatures that Metafont can output. */
+
+#define STOP_FLAG 128
+#define KERN_FLAG 128
+
+void
+Tex_font_metric_reader::read_lig_kern_program (vector<Tfm_ligature> *ligatures, vector<Tfm_kern> *kerns)
+{
+ bool end_b;
+
+ do
+ {
+ end_b = input_.get_U8 () >= STOP_FLAG;
+
+ U8 next_char = input_.get_U8 ();
+ bool kern_step_b = input_.get_U8 () >= KERN_FLAG;
+ U8 remainder = input_.get_U8 ();
+
+ if (kern_step_b)
+ {
+ Tfm_kern kern_element;
+ kern_element.character = next_char;
+
+ char const *old_pos = input_.pos_str0 ();
+ input_.seek_str0 (header_.kern_pos + remainder * 4);
+ kern_element.kern = get_U32_fix_scaled ();
+ input_.set_pos (old_pos);
+
+ kerns->push_back (kern_element);
+ }
+ else
+ {
+ Tfm_ligature ligature_element;
+ ligature_element.character = next_char;
+ ligature_element.ligature = remainder;
+ ligatures->push_back (ligature_element);
+ }
+ }
+ while (!end_b);
+}
+
--- /dev/null
+/*
+ tfm.cc -- implement Tex_font_metric
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999--2006 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ some code shamelessly copied from GNU fontutils-0.6/tfm/tfm_input.c
+*/
+
+#include "tfm.hh"
+
+#include "dimensions.hh"
+#include "file-name.hh"
+#include "international.hh"
+#include "string-convert.hh"
+#include "tfm-reader.hh"
+#include "warn.hh"
+
+static Tex_font_char_metric dummy_static_char_metric;
+
+Tex_font_char_metric::Tex_font_char_metric ()
+{
+ exists_ = false;
+ code_ = 0;;
+ width_ = 0;
+ height_ = 0;
+ depth_ = 0;
+ italic_correction_ = 0;
+ width_fix_ = 0;
+ height_fix_ = 0;
+ depth_fix_ = 0;
+ italic_correction_fix_ = 0;
+}
+
+Box
+Tex_font_char_metric::dimensions () const
+{
+ if (!exists_)
+ {
+ Box b;
+ b.set_empty ();
+ return b;
+ }
+
+ Real d = -depth_;
+ Real point_constant = 1 PT;
+
+ return Box (Interval (0, width_ * point_constant),
+ Interval (min (d, height_) * point_constant,
+ max (d, height_) * point_constant));
+}
+
+Tex_font_metric::Tex_font_metric ()
+{
+ encoding_table_ = SCM_EOL;
+}
+
+void
+Tex_font_metric::derived_mark () const
+{
+ scm_gc_mark (encoding_table_);
+}
+
+Tex_font_char_metric const *
+Tex_font_metric::find_ascii (vsize ascii, bool warn) const
+{
+ if (ascii != VPOS && ascii < ascii_to_metric_idx_.size ()
+ && ascii_to_metric_idx_[ascii] != VPOS)
+ return &char_metrics_[ascii_to_metric_idx_ [ascii]];
+ else if (warn)
+ warning (_f ("can't find ascii character: %d", ascii));
+ return &dummy_static_char_metric;
+}
+
+/* UGH: glyphs need not be consecutive in TFM. */
+vsize
+Tex_font_metric::count () const
+{
+ for (vsize i = ascii_to_metric_idx_.size (); i--;)
+ if (ascii_to_metric_idx_[i] != VPOS)
+ return i + 1;
+ return 0;
+}
+
+Box
+Tex_font_metric::get_ascii_char (vsize a) const
+{
+ Box b = find_ascii (a)->dimensions ();
+ return b;
+}
+
+SCM
+Tex_font_metric::make_tfm (string file_name)
+{
+ Tex_font_metric *tfm = new Tex_font_metric;
+ Tex_font_metric_reader reader (file_name);
+
+ tfm->info_ = reader.info_;
+ tfm->header_ = reader.header_;
+ tfm->char_metrics_ = reader.char_metrics_;
+ tfm->ascii_to_metric_idx_ = reader.ascii_to_metric_idx_;
+
+ File_name fn (file_name);
+ tfm->font_name_ = fn.base_;
+ return tfm->self_scm ();
+}
+
+Tfm_info const &
+Tex_font_metric::info () const
+{
+ return info_;
+}
+
+Real
+Tex_font_metric::design_size () const
+{
+ return info_.design_size * point_constant;
+}
+
+string
+Tex_font_metric::font_name () const
+{
+ return font_name_;
+}
+
+vsize
+Tex_font_metric::name_to_index (string) const
+{
+ assert (false);
+ return 0;
+}
return SCM_BOOL_T;
}
- vector_sort (ties, Tie::less);
+ vector_sort (ties, &Tie::compare);
Tie_formatting_problem problem;
problem.from_ties (ties);
#include "protected-scm.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "tie-column.hh"
#include "tie.hh"
#include "warn.hh"
-#include "translator.icc"
-
/**
Manufacture ties. Acknowledge noteheads, and put them into a
priority queue. If we have a TieEvent, connect the notes that finish
struct Head_event_tuple
{
Grob *head_;
- Moment end_moment_;
SCM tie_definition_;
- Stream_event *tie_stream_event_;
- Stream_event *tie_event_;
-
+ Music *event_;
Head_event_tuple ()
{
- head_ = 0;
- tie_definition_ = SCM_EOL;
- tie_event_ = 0;
- tie_stream_event_ = 0;
+ }
+ Head_event_tuple (Grob *h, Music *m, SCM def)
+ {
+ head_ = h;
+ event_ = m;
+ tie_definition_ = def;
}
};
class Tie_engraver : public Engraver
{
- Stream_event *event_;
+ Music *event_;
vector<Grob*> now_heads_;
vector<Head_event_tuple> heads_to_tie_;
vector<Grob*> ties_;
virtual void derived_mark () const;
void start_translation_timestep ();
DECLARE_ACKNOWLEDGER (note_head);
- DECLARE_TRANSLATOR_LISTENER (tie);
+ virtual bool try_music (Music *);
void process_music ();
void typeset_tie (Grob *);
public:
tie_column_ = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tie_engraver, tie);
-void
-Tie_engraver::listen_tie (Stream_event *ev)
+bool
+Tie_engraver::try_music (Music *mus)
{
- ASSIGN_EVENT_ONCE (event_, ev);
+ if (mus->is_mus_type ("tie-event"))
+ event_ = mus;
+
+ return true;
}
void
Tie_engraver::process_music ()
{
- bool busy = event_;
- for (vsize i = 0; !busy && i < heads_to_tie_.size (); i++)
- busy |= (heads_to_tie_[i].tie_event_
- || heads_to_tie_[i].tie_stream_event_);
-
- if (busy)
+ if (event_)
context ()->set_property ("tieMelismaBusy", SCM_BOOL_T);
}
Tie_engraver::acknowledge_note_head (Grob_info i)
{
Grob *h = i.grob ();
-
now_heads_.push_back (h);
for (vsize i = heads_to_tie_.size (); i--;)
{
Grob *th = heads_to_tie_[i].head_;
- Stream_event *right_ev = unsmob_stream_event (h->get_property ("cause"));
- Stream_event *left_ev = unsmob_stream_event (th->get_property ("cause"));
+ Music *right_mus = unsmob_music (h->get_property ("cause"));
+ Music *left_mus = unsmob_music (th->get_property ("cause"));
/*
maybe should check positions too.
*/
- if (!right_ev || !left_ev)
- continue;
-
- if (ly_is_equal (right_ev->get_property ("pitch"),
- left_ev->get_property ("pitch")))
+ if (right_mus && left_mus
+ && ly_is_equal (right_mus->get_property ("pitch"),
+ left_mus->get_property ("pitch")))
{
Grob *p = new Spanner (heads_to_tie_[i].tie_definition_,
context ()->get_grob_key ("Tie"));
-
- SCM cause = heads_to_tie_[i].tie_event_
- ? heads_to_tie_[i].tie_event_->self_scm ()
- : heads_to_tie_[i].tie_stream_event_->self_scm ();
-
- announce_grob (p, cause);
+ announce_grob (p, heads_to_tie_[i].event_->self_scm ());
Tie::set_head (p, LEFT, th);
Tie::set_head (p, RIGHT, h);
{
context ()->set_property ("tieMelismaBusy",
ly_bool2scm (heads_to_tie_.size ()));
-
- if (!to_boolean (get_property ("tieWaitForNote")))
- {
- Moment now = now_mom ();
- for (vsize i = heads_to_tie_.size (); i--; )
- {
- if (now > heads_to_tie_[i].end_moment_)
- heads_to_tie_.erase (heads_to_tie_.begin () + i);
- }
- }
}
void
Tie_engraver::stop_translation_timestep ()
{
- bool wait = to_boolean (get_property ("tieWaitForNote"));
if (ties_.size ())
{
- if (!wait)
+ if (!to_boolean (get_property ("tieWaitForNote")))
heads_to_tie_.clear ();
for (vsize i = 0; i < ties_.size (); i++)
tie_column_ = 0;
}
- vector<Head_event_tuple> new_heads_to_tie;
-
- for (vsize i = 0; i < now_heads_.size (); i++)
+ if (event_)
{
- Grob *head = now_heads_[i];
- Stream_event *left_ev
- = unsmob_stream_event (head->get_property ("cause"));
+ SCM start_definition
+ = updated_grob_properties (context (), ly_symbol2scm ("Tie"));
- if (!left_ev)
- {
- // may happen for ambituses
- continue;
- }
-
-
- SCM left_articulations = left_ev->get_property ("articulations");
-
- Stream_event *tie_event = 0;
- Stream_event *tie_stream_event = event_;
- for (SCM s = left_articulations;
- !tie_event && !tie_stream_event && scm_is_pair (s);
- s = scm_cdr (s))
- {
- Stream_event *ev = unsmob_stream_event (scm_car (s));
- if (!ev)
- continue;
-
- if (ev->in_event_class ("tie-event"))
- tie_event = ev;
- }
-
- if (left_ev && (tie_event || tie_stream_event))
+ if (!to_boolean (get_property ("tieWaitForNote")))
+ heads_to_tie_.clear ();
+
+ for (vsize i = 0; i < now_heads_.size (); i++)
{
- Head_event_tuple event_tup;
-
- SCM start_definition
- = updated_grob_properties (context (), ly_symbol2scm ("Tie"));
-
- event_tup.head_ = head;
- event_tup.tie_definition_ = start_definition;
- event_tup.tie_event_ = tie_event;
- event_tup.tie_stream_event_ = tie_stream_event;
-
- Moment end = now_mom ();
- if (end.grace_part_)
- {
- end.grace_part_ += get_event_length (left_ev).main_part_;
- }
- else
- {
- end += get_event_length (left_ev);
- }
- event_tup.end_moment_ = end;
-
- new_heads_to_tie.push_back (event_tup);
+ heads_to_tie_.push_back (Head_event_tuple (now_heads_[i], event_,
+ start_definition));
}
}
- if (!wait && new_heads_to_tie.size ())
- heads_to_tie_.clear ();
-
- // hmmm, how to do with copy() ?
- for (vsize i = 0; i < new_heads_to_tie.size (); i++)
- heads_to_tie_.push_back (new_heads_to_tie[i]);
-
event_ = 0;
now_heads_.clear ();
}
sp->set_bound (RIGHT, new_head_drul[RIGHT]);
}
+#include "translator.icc"
+
ADD_ACKNOWLEDGER (Tie_engraver, note_head);
ADD_TRANSLATOR (Tie_engraver,
/* doc */ "Generate ties between noteheads of equal pitch.",
/* create */
"Tie "
- "TieColumn ",
+ "TieColumn",
/* accept */ "tie-event",
/* read */ "tieWaitForNote",
Y_AXIS, -dir);
}
}
- else if (stem)
- {
- Grob *head = Stem::support_head (stem);
-
- /*
- In case of invisible stem, don't pass x-center of heads.
- */
- Real x_center = head->extent (x_refpoint_, X_AXIS).center ();
- Interval x_ext;
- x_ext[-dir] = x_center;
- Interval y_ext;
- for (vsize j = 0; j < head_boxes.size (); j++)
- y_ext.unite (head_boxes[j][Y_AXIS]);
-
- insert_extent_into_skyline (&chord_outlines_[key],
- Box (x_ext, y_ext),
- Y_AXIS, -dir);
- }
Direction updowndir = DOWN;
do
for (vsize i = 0; i < bounds.size (); i++)
ranks.push_back (bounds[i]->get_column ()->get_rank ());
- vector_sort (ranks, less<int> ());
+ vector_sort (ranks, default_compare);
uniq (ranks);
for (vsize i = 0; i < ranks.size (); i++)
Ties_configuration
Tie_formatting_problem::generate_optimal_chord_configuration ()
{
+
Ties_configuration base = generate_base_chord_configuration ();
vector<Tie_configuration_variation> vars = generate_collision_variations (base);
#include "performer.hh"
-#include "audio-item.hh"
+#include "music.hh"
#include "context.hh"
+#include "audio-item.hh"
#include "pqueue.hh"
-#include "stream-event.hh"
-#include "translator.icc"
class Tie_performer : public Performer
{
- Stream_event *event_;
+ Music *event_;
+ Music *last_event_;
vector<Audio_element_info> now_heads_;
- vector<Audio_element_info> now_tied_heads_;
vector<Audio_element_info> heads_to_tie_;
bool ties_created_;
void stop_translation_timestep ();
void start_translation_timestep ();
virtual void acknowledge_audio_element (Audio_element_info);
+ virtual bool try_music (Music *);
void process_music ();
- DECLARE_TRANSLATOR_LISTENER (tie);
public:
TRANSLATOR_DECLARATIONS (Tie_performer);
};
Tie_performer::Tie_performer ()
{
event_ = 0;
+ last_event_ = 0;
ties_created_ = false;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Tie_performer, tie);
-void
-Tie_performer::listen_tie (Stream_event *ev)
+bool
+Tie_performer::try_music (Music *mus)
{
- event_ = ev;
+ if (mus->is_mus_type ("tie-event"))
+ event_ = mus;
+
+ return true;
}
void
{
if (Audio_note *an = dynamic_cast<Audio_note *> (inf.elem_))
{
- if (an->tie_event_)
- now_tied_heads_.push_back (inf);
- else
- now_heads_.push_back (inf);
-
+ now_heads_.push_back (inf);
for (vsize i = heads_to_tie_.size (); i--;)
{
- Stream_event *right_mus = inf.event_;
+ Music *right_mus = inf.event_;
Audio_note *th = dynamic_cast<Audio_note *> (heads_to_tie_[i].elem_);
- Stream_event *left_mus = heads_to_tie_[i].event_;
+ Music *left_mus = heads_to_tie_[i].event_;
if (right_mus && left_mus
&& ly_is_equal (right_mus->get_property ("pitch"),
if (ties_created_)
{
heads_to_tie_.clear ();
+ last_event_ = 0;
ties_created_ = false;
}
if (event_)
{
heads_to_tie_ = now_heads_;
+ last_event_ = event_;
}
-
- for (vsize i = now_tied_heads_.size(); i--;)
- heads_to_tie_.push_back (now_tied_heads_[i]);
-
event_ = 0;
now_heads_.clear ();
- now_tied_heads_.clear ();
}
+#include "translator.icc"
+
ADD_TRANSLATOR (Tie_performer,
/* doc */ "Generate ties between noteheads of equal pitch.",
/* create */ "",
#include "warn.hh"
-bool
-Tie::less (Grob *const &s1,
- Grob *const &s2)
+int
+Tie::compare (Grob *const &s1,
+ Grob *const &s2)
{
- return Tie::get_position (s1) < Tie::get_position (s2);
+ return sign (Tie::get_position (s1) - Tie::get_position (s2));
}
void
Bezier b;
int i = 0;
- for (SCM s = cp; scm_is_pair (s); s = scm_cdr (s))
+ for (SCM s = cp; s != SCM_EOL; s = scm_cdr (s))
{
b.control_[i] = ly_scm2offset (scm_car (s));
i++;
Erik Sandberg <mandolaerik@gmail.com>
*/
+#include "time-scaled-music-iterator.hh"
+
#include "context.hh"
#include "input.hh"
#include "international.hh"
#include "music.hh"
-#include "sequential-iterator.hh"
-
-/*
- Iterates \times, by sending TupletSpanEvents at the start/end of each
- tuplet bracket. Extra stop/start events are sent at regular
- intervals if tupletSpannerDuration is set.
-*/
-class Time_scaled_music_iterator : public Sequential_iterator
-{
-public:
- DECLARE_SCHEME_CALLBACK (constructor, ());
- /* construction */
- DECLARE_CLASSNAME(Time_scaled_music_iterator);
- Time_scaled_music_iterator ();
-protected:
- virtual SCM get_music_list () const;
- virtual void process (Moment m);
- virtual void construct_children ();
- virtual void derived_mark () const;
- virtual Moment pending_moment () const;
-private:
-
- /* tupletSpannerDuration */
- Moment spanner_duration_;
-
- /* next time to add a stop/start pair */
- Moment next_split_mom_;
-
- /* Recycle start/stop events if tupletSpannerDuration is set. */
- Music *start_;
- Music *stop_;
-};
Time_scaled_music_iterator::Time_scaled_music_iterator ()
{
- spanner_duration_ = next_split_mom_ = 0;
-}
-
-
-Moment
-Time_scaled_music_iterator::pending_moment () const
-{
- Moment next_mom = Sequential_iterator::pending_moment ();
-
- if (spanner_duration_.to_bool () &&
- next_mom.main_part_ > next_split_mom_)
- {
- next_mom = next_split_mom_;
- }
-
- return next_mom;
-}
-
-
-void
-Time_scaled_music_iterator::process (Moment m)
-{
- if (spanner_duration_.to_bool () &&
- m.main_part_ == next_split_mom_)
- {
- report_event (stop_);
- report_event (start_);
-
- next_split_mom_ += spanner_duration_;
- /* avoid sending events twice at the end */
- if (next_split_mom_ == get_music ()->get_length ().main_part_)
- next_split_mom_.set_infinite (1);
- }
- Sequential_iterator::process(m);
-}
-
-void
-Time_scaled_music_iterator::construct_children ()
-{
- /*
- Inheritance trickery:
- Time_scaled_music_iterator::construct_children initialises start_
- and stop_, and calls Sequential_music::construct_children, which
- in turn calls Time_scaled_music_iterator::get_music which reads
- start_ and stop_.
- */
-
- Music *mus = get_music ();
- Input *origin = mus->origin ();
-
- SCM tuplet_symbol = ly_symbol2scm ("TupletSpanEvent");
- SCM start_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START));
- start_ = unsmob_music (start_scm);
- start_->set_spot (*origin);
- start_->set_property ("numerator", mus->get_property ("numerator"));
- start_->set_property ("denominator", mus->get_property ("denominator"));
- start_->set_property ("tweaks", mus->get_property ("tweaks"));
-
-
- SCM stop_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP));
- stop_ = unsmob_music (stop_scm);
- stop_->set_spot (*origin);
-
- Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration"));
-
- if (mp)
- {
- spanner_duration_ = mp->main_part_;
- next_split_mom_ = spanner_duration_;
- }
-
- Sequential_iterator::construct_children ();
}
SCM
Time_scaled_music_iterator::get_music_list () const
{
Music *mus = get_music ();
- SCM child = mus->get_property ("element");
-
- return scm_list_3 (start_->self_scm (), child, stop_->self_scm ());
-}
-
-void
-Time_scaled_music_iterator::derived_mark () const
-{
- if (start_)
- scm_gc_mark (start_->self_scm ());
- if (stop_)
- scm_gc_mark (stop_->self_scm ());
-
- Sequential_iterator::derived_mark ();
+ Input *origin = mus->origin ();
+ Music *child = unsmob_music (mus->get_property ("element"));
+
+ /* Create tuplet start/stop span events before/after the music */
+ SCM tuplet_symbol = ly_symbol2scm ("TupletEvent");
+ SCM start_event = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START));
+ Music *start = unsmob_music (start_event);
+ start->set_spot (*origin);
+ start->set_property ("numerator", mus->get_property ("numerator"));
+ start->set_property ("denominator", mus->get_property ("denominator"));
+ start_event = scm_call_1 (ly_lily_module_constant ("make-event-chord"), scm_list_1 (start_event));
+ unsmob_music (start_event)->set_spot (*origin);
+
+ SCM stop_event = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP));
+ unsmob_music (stop_event)->set_spot (*origin);
+ stop_event = scm_call_1 (ly_lily_module_constant ("make-event-chord"), scm_list_1 (stop_event));
+ unsmob_music (stop_event)->set_spot (*origin);
+
+ return scm_list_3 (start_event, child->self_scm (), stop_event);
}
IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);
{
if (audio_)
{
+ play_element (audio_);
audio_ = 0;
}
}
{
context ()->add_alias (ly_symbol2scm ("Timing"));
context ()->set_property ("currentBarNumber", scm_from_int (1));
- context ()->set_property ("internalBarNumber", scm_from_int (1));
context ()->set_property ("timeSignatureFraction",
scm_cons (scm_from_int (4), scm_from_int (4)));
measposp += dt;
- int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0);
- int internal_barnumber = robust_scm2int (get_property ("internalBarNumber"), 0);
+ SCM barn = get_property ("currentBarNumber");
+ int b = 0;
+ if (scm_is_number (barn))
+ b = scm_to_int (barn);
SCM cad = get_property ("timing");
bool c = to_boolean (cad);
while (c && measposp.main_part_ >= len)
{
measposp.main_part_ -= len;
- current_barnumber ++;
- internal_barnumber ++;
+ b++;
}
- context ()->set_property ("currentBarNumber", scm_from_int (current_barnumber));
- context ()->set_property ("internalBarNumber", scm_from_int (internal_barnumber));
+ context ()->set_property ("currentBarNumber", scm_from_int (b));
context ()->set_property ("measurePosition", measposp.smobbed_copy ());
}
"@code{Staff}. "
"\n\nThis engraver adds the alias @code{Timing} to its containing context.",
- "", "",
-
- "internalBarNumber "
- "currentBarNumber "
- "measureLength "
- "measurePosition ",
-
- "internalBarNumber "
- "currentBarNumber "
- "measurePosition "
- );
+ "", "", "", "");
#include "context-def.hh"
#include "context.hh"
#include "dispatcher.hh"
-#include "engraver-group.hh"
#include "international.hh"
#include "main.hh"
#include "music.hh"
#include "output-def.hh"
-#include "performer-group.hh"
#include "scm-hash.hh"
#include "stream-event.hh"
#include "warn.hh"
Translator_group::connect_to_context (Context *c)
{
if (context_)
- {
- programming_error ("translator group is already connected to context "
- + context_->context_name ());
- }
-
+ programming_error ("already connected to a context");
context_ = c;
- c->event_source ()->add_listener (GET_LISTENER (create_child_translator),
- ly_symbol2scm ("AnnounceNewContext"));
- for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (tr_list))
- {
- Translator *tr = unsmob_translator (scm_car (tr_list));
- tr->connect_to_context (c);
- }
-}
-
-void
-Translator_group::disconnect_from_context ()
-{
- for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (tr_list))
- {
- Translator *tr = unsmob_translator (scm_car (tr_list));
- tr->disconnect_from_context (context_);
- }
- context_->event_source ()->remove_listener (GET_LISTENER (create_child_translator),
- ly_symbol2scm ("AnnounceNewContext"));
- context_ = 0;
- protected_events_ = SCM_EOL;
+ c->event_source ()->add_listener (GET_LISTENER (eat_event), ly_symbol2scm ("MusicEvent"));
}
void
{
}
-SCM
-filter_performers (SCM ell)
+bool
+translator_accepts_any_of (Translator *tr, SCM ifaces)
{
- SCM *tail = ℓ
- for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
- {
- if (dynamic_cast<Performer *> (unsmob_translator (scm_car (*tail))))
- *tail = scm_cdr (*tail);
- else
- tail = SCM_CDRLOC (*tail);
- }
- return ell;
+ SCM ack_ifs = scm_assoc (ly_symbol2scm ("events-accepted"),
+ tr->translator_description ());
+ ack_ifs = scm_cdr (ack_ifs);
+ for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
+ if (scm_c_memq (scm_car (s), ack_ifs) != SCM_BOOL_F)
+ return true;
+ return false;
}
SCM
-filter_engravers (SCM ell)
+find_accept_translators (SCM gravlist, SCM ifaces)
{
- SCM *tail = ℓ
- for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
+ SCM l = SCM_EOL;
+ for (SCM s = gravlist; scm_is_pair (s); s = scm_cdr (s))
{
- if (dynamic_cast<Engraver *> (unsmob_translator (scm_car (*tail))))
- *tail = scm_cdr (*tail);
- else
- tail = SCM_CDRLOC (*tail);
+ Translator *tr = unsmob_translator (scm_car (s));
+ if (translator_accepts_any_of (tr, ifaces))
+ l = scm_cons (tr->self_scm (), l);
}
- return ell;
-}
+ l = scm_reverse_x (l, SCM_EOL);
-/*
- Protects the parameter from being garbage collected. The object is
- protected until the next disconnect_from_context call.
-
- Whenever a child translator hears an event, the event is added to
- this list. This eliminates the need for derived_mark methods in most
- translators; all incoming events are instead protected by the
- translator group.
-
- TODO: Should the list also be flushed at the beginning of each new
- moment?
- */
-void
-Translator_group::protect_event (SCM ev)
-{
- protected_events_ = scm_cons (ev, protected_events_);
+ return l;
}
-/*
- Create a new translator for a newly created child context. Triggered
- by AnnounceNewContext events.
- */
-IMPLEMENT_LISTENER (Translator_group, create_child_translator);
+IMPLEMENT_LISTENER (Translator_group, eat_event);
void
-Translator_group::create_child_translator (SCM sev)
+Translator_group::eat_event (SCM sev)
{
Stream_event *ev = unsmob_stream_event (sev);
- // get from AnnounceNewContext
- SCM cs = ev->get_property ("context");
- Context *new_context = unsmob_context (cs);
- Context_def *def = unsmob_context_def (new_context->get_definition ());
- SCM ops = new_context->get_definition_mods ();
-
- SCM trans_names = def->get_translator_names (ops);
-
- Translator_group *g = get_translator_group (def->get_translator_group_type ());
- SCM trans_list = SCM_EOL;
-
- for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s))
- {
- Translator *type = get_translator (scm_car (s));
- if (!type)
- warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
- else
- {
- Translator *tr = type->clone ();
- SCM str = tr->self_scm ();
-
- if (tr->must_be_last ())
- {
- SCM cons = scm_cons (str, SCM_EOL);
- if (scm_is_pair (trans_list))
- scm_set_cdr_x (scm_last_pair (trans_list), cons);
- else
- trans_list = cons;
- }
- else
- trans_list = scm_cons (str, trans_list);
-
- tr->daddy_context_ = new_context;
- tr->unprotect ();
- }
- }
+ SCM sm = ev->get_property ("music");
+ Music *m = unsmob_music (sm);
+ try_music (m);
+}
- /* Filter unwanted translator types. Required to make
- \with {\consists "..."} work. */
- if (dynamic_cast<Engraver_group *> (g))
- g->simple_trans_list_ = filter_performers (trans_list);
- else if (dynamic_cast<Performer_group *> (g))
- g->simple_trans_list_ = filter_engravers (trans_list);
+bool
+Translator_group::try_music (Music *m)
+{
+ SCM name = scm_sloppy_assq (ly_symbol2scm ("name"),
+ m->get_property_alist (false));
- // TODO: scrap Context::implementation
- new_context->implementation_ = g;
+ if (!scm_is_pair (name))
+ return false;
- g->connect_to_context (new_context);
- g->unprotect ();
+ name = scm_cdr (name);
+ SCM accept_list = scm_hashq_ref (accept_hash_table_, name, SCM_UNDEFINED);
+ if (accept_list == SCM_BOOL_F)
+ {
+ accept_list = find_accept_translators (get_simple_trans_list (),
+ m->get_property ("types"));
+ scm_hashq_set_x (accept_hash_table_, name, accept_list);
+ }
- recurse_over_translators (new_context,
- &Translator::initialize,
- &Translator_group::initialize,
- DOWN);
+ for (SCM p = accept_list; scm_is_pair (p); p = scm_cdr (p))
+ {
+ Translator *t = unsmob_translator (scm_car (p));
+ if (t && t->try_music (m))
+ return true;
+ }
+
+ // We couldn't swallow the event in this context. Try parent.
+ Context *p = context ()->get_parent_context ();
+ // Global context's translator group is a dummy, so don't try it.
+ if (p->get_parent_context())
+ // ES todo: Make Translators listeners directly instead.
+ return p->implementation ()->try_music (m);
+ else
+ // We have tried all possible contexts. Give up.
+ m->origin ()->warning (_f ("junking event: `%s'", m->name ()));
+ return false;
}
SCM
Translator_group::Translator_group ()
{
simple_trans_list_ = SCM_EOL;
- protected_events_ = SCM_EOL;
+ accept_hash_table_ = SCM_EOL;
context_ = 0;
smobify_self ();
+
+ accept_hash_table_ = scm_c_make_hash_table (19);
}
void
Translator_group *me = (Translator_group *)SCM_CELL_WORD_1 (smob);
me->derived_mark ();
- scm_gc_mark (me->protected_events_);
+ scm_gc_mark (me->accept_hash_table_);
return me->simple_trans_list_;
}
#include "translator.hh"
+#include "warn.hh"
+#include "translator-group.hh"
#include "context-def.hh"
-#include "dispatcher.hh"
#include "global-context.hh"
-#include "international.hh"
-#include "translator-group.hh"
-#include "warn.hh"
#include "translator.icc"
#include "ly-smobs.icc"
must_be_last_ = src.must_be_last_;
}
+bool
+Translator::try_music (Music *)
+{
+ return false;
+}
+
Moment
Translator::now_mom () const
{
return daddy_context_->implementation ();
}
-void
-Translator::protect_event (SCM ev)
-{
- get_daddy_translator ()->protect_event (ev);
-}
-
SCM
Translator::internal_get_property (SCM sym) const
{
}
/*
- this function is called once each moment, before any user
- information enters the translators. (i.e. no \property or event has
- been processed yet.)
+ this function has 2 properties
+
+ - It is called before try_music ()
+
+ - It is called before any user information enters the translators.
+ (i.e. any \property or event is not processed yet.)
*/
void
Translator::start_translation_timestep ()
{
}
-void
-Translator::connect_to_context (Context *c)
-{
- for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
- c->events_below ()->add_listener (r->get_listener_ (this), r->event_class_);
-}
-
-void
-Translator::disconnect_from_context (Context *c)
-{
- for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
- c->events_below ()->remove_listener (r->get_listener_ (this), r->event_class_);
-}
-
-static SCM listened_event_class_table;
-void
-ensure_listened_hash ()
-{
- if (!listened_event_class_table)
- listened_event_class_table = scm_permanent_object (scm_c_make_hash_table (61));
-}
-
-
-LY_DEFINE (ly_get_listened_event_classes, "ly:get-listened-event-classes",
- 0, 0, 0, (),
- "Returns a list of all event classes that some translator listens to.")
-{
- ensure_listened_hash ();
- return ly_hash_table_keys (listened_event_class_table);
-}
-
-LY_DEFINE (ly_is_listened_event_class, "ly:is-listened-event-class",
- 1, 0, 0, (SCM sym),
- "Is @var{sym} a listened event class?")
-{
- ensure_listened_hash ();
- return scm_hashq_ref (listened_event_class_table, sym, SCM_BOOL_F);
-}
-
-void
-add_listened_event_class (SCM sym)
-{
- ensure_listened_hash ();
- scm_hashq_set_x (listened_event_class_table, sym, SCM_BOOL_T);
-}
-
-
-/*
- internally called once, statically, for each translator
- listener. Connects the name of an event class with a procedure that
- fetches the corresponding listener.
-
- The method should only be called from the macro
- IMPLEMENT_TRANSLATOR_LISTENER.
- */
-void
-Translator::add_translator_listener (translator_listener_record **listener_list,
- translator_listener_record *r,
- Listener (*get_listener) (void *),
- const char *ev_class)
-{
- /* ev_class is the C++ identifier name. Convert to scm symbol */
- string name = string (ev_class);
- name = replace_all (name, '_', '-');
- name += "-event";
-
- SCM class_sym = scm_str2symbol (name.c_str ());
-
- add_listened_event_class (class_sym);
-
- r->event_class_ = class_sym;
- r->get_listener_ = get_listener;
- r->next_ = *listener_list;
- *listener_list = r;
-}
-
-/*
- Used by ADD_THIS_TRANSLATOR to extract a list of event-class names
- for each translator. This list is used by the internals
- documentation.
-*/
-SCM
-Translator::get_listened_class_list (const translator_listener_record *listeners) const
-{
- SCM list = SCM_EOL;
- for (; listeners; listeners = listeners->next_)
- list = scm_cons (listeners->event_class_, list);
- return list;
-}
-
/*
SMOBS
*/
return daddy_context_->get_global_context ();
}
-Context *
+Score_context *
Translator::get_score_context () const
{
return daddy_context_->get_score_context ();
interface_name = replace_all (interface_name, '_', '-');
interface_name += "-interface";
- /*
- this is only called during program init, so safe to use scm_gc_protect_object()
- */
inf.symbol_ = scm_gc_protect_object (ly_symbol2scm (interface_name.c_str ()));
ack_array->push_back (inf);
}
return 0;
}
-Moment
-get_event_length (Stream_event *e)
-{
- Moment *m = unsmob_moment (e->get_property ("length"));
- if (m)
- return *m;
- else
- return Moment (0);
-}
-
-/*
- Helper, used through ASSIGN_EVENT_ONCE to throw warnings for
- simultaneous events. The helper is only useful in listen_* methods
- of translators.
-*/
-bool
-internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function)
-{
- if (*old_ev)
- {
- /* extract event class from function name */
- const char *prefix = "listen_";
- string ev_class = function;
- /* This assertion fails if EVENT_ASSIGNMENT was called outside a
- translator listener. Don't do that. */
- assert (0 == ev_class.find (prefix));
-
- /* "listen_foo_bar" -> "foo-bar" */
- ev_class.erase (0, strlen(prefix));
- replace_all (ev_class, '_', '-');
-
- new_ev->origin ()->warning (_f ("Two simultaneous %s events, junking this one", ev_class.c_str ()));
- (*old_ev)->origin ()->warning (_f ("Previous %s event here", ev_class.c_str ()));
- return false;
- }
- else
- {
- *old_ev = new_ev;
- return true;
- }
-}
-
ADD_TRANSLATOR (Translator,
"Base class. Unused",
"",
#include "international.hh"
#include "note-column.hh"
#include "side-position-interface.hh"
-#include "stream-event.hh"
#include "translator.icc"
protected:
virtual void finalize ();
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (trill_span);
+ virtual bool try_music (Music *);
void stop_translation_timestep ();
void process_music ();
private:
Spanner *span_;
Spanner *finished_;
- Stream_event *current_event_;
- Drul_array<Stream_event *> event_drul_;
+ Music *current_event_;
+ Drul_array<Music *> event_drul_;
void typeset_all ();
};
event_drul_[STOP] = 0;
}
-IMPLEMENT_TRANSLATOR_LISTENER (Trill_spanner_engraver, trill_span);
-void
-Trill_spanner_engraver::listen_trill_span (Stream_event *ev)
+bool
+Trill_spanner_engraver::try_music (Music *m)
{
- Direction d = to_dir (ev->get_property ("span-direction"));
- ASSIGN_EVENT_ONCE (event_drul_[d], ev);
+ if (m->is_mus_type ("trill-span-event"))
+ {
+ Direction d = to_dir (m->get_property ("span-direction"));
+ event_drul_[d] = m;
+ return true;
+ }
+
+ return false;
}
void
typeset_all ();
if (span_)
{
- finished_ = span_;
- typeset_all ();
+ current_event_->origin ()->warning (_ ("unterminated trill spanner"));
+ span_->suicide ();
+ span_ = 0;
}
}
ADD_ACKNOWLEDGER (Trill_spanner_engraver, note_column);
ADD_TRANSLATOR (Trill_spanner_engraver,
- /* doc */ "Create trill spanner from an event.",
+ /* doc */ "Create trill spanner from a Music.",
/* create */ "TrillSpanner",
/* accept */ "trill-span-event",
/* read */ "",
= robust_scm2drul (me->internal_get_property (sym), zero);
pair[xdir] = 0.0;
- me->set_property (sym, ly_interval2scm (pair));
+ me->internal_set_property (sym, ly_interval2scm (pair));
}
-/*
- Return beam that encompasses the span of the tuplet bracket.
-*/
-
Grob *
-Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols,
- bool *equally_long)
+Tuplet_bracket::parallel_beam (Grob *me_grob, vector<Grob*> const &cols, bool *equally_long)
{
Spanner *me = dynamic_cast<Spanner *> (me_grob);
}
*equally_long =
- (beam_stems[0] == stems[LEFT]
- && beam_stems.back () == stems[RIGHT]);
+ (beam_stems[0] == stems[LEFT] && beam_stems.back () == stems[RIGHT]);
return beams[LEFT];
}
if (!par_beam
|| get_grob_direction (par_beam) != dir)
calc_position_and_height (me, &offset, &dy);
- else if (columns.size ()
- && Note_column::get_stem (columns[0])
- && Note_column::get_stem (columns.back ()))
+ else
{
- /*
- trigger set_stem_ends
- */
- (void) par_beam->get_property ("quantized-positions");
-
+ SCM ps = par_beam->get_property ("positions");
- Drul_array<Grob *> stems (Note_column::get_stem (columns[0]),
- Note_column::get_stem (columns.back ()));
-
-
-
-
- Real ss = 0.5 * Staff_symbol_referencer::staff_space (me);
- Real lp = ss * robust_scm2double (stems[LEFT]->get_property ("stem-end-position"), 0.0);
- Real rp = ss * robust_scm2double (stems[RIGHT]->get_property ("stem-end-position"), 0.0);
+ Real lp = scm_to_double (scm_car (ps));
+ Real rp = scm_to_double (scm_cdr (ps));
+ Real ss = Staff_symbol_referencer::staff_space (me);
offset = lp + dir * (0.5 + scm_to_double (me->get_property ("padding")));
dy = (rp - lp);
+
+ dy *= ss;
+ offset *= ss;
}
(c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
*/
+#include "tuplet-bracket.hh"
+#include "note-column.hh"
#include "beam.hh"
#include "engraver.hh"
-#include "international.hh"
-#include "note-column.hh"
#include "spanner.hh"
-#include "stream-event.hh"
-#include "tuplet-bracket.hh"
-#include "warn.hh"
#include "translator.icc"
struct Tuplet_description
{
- Stream_event *event_;
+ Music *music_;
Spanner *bracket_;
Spanner *number_;
-
- bool full_length_;
- bool full_length_note_;
-
Tuplet_description ()
{
- event_ = 0;
- full_length_note_ = false;
- full_length_ = false;
+ music_ = 0;
bracket_ = 0;
number_ = 0;
}
vector<Tuplet_description> stopped_tuplets_;
vector<Spanner*> last_tuplets_;
DECLARE_ACKNOWLEDGER (note_column);
- DECLARE_TRANSLATOR_LISTENER (tuplet_span);
+ virtual bool try_music (Music *r);
virtual void finalize ();
void start_translation_timestep ();
void process_music ();
};
-IMPLEMENT_TRANSLATOR_LISTENER (Tuplet_engraver, tuplet_span);
-void
-Tuplet_engraver::listen_tuplet_span (Stream_event *ev)
+bool
+Tuplet_engraver::try_music (Music *music)
{
- Direction dir = to_dir (ev->get_property ("span-direction"));
- if (dir == START)
+ if (music->is_mus_type ("tuplet-spanner-event"))
{
- Tuplet_description d;
- d.event_ = ev;
- tuplets_.push_back (d);
- }
- else if (dir == STOP && tuplets_.size ())
- {
- stopped_tuplets_.push_back (tuplets_.back ());
- tuplets_.pop_back ();
+ Direction dir = to_dir (music->get_property ("span-direction"));
+ if (dir == START)
+ {
+ Tuplet_description d;
+ d.music_ = music;
+ tuplets_.push_back (d);
+ }
+ if (dir == STOP)
+ {
+ stopped_tuplets_.push_back (tuplets_.back ());
+ tuplets_.pop_back ();
+ }
+ return true;
}
- else
- programming_error (_ ("invalid direction of tuplet-span-event"));
+ return false;
}
void
{
for (vsize i = 0; i < stopped_tuplets_.size (); i++)
{
+ bool full_length = to_boolean (get_property ("tupletFullLength"));
if (stopped_tuplets_[i].bracket_)
{
- if (stopped_tuplets_[i].full_length_)
+ if (full_length)
{
- Item *col =
- unsmob_item (stopped_tuplets_[i].full_length_note_
- ? get_property ("currentMusicalColumn")
- : get_property ("currentCommandColumn"));
+ Item *col = unsmob_item (get_property ("currentMusicalColumn"));
stopped_tuplets_[i].bracket_->set_bound (RIGHT, col);
stopped_tuplets_[i].number_->set_bound (RIGHT, col);
/* i goes from size-1 downto 0, inclusively */
vsize i = j - 1;
-
if (tuplets_[i].bracket_)
continue;
- tuplets_[i].full_length_ = to_boolean (get_property ("tupletFullLength"));
- tuplets_[i].full_length_note_
- = to_boolean (get_property ("tupletFullLengthNote"));
-
tuplets_[i].bracket_ = make_spanner ("TupletBracket",
- tuplets_[i].event_->self_scm ());
+ tuplets_[i].music_->self_scm ());
tuplets_[i].number_ = make_spanner ("TupletNumber",
- tuplets_[i].event_->self_scm ());
+ tuplets_[i].music_->self_scm ());
tuplets_[i].number_->set_object ("bracket", tuplets_[i].bracket_->self_scm ());
tuplets_[i].bracket_->set_object ("tuplet-number", tuplets_[i].number_->self_scm ());
if (i > 0 && tuplets_[i - 1].bracket_)
Tuplet_bracket::add_tuplet_bracket (tuplets_[i - 1].bracket_, tuplets_[i].bracket_);
+
+ SCM proc = get_property ("tupletNumberFormatFunction");
+ if (ly_is_procedure (proc))
+ {
+ SCM t = scm_apply_0 (proc, scm_list_1 (tuplets_[i].music_->self_scm ()));
+ tuplets_[i].number_->set_property ("text", t);
+ }
}
}
Tuplet_engraver::finalize ()
{
if (to_boolean (get_property ("tupletFullLength")))
- for (vsize i = 0; i < last_tuplets_.size (); i++)
- {
- Item *col = unsmob_item (get_property ("currentCommandColumn"));
- last_tuplets_[i]->set_bound (RIGHT, col);
- }
+ {
+ for (vsize i = 0; i < last_tuplets_.size (); i++)
+ {
+ Item *col = unsmob_item (get_property ("currentCommandColumn"));
+ last_tuplets_[i]->set_bound (RIGHT, col);
+ }
+ }
}
Tuplet_engraver::Tuplet_engraver ()
ADD_ACKNOWLEDGER (Tuplet_engraver, note_column);
ADD_TRANSLATOR (Tuplet_engraver,
/* doc */ "Catch TupletSpannerEvent and generate appropriate bracket ",
- /* create */
- "TupletBracket "
- "TupletNumber ",
- /* accept */ "tuplet-span-event",
- /* read */
- "tupletFullLength "
- "tupletFullLengthNote ",
+ /* create */ "TupletBracket TupletNumber ",
+ /* accept */ "tuplet-spanner-event",
+ /* read */ "tupletNumberFormatFunction tupletSpannerDuration tupletFullLength ",
/* write */ "");
me->suicide ();
return SCM_EOL;
}
-
- SCM stc_scm = Text_interface::print (smob);
- Stencil *stc = unsmob_stencil (stc_scm);
+
+ Stencil *stc = unsmob_stencil (Text_interface::print (smob));
stc->align_to (X_AXIS, CENTER);
stc->align_to (Y_AXIS, CENTER);
stc->translate ((points[RIGHT] + points[LEFT]) / 2);
- return stc_scm;
+ return stc->smobbed_copy ();
}
#include "engraver.hh"
+#include "music.hh"
#include "grob.hh"
-#include "stream-event.hh"
#include "translator.icc"
class Tweak_engraver : public Engraver
void
Tweak_engraver::acknowledge_grob (Grob_info info)
{
- if (Stream_event *ev = info.event_cause ())
+ if (Music *music = info.music_cause ())
{
- for (SCM s = ev->get_property ("tweaks");
+ for (SCM s = music->get_property ("tweaks");
scm_is_pair (s); s = scm_cdr (s))
{
- info.grob ()->set_property (scm_caar (s), scm_cdar (s));
+ info.grob ()->internal_set_property (scm_caar (s), scm_cdar (s));
}
}
}
ADD_ACKNOWLEDGER (Tweak_engraver, grob);
ADD_TRANSLATOR (Tweak_engraver,
- /* doc */ "Read the @code{tweaks} property from the originating event, and set properties." ,
+ /* doc */ "Read the @code{tweaks} property from the originating Music event, and set properties." ,
/* create */ "",
/* accept */ "",
#include "paper-column.hh"
#include "spanner.hh"
#include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
#include "vaticana-ligature.hh"
#include "warn.hh"
virtual Spanner *create_ligature_spanner ();
virtual void transform_heads (Spanner *ligature,
vector<Grob_info> primitives);
- DECLARE_TRANSLATOR_LISTENER (pes_or_flexa);
- DECLARE_TRANSLATOR_LISTENER (ligature);
};
-IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, pes_or_flexa);
-void
-Vaticana_ligature_engraver::listen_pes_or_flexa (Stream_event *ev)
-{
- Gregorian_ligature_engraver::listen_pes_or_flexa (ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, ligature);
-void
-Vaticana_ligature_engraver::listen_ligature (Stream_event *ev)
-{
- Ligature_engraver::listen_ligature (ev);
-}
-
Vaticana_ligature_engraver::Vaticana_ligature_engraver ()
{
brew_ligature_primitive_proc =
int delta_pitch = 0;
if (prev_primitive) /* urgh, need prev_primitive only here */
{
- SCM delta_pitch_scm = prev_primitive->get_property ("delta-position");
+ SCM delta_pitch_scm = prev_primitive->get_property ("delta-pitch");
if (delta_pitch_scm != SCM_EOL)
delta_pitch = scm_to_int (delta_pitch_scm);
else
{
primitive->programming_error ("Vaticana_ligature:"
- "delta-position undefined -> "
+ "delta-pitch undefined -> "
"ignoring grob");
continue;
}
Item *primitive = dynamic_cast<Item *> (primitives[i].grob ());
int delta_pitch;
- SCM delta_pitch_scm = primitive->get_property ("delta-position");
+ SCM delta_pitch_scm = primitive->get_property ("delta-pitch");
if (delta_pitch_scm != SCM_EOL)
delta_pitch = scm_to_int (delta_pitch_scm);
else
{
primitive->programming_error ("Vaticana_ligature:"
- "delta-position undefined -> "
+ "delta-pitch undefined -> "
"ignoring grob");
continue;
}
int pos = Staff_symbol_referencer::get_rounded_position (me);
- SCM delta_pitch_scm = me->get_property ("delta-position");
+ SCM delta_pitch_scm = me->get_property ("delta-pitch");
int delta_pitch;
if (delta_pitch_scm != SCM_EOL)
delta_pitch = scm_to_int (delta_pitch_scm);
"add-cauda "
"add-stem "
"add-join "
- "delta-position "
+ "delta-pitch "
"x-offset "
);
"them vertically.",
/* create */ "VerticalAlignment",
/* accept */ "",
- /* read */ "alignAboveContext alignBelowContext",
+ /* read */ "",
/* write */ "");
Vertical_align_engraver::Vertical_align_engraver ()
TRANSLATOR_DECLARATIONS (Volta_engraver);
protected:
- DECLARE_END_ACKNOWLEDGER (staff_symbol);
DECLARE_ACKNOWLEDGER (staff_symbol);
DECLARE_ACKNOWLEDGER (note_column);
DECLARE_ACKNOWLEDGER (bar_line);
Volta_bracket_interface::add_bar (end_volta_span_, i.item ());
}
-void
-Volta_engraver::acknowledge_end_staff_symbol (Grob_info i)
-{
- if (i.grob ()->self_scm () == staff_)
- staff_ = SCM_EOL;
-}
-
void
Volta_engraver::acknowledge_staff_symbol (Grob_info i)
{
staff_ = i.grob ()->self_scm ();
}
-
void
Volta_engraver::finalize ()
{
TODO: should attach volta to paper-column if no bar is found.
*/
ADD_ACKNOWLEDGER (Volta_engraver, staff_symbol);
-ADD_END_ACKNOWLEDGER (Volta_engraver, staff_symbol);
ADD_ACKNOWLEDGER (Volta_engraver, note_column);
ADD_ACKNOWLEDGER (Volta_engraver, bar_line);
ADD_TRANSLATOR (Volta_engraver,
&& current_reps == SCM_EOL || scm_is_pair (current_reps))
{
current_reps = scm_cons (what, current_reps);
- where->set_property (reps, current_reps);
+ where->internal_set_property (reps, current_reps);
}
}
depth = ..
-INI_FILES = $(LY_FILES)
+INI_FILES = $(FLY_FILES) $(SLY_FILES) $(LY_FILES)
EXTRA_DIST_FILES = $(SCM_FILES)
INSTALLATION_DIR=$(local_lilypond_datadir)/ly/
(make-music 'PageBreakEvent 'break-permission 'force)
(make-music 'PageTurnEvent 'break-permission 'force)))
noPageTurn = #(make-event-chord (list (make-music 'PageTurnEvent 'break-permission '())))
-allowPageTurn = #(make-event-chord (list (make-music 'PageTurnEvent 'break-permission 'allow)))
stopStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent STOP)))
startStaff = #(make-event-chord (list (make-span-event 'StaffSpanEvent START)))
\include "scale-definitions-init.ly"
-melisma = #(context-spec-music (make-property-set 'melismaBusy #t) 'Bottom)
-melismaEnd = #(context-spec-music (make-property-unset 'melismaBusy) 'Bottom)
-
+melisma = #(make-span-event 'ManualMelismaEvent START)
+melismaEnd = #(make-span-event 'ManualMelismaEvent STOP)
laissezVibrer = #(make-music 'LaissezVibrerEvent)
repeatTie = #(make-music 'RepeatTieEvent)
\context {
\Score
skipTypesetting = ##t
- ignoreBarChecks = ##t
- \alias "Timing"
+ ignoreBarChecks = ##t
}
}
%{
English note names spelled out in full, and abbreviated
-
- ff for double-flat
- tqf for three-quarters flat
- f for flat
- qf for quarter-flat
-
- qs for quarter-sharp
- s for sharp
- tqs for three-quarters sharp
- x for double-sharp
+ with s for sharp and f for flat.
%}
pitchnamesEnglish = #`(
(bsharpsharp . ,(ly:make-pitch -1 6 DOUBLE-SHARP))
(cff . ,(ly:make-pitch -1 0 DOUBLE-FLAT))
- (ctqf . ,(ly:make-pitch -1 0 THREE-Q-FLAT))
(cf . ,(ly:make-pitch -1 0 FLAT))
- (cqf . ,(ly:make-pitch -1 0 SEMI-FLAT))
(c . ,(ly:make-pitch -1 0 NATURAL))
- (cqs . ,(ly:make-pitch -1 0 SEMI-SHARP))
(cs . ,(ly:make-pitch -1 0 SHARP))
- (ctqs . ,(ly:make-pitch -1 0 THREE-Q-SHARP))
(css . ,(ly:make-pitch -1 0 DOUBLE-SHARP))
(cx . ,(ly:make-pitch -1 0 DOUBLE-SHARP))
-
(dff . ,(ly:make-pitch -1 1 DOUBLE-FLAT))
- (dtqf . ,(ly:make-pitch -1 1 THREE-Q-FLAT))
(df . ,(ly:make-pitch -1 1 FLAT))
- (dqf . ,(ly:make-pitch -1 1 SEMI-FLAT))
(d . ,(ly:make-pitch -1 1 NATURAL))
- (dqs . ,(ly:make-pitch -1 1 SEMI-SHARP))
(ds . ,(ly:make-pitch -1 1 SHARP))
- (dtqs . ,(ly:make-pitch -1 1 THREE-Q-SHARP))
(dss . ,(ly:make-pitch -1 1 DOUBLE-SHARP))
(dx . ,(ly:make-pitch -1 1 DOUBLE-SHARP))
-
(eff . ,(ly:make-pitch -1 2 DOUBLE-FLAT))
- (etqf . ,(ly:make-pitch -1 2 THREE-Q-FLAT))
(ef . ,(ly:make-pitch -1 2 FLAT))
- (eqf . ,(ly:make-pitch -1 2 SEMI-FLAT))
(e . ,(ly:make-pitch -1 2 NATURAL))
- (eqs . ,(ly:make-pitch -1 2 SEMI-SHARP))
- (es . ,(ly:make-pitch -1 2 SHARP))
- (etqs . ,(ly:make-pitch -1 2 THREE-Q-SHARP))
+
+ (es . ,(ly:make-pitch -1 2 SHARP))
(ess . ,(ly:make-pitch -1 2 DOUBLE-SHARP))
(ex . ,(ly:make-pitch -1 2 DOUBLE-SHARP))
-
(fff . ,(ly:make-pitch -1 3 DOUBLE-FLAT))
- (ftqf . ,(ly:make-pitch -1 3 THREE-Q-FLAT))
(ff . ,(ly:make-pitch -1 3 FLAT))
- (fqf . ,(ly:make-pitch -1 3 SEMI-FLAT))
(f . ,(ly:make-pitch -1 3 NATURAL))
- (fqs . ,(ly:make-pitch -1 3 SEMI-SHARP))
(fs . ,(ly:make-pitch -1 3 SHARP))
- (ftqs . ,(ly:make-pitch -1 3 THREE-Q-SHARP))
(fss . ,(ly:make-pitch -1 3 DOUBLE-SHARP))
(fx . ,(ly:make-pitch -1 3 DOUBLE-SHARP))
-
(gff . ,(ly:make-pitch -1 4 DOUBLE-FLAT))
- (gtqf . ,(ly:make-pitch -1 4 THREE-Q-FLAT))
(gf . ,(ly:make-pitch -1 4 FLAT))
- (gqf . ,(ly:make-pitch -1 4 SEMI-FLAT))
(g . ,(ly:make-pitch -1 4 NATURAL))
- (gqs . ,(ly:make-pitch -1 4 SEMI-SHARP))
(gs . ,(ly:make-pitch -1 4 SHARP))
- (gtqs . ,(ly:make-pitch -1 4 THREE-Q-SHARP))
(gss . ,(ly:make-pitch -1 4 DOUBLE-SHARP))
(gx . ,(ly:make-pitch -1 4 DOUBLE-SHARP))
-
(aff . ,(ly:make-pitch -1 5 DOUBLE-FLAT))
- (atqf . ,(ly:make-pitch -1 5 THREE-Q-FLAT))
(af . ,(ly:make-pitch -1 5 FLAT))
- (aqf . ,(ly:make-pitch -1 5 SEMI-FLAT))
(a . ,(ly:make-pitch -1 5 NATURAL))
- (aqs . ,(ly:make-pitch -1 5 SEMI-SHARP))
(as . ,(ly:make-pitch -1 5 SHARP))
- (atqs . ,(ly:make-pitch -1 5 THREE-Q-SHARP))
(ass . ,(ly:make-pitch -1 5 DOUBLE-SHARP))
(ax . ,(ly:make-pitch -1 5 DOUBLE-SHARP))
-
(bff . ,(ly:make-pitch -1 6 DOUBLE-FLAT))
- (btqf . ,(ly:make-pitch -1 6 THREE-Q-FLAT))
(bf . ,(ly:make-pitch -1 6 FLAT))
- (bqf . ,(ly:make-pitch -1 6 SEMI-FLAT))
(b . ,(ly:make-pitch -1 6 NATURAL))
- (bqs . ,(ly:make-pitch -1 6 SEMI-SHARP))
(bs . ,(ly:make-pitch -1 6 SHARP))
- (btqs . ,(ly:make-pitch -1 6 THREE-Q-SHARP))
(bss . ,(ly:make-pitch -1 6 DOUBLE-SHARP))
(bx . ,(ly:make-pitch -1 6 DOUBLE-SHARP))
)
verticalExtent = ##f
localKeySignature = #'()
createSpacing = ##t
- ignoreFiguredBassRest = ##t
%% explicitly set instrument, so we don't get
%% weird effects when doing instrument names for
%% piano staves
- instrumentName = #'()
- shortInstrumentName = #'()
+ instrument = #'()
+ instr = #'()
\defaultchild "Voice"
\accepts "Voice"
\consists "System_start_delimiter_engraver"
systemStartDelimiter = #'SystemStartBracket
vocalName = #'()
- shortVocalName = #'()
+ vocNam = #'()
\accepts "Staff"
\accepts "DrumStaff"
\consists "Time_signature_engraver"
\consists "Instrument_name_engraver"
\consists "Axis_group_engraver"
- \consists "Ledger_line_engraver"
\accepts "Voice"
\accepts "CueVoice"
\consists "Ligature_bracket_engraver"
\consists "Breathing_sign_engraver"
\consists "Note_heads_engraver"
- \consists "Dots_engraver"
\consists "Rest_engraver"
%% switch on to make stem directions interpolate for the
\consists "Beam_engraver"
\consists "Grace_beam_engraver"
\consists "Auto_beam_engraver"
-
- %% must come before Script_column_engraver.
\consists "New_fingering_engraver"
-
\consists "Chord_tremolo_engraver"
\consists "Percent_repeat_engraver"
\consists "Slash_repeat_engraver"
+ \consists "Melisma_translator"
\consists "Part_combine_engraver"
\consists "Text_engraver"
\consists "Dynamic_engraver"
\consists "Fingering_engraver"
- \consists "Bend_after_engraver"
\consists "Script_engraver"
\consists "Script_column_engraver"
\consists "Tie_engraver"
\consists "Tuplet_engraver"
\consists "Grace_engraver"
- \consists "Instrument_switch_engraver"
+
\consists "Skip_event_swallow_translator"
}
systemStartDelimiter = #'SystemStartBrace
\accepts "Staff"
- \accepts "FiguredBass"
}
\context{
\consists "Vertical_align_engraver"
\consists "Instrument_name_engraver"
- instrumentName = #'()
- shortInstrumentName = #'()
+ instrument = #'()
+ instr = #'()
}
\context {
\description " Corresponds to a voice with lyrics. Handles the
printing of a single line of lyrics. "
- \name "Lyrics"
+ \name Lyrics
\consists "Lyric_engraver"
\consists "Extender_engraver"
\consists "Hyphen_engraver"
\consists "Metronome_mark_engraver"
\consists "Break_align_engraver"
\consists "Spacing_engraver"
- \consists "Grace_spacing_engraver"
\consists "Vertical_align_engraver"
\consists "Stanza_number_align_engraver"
\consists "Bar_number_engraver"
harmonicAccidentals = ##t
fingeringOrientations = #'(up down)
stringNumberOrientations = #'(up down)
+ tupletNumberFormatFunction = #denominator-tuplet-formatter
markFormatter = #format-mark-letters
rehearsalMark = #1
subdivideBeams = ##f
\alias "Staff"
\name "TabStaff"
\denies "Voice"
+ \remove "Staff_symbol_engraver"
\consists "Tab_staff_symbol_engraver"
\description "Context for generating tablature. [DOCME]"
-%{
- Shortcuts common for all styles of gregorian chant notation.
- $Id: gregorian-init.ly,v 1.46 2006/06/06 21:19:17 reuter Exp $
-%}
-
\version "2.7.39"
-%
-% Declare memorable shortcuts for special unicode characters
-% that are used in chant notation.
-%
-
-% unicode 0132 (latin capital ligature IJ)
-IJ = \lyricmode { IJ }
-IIJ = \lyricmode { IIJ }
-
-% unicode 0133 (latin small ligature ij)
-ij = \lyricmode { ij }
-iij = \lyricmode { iij }
+%%%%%%%%
+%%%%%%%% shortcuts common for all styles of gregorian chant notation
+%%%%%%%%
%
-% Given some music that represents lyrics, add a prefix to the first
-% lyric event.
-%
-% TODO: Robustify this function. For example, this function works
-% correctly for "\versus { some lyrics }", but it barfs with a wrong type
-% argument error for e.g. "\versus some lyrics".
-%
-#(define (add-prefix-to-lyrics prefix music)
- (make-music
- 'SequentialMusic
- 'elements (append
- (cons
- (let* ((elems (car (ly:music-property music 'elements)))
- (props (ly:music-mutable-properties elems))
- (events (filter (lambda (x)
- (equal? (car x) 'elements))
- props))
- (first-evt (cadar events))
- (first-syllable (ly:prob-property first-evt 'text))
- (first-duration (ly:prob-property first-evt 'duration)))
- (make-music
- 'LyricEvent
- 'duration first-duration
- 'text (string-append prefix first-syllable)))
- (cdr (ly:music-property music 'elements))))))
-
-% Add unicode 2123 (versicle) as prefix to lyrics.
-versus =
-#(define-music-function (parser location music) (ly:music?)
- (add-prefix-to-lyrics "℣" music))
-
-% Add unicode 211F (response) as prefix to lyrics.
-responsum =
-#(define-music-function (parser location music) (ly:music?)
- (add-prefix-to-lyrics "℟" music))
-
-%
-% Declare head prefix shortcuts.
+% declare head prefix shortcuts
%
virga =
\once \override NoteHead #'virga = ##t
\once \override NoteHead #'cavum = ##t
%
-% Declare divisiones shortcuts.
+% declare divisiones shortcuts
%
virgula = {
\once \override BreathingSign #'text = #(make-musicglyph-markup "scripts.rcomma")
\breathe
}
+augmentum = {
+ %%% TODO: A ligature head postfix that indicates that an
+ %%% augmentum dot should be appended to the right end of
+ %%% the surrounding ligature. [Not yet implemented.]
+}
+
%
-% Declare articulation shortcuts.
+% declare articulation shortcuts
%
accentus = #(make-articulation "accentus")
ictus = #(make-articulation "ictus")
circulus = #(make-articulation "circulus")
episemInitium = #(make-span-event 'TextSpanEvent START)
episemFinis = #(make-span-event 'TextSpanEvent STOP)
-augmentum = {
- %%% TODO: A ligature head postfix that indicates that an
- %%% augmentum dot should be appended to the right end of
- %%% the surrounding ligature. [Not yet implemented.]
-}
-
%
-% Declare shortcut music functions for Liber Hymnarius neumes
-% table (experimental).
+% shortcut music functions for Liber Hymnarius neumes table
+% (experimental)
%
#(define (make-ligature music)
% 'LigatureStopEvent))))
%climacus = #(def-climacus-function startSequentialMusic stopSequentialMusic)
-%
-% Declare default layout; here for Vaticana style. In case there will
-% be additional styles, we may want to create style-specific .ly files
-% for inclusion (e.g. vaticana-init.ly), move the style-dependent stuff
-% over there, leave the style-independent Gregorian stuff here, and let
-% the style-specific file (vaticana-init.ly) include this file. The
-% user then will have to include vaticana-init.ly instead of
-% gregorian-init.ly.
-%
\layout {
indent = 0.0
packed = ##t
}
%
-% neumeDemoLayout defines a layout block suitable for notating pure
-% Vaticana style neumes without any other notation symbols such as
-% staff lines or clefs. This layout is useful for engraving neumes
-% tables, such as that one in the lilypond manual section on
-% Gregorian ligatures, or for educational works.
+% example layout block for gregorian chant notation
%
+
neumeDemoLayout = \layout {
interscoreline = 1
\context {
\override Stem #'transparent = ##t
}
}
-
-%%% Local Variables:
-%%% coding: utf-8
-%%% End:
#(define toplevel-scores '())
#(define output-count 0)
#(define $defaultheader #f)
-#(define version-seen #f)
+#(define version-seen? #f)
\maininput
%% there is a problem at the end of the input file
(not (ly:get-option 'old-relative-used)))
(old-relative-not-used-message input-file-name))%% there is a problem at the end of the input file
-#(if (and (not version-seen)
+#(if (and (not version-seen?)
(defined? 'input-file-name))
(version-not-seen-message input-file-name))
+++ /dev/null
-
-\version "2.9.9"
-
-#(set! toplevel-score-handler print-score-with-defaults)
-#(set! toplevel-music-handler
- (lambda (p m)
- (if (not (eq? (ly:music-property m 'void) #t))
- (print-score-with-defaults
- p (scorify-music m p)))))
-
-#(ly:set-option (quote no-point-and-click))
-#(define inside-lilypond-book #t)
-#(define version-seen #t)
\version "2.7.39"
\midi {
+ \tempo 4=60
\include "performer-init.ly"
}
% -*-Scheme-*-
-\version "2.9.12"
+\version "2.7.39"
%% need SRFI-1 filter
#(use-modules (srfi srfi-1))
-%% FIXME: guile-1.7 required?
-%#(use-modules (scm display-lily))invalid module name for use-syntax ((srfi srfi-39))
-#(use-modules (scm display-lily))
-#(display-lily-init parser)
+tweak = #(define-music-function (parser location sym val arg)
+ (symbol? scheme? ly:music?)
-acciaccatura =
-#(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic)
+ "Add @code{sym . val} to the @code{tweaks} property of @var{arg}."
-addquote =
-#(define-music-function (parser location name music) (string? ly:music?)
- "Add a piece of music to be quoted "
- (add-quotable name music)
- (make-music 'SequentialMusic 'void #t))
+
+ (set!
+ (ly:music-property arg 'tweaks)
+ (acons sym val
+ (ly:music-property arg 'tweaks)))
+ arg)
+tag = #(define-music-function (parser location tag arg)
+ (symbol? ly:music?)
-afterGraceFraction =
-#(cons 6 8)
+ "Add @var{tag} to the @code{tags} property of @var{arg}."
-afterGrace =
-#(define-music-function
- (parser location main grace)
- (ly:music? ly:music?)
+ (set!
+ (ly:music-property arg 'tags)
+ (cons tag
+ (ly:music-property arg 'tags)))
+ arg)
- (let*
- ((main-length (ly:music-length main))
- (fraction (ly:parser-lookup parser 'afterGraceFraction)))
-
- (make-simultaneous-music
- (list
- main
- (make-sequential-music
- (list
+clef =
+#(define-music-function (parser location type)
+ (string?)
+
+ "Set the current clef."
- (make-music 'SkipMusic
- 'duration (ly:make-duration
- 0 0
- (* (ly:moment-main-numerator main-length)
- (car fraction))
- (* (ly:moment-main-denominator main-length)
- (cdr fraction)) ))
- (make-music 'GraceMusic
- 'element grace)))))))
+ (make-clef-set type))
+
+bar =
+#(define-music-function (parser location type)
+ (string?)
+ (context-spec-music
+ (make-property-set 'whichBar type)
+ 'Timing))
applyMusic =
#(define-music-function (parser location func music) (procedure? ly:music?)
(func music))
+oldaddlyrics =
+#(define-music-function (parser location music lyrics) (ly:music? ly:music?)
-applyOutput =
-#(define-music-function (parser location ctx proc) (symbol? procedure?)
- (make-music 'ApplyOutputEvent
- 'origin location
- 'procedure proc
- 'context-type ctx))
+ (make-music 'OldLyricCombineMusic
+ 'origin location
+ 'elements (list music lyrics)))
+grace =
+#(def-grace-function startGraceMusic stopGraceMusic)
+
+acciaccatura =
+#(def-grace-function startAcciaccaturaMusic stopAcciaccaturaMusic)
appoggiatura =
#(def-grace-function startAppoggiaturaMusic stopAppoggiaturaMusic)
-
-
-% for regression testing purposes.
-assertBeamQuant =
-#(define-music-function (parser location l r) (pair? pair?)
- (make-grob-property-override 'Beam 'positions
- (ly:make-simple-closure
- (ly:make-simple-closure
- (append
- (list chain-grob-member-functions `(,cons 0 0))
- (check-quant-callbacks l r))))))
-
-% for regression testing purposes.
-assertBeamSlope =
-#(define-music-function (parser location comp) (procedure?)
- (make-grob-property-override 'Beam 'positions
- (ly:make-simple-closure
- (ly:make-simple-closure
- (append
- (list chain-grob-member-functions `(,cons 0 0))
- (check-slope-callbacks comp))))))
-
-
+partcombine =
+#(define-music-function (parser location part1 part2) (ly:music? ly:music?)
+ (make-part-combine-music (list part1 part2)))
autochange =
#(define-music-function (parser location music) (ly:music?)
'origin location
'procedure proc))
-bar =
-#(define-music-function (parser location type)
- (string?)
- (context-spec-music
- (make-property-set 'whichBar type)
- 'Timing))
-
-
-barNumberCheck =
-#(define-music-function (parser location n) (integer?)
- (make-music 'ApplyContext
- 'origin location
- 'procedure
- (lambda (c)
- (let*
- ((cbn (ly:context-property c 'currentBarNumber)))
- (if (and (number? cbn) (not (= cbn n)))
- (ly:input-message location "Barcheck failed got ~a expect ~a"
- cbn n))))))
-
-
-%% why a function?
-breathe =
-#(define-music-function (parser location) ()
- (make-music 'EventChord
- 'origin location
- 'elements (list (make-music 'BreathingEvent))))
-
-bendAfter =
-#(define-music-function (parser location delta) (integer?)
-
- (make-music 'BendAfterEvent
- 'delta-step delta))
-
-clef =
-#(define-music-function (parser location type)
- (string?)
-
- "Set the current clef."
-
- (make-clef-set type))
-
-
-compressMusic =
-#(define-music-function
- (parser location fraction music) (number-pair? ly:music?)
- (ly:music-compress music (ly:make-moment (car fraction) (cdr fraction))))
-
-
-cueDuring =
-#(define-music-function
- (parser location what dir main-music)
- (string? ly:dir? ly:music?)
- (make-music 'QuoteMusic
- 'element main-music
- 'quoted-context-type 'Voice
- 'quoted-context-id "cue"
- 'quoted-music-name what
- 'quoted-voice-direction dir
- 'origin location))
-
-
-displayLilyMusic =
-#(define-music-function (parser location music) (ly:music?)
- (display-lily-music music)
- music)
-
-displayMusic =
-#(define-music-function (parser location music) (ly:music?)
- (display-scheme-music music)
- music)
-
-featherDurations=
-#(define-music-function (parser location factor argument) (ly:moment? ly:music?)
+shiftDurations =
+#(define-music-function (parser location dur dots arg) (integer? integer? ly:music?)
+ ""
- "Rearrange durations in ARGUMENT so there is an
-acceleration/deceleration. "
- (let*
- ((orig-duration (ly:music-length argument))
- (multiplier (ly:make-moment 1 1)))
-
- (music-map
- (lambda (mus)
- (if (and (eq? (ly:music-property mus 'name) 'EventChord)
- (< 0 (ly:moment-main-denominator (ly:music-length mus))))
- (begin
- (ly:music-compress mus multiplier)
- (set! multiplier (ly:moment-mul factor multiplier)))
- )
- mus)
- argument)
-
- (ly:music-compress
- argument
- (ly:moment-div orig-duration (ly:music-length argument)))
-
- argument))
-
-grace =
-#(def-grace-function startGraceMusic stopGraceMusic)
-
-
-"instrument-definitions" = #'()
-
-addInstrumentDefinition =
-#(define-music-function
- (parser location name lst) (string? list?)
-
- (set! instrument-definitions (acons name lst instrument-definitions))
-
- (make-music 'SequentialMusic 'void #t))
-
-
-instrumentSwitch =
-#(define-music-function
- (parser location name) (string?)
- (let*
- ((handle (assoc name instrument-definitions))
- (instrument-def (if handle (cdr handle) '()))
- )
-
- (if (not handle)
- (ly:input-message "No such instrument: ~a" name))
- (context-spec-music
- (make-music 'SimultaneousMusic
- 'elements
- (map (lambda (kv)
- (make-property-set
- (car kv)
- (cdr kv)))
- instrument-def))
- 'Staff)))
-
-
-keepWithTag =
-#(define-music-function
- (parser location tag music) (symbol? ly:music?)
- (music-filter
- (lambda (m)
- (let* ((tags (ly:music-property m 'tags))
- (res (memq tag tags)))
- (or
- (eq? tags '())
- res)))
- music))
-
-
-
-killCues =
-#(define-music-function
- (parser location music)
- (ly:music?)
(music-map
- (lambda (mus)
- (if (string? (ly:music-property mus 'quoted-music-name))
- (ly:music-property mus 'element)
- mus)) music))
-
-
-makeClusters =
-#(define-music-function
- (parser location arg) (ly:music?)
- (music-map note-to-cluster arg))
+ (lambda (x)
+ (shift-one-duration-log x dur dots)) arg))
musicMap =
#(define-music-function (parser location proc mus) (procedure? ly:music?)
(music-map proc mus))
+displayMusic =
+#(define-music-function (parser location music) (ly:music?)
+ (display-scheme-music music)
+ music)
+%% FIXME: guile-1.7 required?
+%#(use-modules (scm display-lily))invalid module name for use-syntax ((srfi srfi-39))
-oldaddlyrics =
-#(define-music-function (parser location music lyrics) (ly:music? ly:music?)
-
- (make-music 'OldLyricCombineMusic
- 'origin location
- 'elements (list music lyrics)))
+#(use-modules (scm display-lily))
+#(display-lily-init parser)
+displayLilyMusic =
+#(define-music-function (parser location music) (ly:music?)
+ (display-lily-music music)
+ music)
+applyOutput =
+#(define-music-function (parser location ctx proc) (symbol? procedure?)
+ (make-music 'ApplyOutputEvent
+ 'origin location
+ 'procedure proc
+ 'context-type ctx))
overrideProperty =
#(define-music-function (parser location name property value)
(set! grob-name (string->symbol (list-ref name-components 1)))
(set! context-name (string->symbol (list-ref name-components 0)))))
- (make-music 'ApplyOutputEvent
- 'origin location
- 'context-type context-name
- 'procedure
- (lambda (grob orig-context context)
- (if (equal?
- (cdr (assoc 'name (ly:grob-property grob 'meta)))
- grob-name)
- (set! (ly:grob-property grob property) value))))))
+ (context-spec-music
+ (make-music 'ApplyOutputEvent
+ 'origin location
+ 'procedure
+ (lambda (grob orig-context context)
+ (if (equal?
+ (cdr (assoc 'name (ly:grob-property grob 'meta)))
+ grob-name)
+ (set! (ly:grob-property grob property) value))))
+
+ context-name)))
+
+breathe =
+#(define-music-function (parser location) ()
+ (make-music 'EventChord
+ 'origin location
+ 'elements (list (make-music 'BreathingSignEvent))))
+
+
+unfoldRepeats =
+#(define-music-function (parser location music) (ly:music?)
+ (unfold-repeats music))
+
+compressMusic =
+#(define-music-function
+ (parser location fraction music) (number-pair? ly:music?)
+ (ly:music-compress music (ly:make-moment (car fraction) (cdr fraction))))
+
+makeClusters =
+#(define-music-function
+ (parser location arg) (ly:music?)
+ (music-map note-to-cluster arg))
removeWithTag =
(res (memq tag tags)))
(not res)))
music))
+
+keepWithTag =
+#(define-music-function
+ (parser location tag music) (symbol? ly:music?)
+ (music-filter
+ (lambda (m)
+ (let* ((tags (ly:music-property m 'tags))
+ (res (memq tag tags)))
+ (or
+ (eq? tags '())
+ res)))
+ music))
+
%% Todo:
%% doing
%% define-music-function in a .scm causes crash.
-octave =
-#(define-music-function (parser location pitch-note) (ly:music?)
- "octave check"
+cueDuring =
+#(define-music-function
+ (parser location what dir main-music)
+ (string? ly:dir? ly:music?)
+ (make-music 'QuoteMusic
+ 'element main-music
+ 'quoted-context-type 'Voice
+ 'quoted-context-id "cue"
+ 'quoted-music-name what
+ 'quoted-voice-direction dir
+ 'origin location))
+
+
+transposedCueDuring = #
+(define-music-function
+ (parser location what dir pitch-note main-music)
+ (string? ly:dir? ly:music? ly:music?)
+
+ "Insert notes from the part @var{what} into a voice called @code{cue},
+using the transposition defined by @var{pitch-note}. This happens
+simultaneously with @var{main-music}, which is usually a rest. The
+argument @var{dir} determines whether the cue notes should be notated
+as a first or second voice."
+
+ (make-music 'QuoteMusic
+ 'element main-music
+ 'quoted-context-type 'Voice
+ 'quoted-context-id "cue"
+ 'quoted-music-name what
+ 'quoted-voice-direction dir
+ 'quoted-transposition (pitch-of-note pitch-note)
+ 'origin location))
+
+
+quoteDuring = #
+(define-music-function
+ (parser location what main-music)
+ (string? ly:music?)
+ (make-music 'QuoteMusic
+ 'element main-music
+ 'quoted-music-name what
+ 'origin location))
- (make-music 'RelativeOctaveCheck
- 'origin location
- 'pitch (pitch-of-note pitch-note)
- ))
-partcombine =
-#(define-music-function (parser location part1 part2) (ly:music? ly:music?)
- (make-part-combine-music (list part1 part2)))
-
pitchedTrill =
#(define-music-function
(parser location main-note secondary-note)
(display sec-note-events)))
main-note))
+
+killCues =
+#(define-music-function
+ (parser location music)
+ (ly:music?)
+ (music-map
+ (lambda (mus)
+ (if (string? (ly:music-property mus 'quoted-music-name))
+ (ly:music-property mus 'element)
+ mus)) music))
-parenthesize =
-#(define-music-function (parser loc arg) (ly:music?)
- "Tag @var{arg} to be parenthesized."
- (set! (ly:music-property arg 'parenthesize) #t)
- arg)
+afterGraceFraction =
+#(cons 6 8)
+
+afterGrace =
+#(define-music-function
+ (parser location main grace)
+ (ly:music? ly:music?)
+
+ (let*
+ ((main-length (ly:music-length main))
+ (fraction (ly:parser-lookup parser 'afterGraceFraction)))
+
+ (make-simultaneous-music
+ (list
+ main
+ (make-sequential-music
+ (list
+
+ (make-music 'SkipMusic
+ 'duration (ly:make-duration
+ 0 0
+ (* (ly:moment-main-numerator main-length)
+ (car fraction))
+ (* (ly:moment-main-denominator main-length)
+ (cdr fraction)) ))
+ (make-music 'GraceMusic
+ 'element grace)))))))
+
+
+barNumberCheck =
+#(define-music-function (parser location n) (integer?)
+ (make-music 'ApplyContext
+ 'origin location
+ 'procedure
+ (lambda (c)
+ (let*
+ ((cbn (ly:context-property c 'currentBarNumber)))
+ (if (not (= cbn n))
+ (ly:input-message location "Barcheck failed got ~a expect ~a"
+ cbn n))))))
+
+
+
+% for regression testing purposes.
+assertBeamQuant =
+#(define-music-function (parser location l r) (pair? pair?)
+ (make-grob-property-override 'Beam 'positions
+ (ly:make-simple-closure
+ (ly:make-simple-closure
+ (append
+ (list chain-grob-member-functions `(,cons 0 0))
+ (check-quant-callbacks l r))))))
+
+% for regression testing purposes.
+assertBeamSlope =
+#(define-music-function (parser location comp) (procedure?)
+ (make-grob-property-override 'Beam 'positions
+ (ly:make-simple-closure
+ (ly:make-simple-closure
+ (append
+ (list chain-grob-member-functions `(,cons 0 0))
+ (check-slope-callbacks comp))))))
-%% for lambda*
-#(use-modules (ice-9 optargs))
parallelMusic =
#(define-music-function (parser location voice-ids music) (list? ly:music?)
voices)
;;
;; check sequence length
- (apply for-each (lambda* (#:rest seqs)
+ (apply for-each (lambda (. seqs)
(let ((moment-reference (ly:music-length (car seqs))))
(for-each (lambda (seq moment)
(if (not (equal? moment moment-reference))
-quoteDuring = #
-(define-music-function
- (parser location what main-music)
- (string? ly:music?)
- (make-music 'QuoteMusic
- 'element main-music
- 'quoted-music-name what
- 'origin location))
-
-
-
-resetRelativeOctave =
-#(define-music-function
- (parser location reference-note)
- (ly:music?)
- "Set the octave inside a \\relative section."
-
- (let*
- ((notes (ly:music-property reference-note 'elements))
- (pitch (ly:music-property (car notes) 'pitch)))
-
- (set! (ly:music-property reference-note 'elements) '())
- (set! (ly:music-property reference-note
- 'to-relative-callback)
- (lambda (music last-pitch)
- pitch))
-
- reference-note))
-
-
-
-shiftDurations =
-#(define-music-function (parser location dur dots arg) (integer? integer? ly:music?)
- ""
-
-
- (music-map
- (lambda (x)
- (shift-one-duration-log x dur dots)) arg))
+%% this is a stub. Write your own to suit the spacing tweak output.
spacingTweaks =
#(define-music-function (parser location parameters) (list?)
- "Set the system stretch, by reading the 'system-stretch property of
- the `parameters' assoc list."
- #{
- \overrideProperty #"Score.NonMusicalPaperColumn"
- #'line-break-system-details
- #$(list (cons 'alignment-extra-space (cdr (assoc 'system-stretch parameters))))
- #})
-
-%% Parser used to read page-layout file, and then retreive score tweaks.
-#(define page-layout-parser #f)
-
-includePageLayoutFile =
-#(define-music-function (parser location) ()
- "If page breaks and tweak dump is not asked, and the file
- <basename>-page-layout.ly exists, include it."
- (if (not (ly:get-option 'dump-tweaks))
- (let ((tweak-filename (format #f "~a-page-layout.ly"
- (ly:parser-output-name parser))))
- (if (access? tweak-filename R_OK)
- (begin
- (ly:message "Including tweak file ~a" tweak-filename)
- (set! page-layout-parser (ly:clone-parser parser))
- (ly:parser-parse-string page-layout-parser
- (format #f "\\include \"~a\""
- tweak-filename))))))
(make-music 'SequentialMusic 'void #t))
-scoreTweak =
-#(define-music-function (parser location name) (string?)
- "Include the score tweak, if exists."
- (if (and page-layout-parser (not (ly:get-option 'dump-tweaks)))
- (let ((tweak-music (ly:parser-lookup page-layout-parser
- (string->symbol name))))
- (if (ly:music? tweak-music)
- tweak-music
- (make-music 'SequentialMusic)))
- (make-music 'SequentialMusic)))
-
-transposedCueDuring =
-#(define-music-function
- (parser location what dir pitch-note main-music)
- (string? ly:dir? ly:music? ly:music?)
-
- "Insert notes from the part @var{what} into a voice called @code{cue},
-using the transposition defined by @var{pitch-note}. This happens
-simultaneously with @var{main-music}, which is usually a rest. The
-argument @var{dir} determines whether the cue notes should be notated
-as a first or second voice."
-
- (make-music 'QuoteMusic
- 'element main-music
- 'quoted-context-type 'Voice
- 'quoted-context-id "cue"
- 'quoted-music-name what
- 'quoted-voice-direction dir
- 'quoted-transposition (pitch-of-note pitch-note)
- 'origin location))
-
-
-
-transposition =
+octave =
#(define-music-function (parser location pitch-note) (ly:music?)
- "Set instrument transposition"
-
- (context-spec-music
- (make-property-set 'instrumentTransposition
- (ly:pitch-diff (ly:make-pitch 0 0 0) (pitch-of-note pitch-note)))
- 'Staff
-))
-
-tweak = #(define-music-function (parser location sym val arg)
- (symbol? scheme? ly:music?)
-
- "Add @code{sym . val} to the @code{tweaks} property of @var{arg}."
+ "octave check"
-
- (set!
- (ly:music-property arg 'tweaks)
- (acons sym val
- (ly:music-property arg 'tweaks)))
- arg)
+ (make-music 'RelativeOctaveCheck
+ 'origin location
+ 'pitch (pitch-of-note pitch-note)
+ ))
-tag = #(define-music-function (parser location tag arg)
- (symbol? ly:music?)
+addquote =
+#(define-music-function (parser location name music) (string? ly:music?)
+ "Add a piece of music to be quoted "
+ (add-quotable name music)
+ (make-music 'SequentialMusic 'void #t))
- "Add @var{tag} to the @code{tags} property of @var{arg}."
+
+parenthesize =
+#(define-music-function (parser loc arg) (ly:music?)
+ "Tag @var{arg} to be parenthesized."
- (set!
- (ly:music-property arg 'tags)
- (cons tag
- (ly:music-property arg 'tags)))
+ (set! (ly:music-property arg 'parenthesize) #t)
arg)
-unfoldRepeats =
-#(define-music-function (parser location music) (ly:music?)
- (unfold-repeats music))
+featherDurations=
+#(define-music-function (parser location factor argument) (ly:moment? ly:music?)
+ "Rearrange durations in ARGUMENT so there is an
+acceleration/deceleration. "
+
+ (let*
+ ((orig-duration (ly:music-length argument))
+ (multiplier (ly:make-moment 1 1)))
+ (music-map
+ (lambda (mus)
+ (if (and (eq? (ly:music-property mus 'name) 'EventChord)
+ (< 0 (ly:moment-main-denominator (ly:music-length mus))))
+ (begin
+ (ly:music-compress mus multiplier)
+ (set! multiplier (ly:moment-mul factor multiplier)))
+ )
+ mus)
+ argument)
-withMusicProperty =
-#(define-music-function (parser location sym val music) (symbol? scheme? ly:music?)
- "Set @var{sym} to @var{val} in @var{music}."
+ (ly:music-compress
+ argument
+ (ly:moment-div orig-duration (ly:music-length argument)))
- (set! (ly:music-property music sym) val)
- music)
+ argument))
\version "2.7.39"
-#(use-modules (scm layout-page-layout))
+
\paper {
%%%% WARNING
%%
ragged-last-bottom= ##t
- %%
- %% settings for the page breaker
- %%
- blank-last-page-force = 0
- blank-page-force = 10
-
#(define font-defaults
'((font-encoding . fetaMusic)))
(baseline-skip . 3)
(word-space . 0.6)))
- #(define page-breaking ly:optimal-breaking)
- #(define page-breaking-wrapper page-breaking-wrapper)
- #(define page-post-process post-process-pages)
-
- #(define write-page-layout (ly:get-option 'dump-tweaks))
- #(define system-maximum-stretch-procedure
- (lambda (line)
- (if (stretchable-line? line)
- (let ((height (line-height line)))
- (/ (* height height) 80.0))
- 0.0)))
-
+ #(define page-breaking optimal-page-breaks)
% #(define page-music-height default-page-music-height )
% #(define page-make-stencil default-page-make-stencil )
\type "Performer_group"
\name Staff
\accepts Voice
- \accepts CueVoice
\defaultchild Voice
\consists "Staff_performer"
\consists "Key_performer"
+ \consists "Tempo_performer"
+ \consists "Time_signature_performer"
}
\context {
\name Global
\consists "Note_performer"
\consists "Beam_performer"
\consists "Slur_performer"
+ \consists "Melisma_translator"
}
\context {
\alias Voice
}
-\context {
- \Voice
- \name VaticanaVoice
- \alias Voice
-}
-
\context {
\Voice
\remove "Note_performer"
\defaultchild "TabVoice"
}
-\context {
- \type "Performer_group"
- \name "VaticanaStaff"
- \alias "Staff"
- \denies "Voice"
- \accepts "VaticanaVoice"
- \defaultchild "VaticanaVoice"
-}
-
\context {
\type "Score_performer"
\name Score
melismaBusyProperties = #default-melisma-properties
- instrumentName = #"bright acoustic"
-
- %% quarter = 60
- tempoWholesPerMinute = #(ly:make-moment 15 1)
-
+ instrument = #"bright acoustic"
\accepts Staff
\accepts DrumStaff
\accepts GrandStaff
\accepts ChordNames
\accepts FiguredBass
\accepts Lyrics
- \accepts VaticanaStaff
-
- \consists "Time_signature_performer"
- \consists "Control_track_performer"
- \consists "Tempo_performer"
+
\consists "Timing_translator"
\consists "Swallow_performer"
-
+
\defaultchild "Staff"
dynamicAbsoluteVolumeFunction = #default-dynamic-absolute-volume
\consists "Staff_performer" % Performer_group ?
\consists "Lyric_performer"
\name Lyrics
+ \consists "Time_signature_performer"
+ \consists "Tempo_performer"
}
\context{
\name StaffGroup
\accepts Staff
\accepts DrumStaff
- \accepts TabStaff
- \accepts RhythmicStaff
- \accepts GrandStaff
- \accepts PianoStaff
- \accepts Lyrics
- \accepts ChordNames
- \accepts FiguredBass
\defaultchild Staff
}
%crescpoco = \set crescendoText = "cresc. poco a poco"
%decresc = \set crescendoText = "decr."
%dim = \set crescendoText = "dim."
-
-newSpacingSection = #(make-event-chord (list (make-music 'SpacingSectionEvent)))
#(define (print-page-number-check-first layout props arg)
(if (or (not (= (chain-assoc-get 'page:page-number props -1)
(ly:output-def-lookup layout 'first-page-number)))
- (eq? (ly:output-def-lookup layout 'print-first-page-number) #t))
+ (eq? (ly:output-def-lookup layout 'printfirst-page-number) #t))
(print-page-number layout props arg)
empty-stencil))
##
## settings to run LilyPond
ifeq ($(LILYPOND_EXTERNAL_BINARY),)
-
# environment settings.
export PATH:=$(top-build-dir)/lily/$(outconfbase):$(top-build-dir)/buildscripts/$(outconfbase):$(top-build-dir)/scripts/$(outconfbase):$(PATH):
-export LILYPOND_BINARY=$(top-build-dir)/$(outconfbase)/bin/lilypond
+export LILYPONDPREFIX:=$(build_lilypond_datadir)/current
+export DVIPSHEADERS:=$(top-build-dir)/mf/out::
+export LILYPOND_BINARY=$(top-build-dir)/lily/$(outconfbase)/lilypond
else
## better not take the binaries from a precompiled bundle, as they
ABC2LY = $(script-dir)/abc2ly.py
CONVERT_LY = $(script-dir)/convert-ly.py
LILYPOND_BOOK = $(script-dir)/lilypond-book.py
-LILYPOND_BOOK_INCLUDES = -I $(src-dir)/ -I $(outdir) -I $(input-dir) -I $(input-dir)/regression/ -I $(input-dir)/manual/ -I $(input-dir)/tutorial/ -I $(top-build-dir)/mf/$(outconfbase)/ -I $(top-build-dir)/mf/out/
-
-LILYPOND_BOOK_LILYPOND_FLAGS=--backend=eps --formats=ps,png,pdf -dinclude-eps-fonts -dgs-load-fonts --header=texidoc -I $(top-src-dir)/input/manual -dcheck-internal-types -ddump-signatures -danti-alias-factor=2
-
-LILYPOND_BOOK_FLAGS = --process="$(LILYPOND_BINARY) $(LILYPOND_BOOK_LILYPOND_FLAGS)"
+LILYPOND_BOOK_INCLUDES = -I $(src-dir)/ -I $(outdir) -I $(input-dir) -I $(input-dir)/regression/ -I $(input-dir)/test/ -I $(input-dir)/tutorial/ -I $(top-build-dir)/mf/$(outconfbase)/ -I $(top-build-dir)/mf/out/
+LILYPOND_BOOK_LILYPOND_FLAGS=-dgs-font-load
+LILYPOND_BOOK_FLAGS = --process="$(LILYPOND_BINARY) --backend=eps --formats=ps,png --header=texidoc -I $(top-src-dir)/input/test -dinternal-type-checking -ddump-signatures -danti-alias-factor=2 $(LILYPOND_BOOK_LILYPOND_FLAGS)"
TEXINPUTS=$(top-src-dir)/tex/::
export TEXINPUTS
-.SUFFIXES: .doc .tely .texi .ly
+.SUFFIXES: .doc .dvi .tely .texi .ly
-$(outdir)/%.latex: %.doc
+$(outdir)/%.latex $(outdir)/%.psfonts: %.doc
$(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --verbose $(LILYPOND_BOOK_FLAGS) $<
# don't do ``cd $(outdir)'', and assume that $(outdir)/.. is the src dir.
# it is not, for --srcdir builds
$(outdir)/%.texi: %.tely
- rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.*tex 2>/dev/null)
- $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
+ rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.tex 2>/dev/null)
+ $(PYTHON) $(LILYPOND_BOOK) --psfonts $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
$(outdir)/%.texi: $(outdir)/%.tely
- rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.*tex 2>/dev/null)
- $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
+ rm -f $$(grep -LF '% eof' $(outdir)/lily-*systems.tex 2>/dev/null)
+ $(PYTHON) $(LILYPOND_BOOK) --psfonts $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BINARY) $(LILYPOND_BOOK_INCLUDES)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) --verbose $(LILYPOND_BOOK_FLAGS) $<
#
# DON'T REMOVE SOURCE FILES, otherwise the .TEXI ALWAYS OUT OF DATE.
# rm -f $<
# huh ? these are for documentation?!
TELY_FILES := $(call src-wildcard,*.tely)
-OMF_FILES += $(foreach format, html pdf, $(foreach f, $(TELY_FILES), $(outdir)/$(f:.tely=.$(format)).omf))
+OMF_FILES += $(foreach format, html pdf ps.gz, $(foreach f, $(TELY_FILES), $(outdir)/$(f:.tely=.$(format)).omf))
ITELY_FILES := $(call src-wildcard,*.itely)
ITEXI_FILES := $(call src-wildcard,*.itexi)
-$(outdir)/%.ly: %.ly
- cp $< $@
-$(outdir)/%.ly: %.abc
+
+$(outdir)/%.ly.txt: %.ly
+ ln -f $< $@
+
+$(outdir)/%.ly.txt: $(outdir)/%.ly
+ cp -f $< $@
+
+$(outdir)/%.ly.txt: %.abc
#which file to show here -- abc seems more cute?
ln -f $< $@
# hmm. notdir builds src-dir builds?
$(outdir)/%.png $(outdir)/%.pdf $(outdir)/%.ly $(outdir)/%.ps: $(outdir)/%.ly
- cd $(outdir); $(LILYPOND_BINARY) --pdf --png -ddump-signatures -danti-alias-factor=2 -ddelete-intermediate-files -dno-point-and-click -I $(call absdir,$(src-dir))/ $(notdir $<)
+ cd $(outdir); $(LILYPOND_BINARY) --pdf --png -danti-alias-factor=2 -ddelete-intermediate-files -dno-point-and-click -I $(call absdir,$(src-dir))/ $(notdir $<)
touch $(outdir)/$(basename $(notdir $<)).png
+$(outdir)/%.ly: %.ly
+ cp $< $@
+
+
LYM4_FILES = $(call src-wildcard,*.lym4)
EXTRA_DIST_FILES += $(M4_FILES) $(LYM4_FILES)
-ly_examples=$(addprefix $(outdir)/, $(addsuffix .ly, $(examples)))
+ly_examples=$(addprefix $(outdir)/, $(addsuffix .ly.txt, $(examples)))
all_examples=$(examples)
ps_examples=$(addprefix $(outdir)/, $(addsuffix .ps.gz, $(all_examples)))
pdf_examples=$(addprefix $(outdir)/, $(addsuffix .pdf, $(all_examples)))
import string
Import ('env', 'base_glob', 'install')
-feta = reduce (lambda x, y: x + y,
+xfeta = reduce (lambda x, y: x + y,
map (lambda x: base_glob (x),
('feta[0-9]*.mf',
'feta-alphabet*[0-9].mf',
feta_braces = base_glob ('feta-braces-[a-z].mf')
parmesan = base_glob ('parmesan[0-9][0-9]*.mf')
-fonts = feta + feta_alphabet + feta_braces + parmesan
+# .pfa rules want an encoding file; ecb10.enc
+#sauter = ['ecb10']
+sauter = []
+fonts = feta + feta_alphabet + feta_braces + parmesan + sauter
+#env['feta'] = string.join (feta)
+#env['sauter'] = ''
feta_sizes = map (lambda x: re.sub ('feta([0-9]+)', '\\1', x), feta)
otfs = map (lambda x: 'emmentaler-' + x, feta_sizes) + ['aybabtu']
t = map (env.TFM, fonts)
g = map (env.GTABLE, fonts)
+# FIXME: don't know how to add prefix: PFAEmmentaler (naming is ugly anyway)
+#p = map (env.PFA, fonts + map (lambda x: 'PFA' + x, otfs))
p = map (env.PFA, fonts)
+#e = map (env.ENC, fonts)
+#c = map (lambda x: x + '.cff', fonts)
+cp = map (lambda x: x + '.cff.ps', fonts)
e = map (lambda x: x + '.enc', fonts)
s = map (lambda x: x + '.svg', fonts)
o = map (env.OTF, otfs)
f = map (env.OTF_TABLE, feta)
g = map (env.OTF_TABLE, feta_braces)
-map (lambda x: env.Depends ('feta' + x + '.otf-table',
- ['parmesan' + x + '.lisp',
- 'feta-alphabet' + x + '.lisp']), feta_sizes)
-
map (lambda x: env.Depends ('emmentaler-' + x + '.otf',
'feta' + x + '.otf-table'),
feta_sizes)
-map (lambda x: env.Depends ('emmentaler-' + x + '.otf',
- ['feta' + x + '.pfa',
- 'parmesan' + x + '.pfa',
- 'feta-alphabet' + x + '.pfa']), feta_sizes)
-
-for i in feta_sizes:
- env.Command ('emmentaler-%(i)s.pe' % locals (),
- '$srcdir/buildscripts/gen-emmentaler-scripts.py',
- '$PYTHON $srcdir/buildscripts/gen-emmentaler-scripts.py --dir=${TARGET.dir}')
+env.Command ('emmentaler-11.pe',
+ '$srcdir/buildscripts/gen-emmentaler-scripts.py',
+ '$PYTHON $srcdir/buildscripts/gen-emmentaler-scripts.py --dir=${TARGET.dir}')
map (lambda x: env.Depends (x + '.pfa', x + '.enc'), feta)
# Aybabtu
-feta_braces_pfa = map (lambda x: x + '.pfa', feta_braces)
+# ugh
+##feta_braces = map (lambda x: 'feta-braces-%c' % (ord ('a') + x), range (9))
env.AT_COPY ('aybabtu.pe.in')
env.Command ('aybabtu.fontname', '', 'echo -n aybabtu > $TARGET')
map (lambda x: x + '.otf-gtable', feta_braces),
'echo "(design_size . 20)" > $TARGET')
-env.Depends ('aybabtu.otf',
- feta_braces_pfa
- + ['aybabtu.subfonts',
- 'aybabtu.fontname',
- 'aybabtu.otf-table',
- 'aybabtu.otf-gtable'])
-
-env.Command ('fonts.cache-1', p + o,
- 'cd ${TARGET.dir}; fc-cache .')
-
-## FIXME: building only a few fonts does not seem to work anymore.
-## what is essential these days, aybabtu/emmentaler are needed always?
+#env.Depends ('aybabtu.otf-table',
+# map (lambda x: x + '.otf-table', feta_braces))
+
+env.Depends ('aybabtu.otf', 'aybabtu.subfonts')
+env.Depends ('aybabtu.otf', 'aybabtu.fontname')
+env.Depends ('aybabtu.otf', 'aybabtu.otf-table')
+env.Depends ('aybabtu.otf', 'aybabtu.otf-gtable')
+
+# Hmm?
+env.Depends ('aybabtu.pfa', 'aybabtu.subfonts')
+env.Depends ('aybabtu.pfa', 'aybabtu.fontname')
+env.Depends ('aybabtu.pfa', 'aybabtu.otf-table')
+env.Depends ('aybabtu.pfa', 'aybabtu.otf-gtable')
+
+
+## FIXME
mf_essential = ['feta16', 'feta20', 'parmesan16', ]
-pfa_essential = map (env.PFA, mf_essential) + ['emmentaler-20.otf']
+pfa_essential = map (env.PFA, mf_essential)
env.Alias ('mf-essential', pfa_essential)
-env.Alias ('mf-essential', 'fonts.cache-1')
env['fonts'] = string.join (fonts)
env['feta_sizes'] = string.join (feta_sizes)
-
+env['sauter'] = string.join (sauter)
+env.Command ('lilypond.map', p,
+ ['for i in $fonts; do echo $$i $$i "<"$$i.pfa; done > $TARGET',
+ 'for i in $feta_sizes; do\
+ echo "Emmentaler-$$i Emmentaler-$$i <emmentaler-$$i.cff.ps";\
+ echo "PFAEmmentaler-$$i PFAEmmentaler-$$i <PFAemmentaler-$$i.pfa";\
+ done >> $TARGET',
+ 'echo "Aybabtu-Regular Aybabtu-Regular <aybabtu.cff.ps" >> $TARGET',
+ 'echo "PFAAybabtu-Regular PFAAybabtu-Regular <aybabtu.cff.ps" >> $TARGET',
+ 'for i in $sauter; do echo "$$i $$i <$$i.pfa"; done >> $TARGET'])
+#env.Alias ('mf', 'lilypond.map')
+
+env.Command ('fonts.scale', p,
+ 'cd ${TARGET.dir} && echo *.pfa *.pfb | $PYTHON $srcdir/buildscripts/make-font-dir.py > $TARGET.file')
+env.Alias ('mf', 'fonts.scale')
+
+env.Command ('Fontmap', p,
+ ["echo '%!' > $TARGET",
+ "echo '% Override default GS Fontmap' >> $TARGET",
+ "echo '% To let gs load fonts from builddir, do:' >> $TARGET",
+ "echo '% export GS_LIB=$$(pwd)/mf/out:' >> $TARGET",
+ "echo '% See Fontmap.GS for the syntax of real Fontmap files.' >> $TARGET",
+ "echo '(Fontmap.GS) .runlibfile' >> $TARGET",
+ "echo '(Fontmap.lily) .runlibfile' >> $TARGET"])
+
+env.Command ('Fontmap.lily', p + ['Fontmap'],
+ ['echo "%!" > $TARGET',
+ '''for i in $fonts; do echo "/$$i ($$i.pfa);"; done >> $TARGET''',
+ ''' for i in $feta_sizes; do \
+ echo "/Emmentaler-$$i (emmentaler-$$i.cff.ps);" ; \
+ echo "/PFAEmmentaler-$$i (PFAemmentaler-$$i.pfa);" ; \
+ done >> $TARGET''',
+ '''echo "/Aybabtu (aybabtu.cff.ps);" >> $TARGET''',
+ '''echo "/PFAAybabtu (PFAaybabtu.pfa);" >> $TARGET''',
+ '''for i in $sauter; do echo "$$i ($$i.pfa);"; done >> $TARGET'''])
+#env.Alias ('mf', 'Fontmap.lily')
+
+# build essential stuff first, that's friendlier
env.Alias ('mf', pfa_essential + p + map (lambda x: x[0], o))
-env.Alias ('mf', s)
-env.Alias ('mf', 'fonts.cache-1')
install (t, env['sharedir_package_version'] + '/fonts/tfm')
install (p, env['sharedir_package_version'] + '/fonts/type1')
install (o, env['sharedir_package_version'] + '/fonts/otf')
install (e, env['sharedir_package_version'] + '/ps')
install (s, env['sharedir_package_version'] + '/fonts/svg')
+#install (c, env['sharedir_package_version'] + '/fonts/cff')
+install (cp, env['sharedir_package_version'] + '/ps')
save p_in, p_out;
path p_in, p_out;
- set_char_box (0, width_factor * solfa_base_notewidth#,
+ set_char_box (0, width_factor * solfa_noteheight#,
0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
pickup pencircle scaled solfa_pen_thick;
path path_out, path_in;
pair ne_dist, se_dist, ne, se;
- set_char_box (0, width_factor * solfa_base_notewidth#,
+ set_char_box (0, width_factor * solfa_noteheight#,
0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
pickup pencircle scaled solfa_pen_thick;
def draw_fa_head (expr width_factor) =
- set_char_box (0, width_factor * solfa_base_notewidth#,
+ set_char_box (0, width_factor * solfa_noteheight#,
0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
save p_down_in, p_down_out, p_up_in, p_up_out, nw_dist, nw;
def draw_la_head (expr width_factor) =
- set_char_box (0, width_factor * solfa_base_notewidth#,
+ set_char_box (0, width_factor * solfa_noteheight#,
0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
save p_in, p_out;
path p_in, p_out;
def draw_ti_head (expr width_factor, dir) =
- set_char_box (0, width_factor * solfa_base_notewidth#,
+ set_char_box (0, width_factor * solfa_noteheight#,
0.5 solfa_noteheight#, 0.5 solfa_noteheight#);
save p_in, p_out, p_top;
save nw_dist, sw_dist, nw, sw;
#: parser.yy:705
msgid "\\paper cannot be used in \\score, use \\layout instead"
msgstr ""
-"\\paper kann nicht in \\score verwendet werden; stattdessen \\layout "
+"\\paper kann nicht in \\source verwendet werden; stattdessen \\layout "
"verwenden"
#: parser.yy:729
+# translation of fi.po to
+# translation of fi.po to
# translation of fi.po to
# Finnish Translation of lilypond.
# Copyright (C) 2003 Han-Wen Nienhuys, Jan Nieuwenhuizen
# This file is distributed under the same license as the lilypond package.
-#
-#
-# First translator: Heikki Junes <hjunes@cc.hut.fi>, 2003-2006.
+# First translator: Heikki Junes <hjunes@cc.hut.fi>, 2003-2005.
+#
+#
msgid ""
msgstr ""
"Project-Id-Version: fi\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-10-04 21:28+0300\n"
-"PO-Revision-Date: 2006-10-04 21:30+0300\n"
-"Last-Translator: hjunes\n"
+"POT-Creation-Date: 2006-03-20 12:53+0100\n"
+"PO-Revision-Date: 2006-03-14 13:04+0100\n"
+"Last-Translator: hjunes <>\n"
"Language-Team: <en@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: KBabel 1.11.2\n"
-#: convertrules.py:12
+#: convertrules.py:9
#, python-format
msgid "Not smart enough to convert %s"
-msgstr "Ei tarpeeksi fiksu konvertoidakseen %s"
+msgstr "Ei tarpeeksi fiksu konvertoidakseen %sd"
-#: convertrules.py:13
+#: convertrules.py:10
msgid "Please refer to the manual for details, and update manually."
msgstr "Ole hyvä ja katso ohjekirjasta yksityiskohdat, ja päivitä käsin."
-#: convertrules.py:14
+#: convertrules.py:11
#, python-format
msgid "%s has been replaced by %s"
msgstr "%s on korvattu %s:lla"
-#: convertrules.py:2398
+#: convertrules.py:2395
msgid "LilyPond source must be UTF-8"
msgstr "LilyPond lähdekoodin täytyy olla UTF-8 muodossa"
-#: convertrules.py:2401
+#: convertrules.py:2398
msgid "Try the texstrings backend"
msgstr "Koeta tex-merkkijonon käyttöä"
-#: convertrules.py:2404
+#: convertrules.py:2401
#, python-format
msgid "Do something like: %s"
msgstr "Tee jotain tällaista: %s"
-#: convertrules.py:2407
+#: convertrules.py:2404
msgid "Or save as UTF-8 in your editor"
msgstr "Tai talleta UTF-8 -muodossa editorissasi"
-#: fontextract.py:26
+#: fontextract.py:25
#, python-format
msgid "Scanning %s"
msgstr "Skannataan %s"
-#: fontextract.py:71
+#: fontextract.py:70
#, python-format
msgid "Extracted %s"
msgstr "Poimittiin %s"
-#: fontextract.py:86
+#: fontextract.py:85
#, python-format
msgid "Writing fonts to %s"
msgstr "Kirjoitetaan fontit osoitteeseen `%s'"
-#: lilylib.py:85 lilylib.py:136
+#: lilylib.py:82
#, python-format
msgid "Invoking `%s'"
msgstr "Kutsutaan `%s'"
-#: lilylib.py:87 lilylib.py:138
+#: lilylib.py:84
#, python-format
msgid "Running %s..."
msgstr "Ajetaan %s..."
-#: lilylib.py:203
+#: lilylib.py:165
#, python-format
msgid "Usage: %s\n"
msgstr "Käyttö: %s\n"
-#: abc2ly.py:1351
+#: abc2ly.py:1357
msgid ""
"This program converts ABC music files (see\n"
"http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) to LilyPond input."
msgstr ""
-"Tämä ohjelma kääntää ABC-musiikkitiedostoja (katso\n"
-"http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) LilyPond-syötteeksi."
+"Tämä ohjelma kääntää ABC musiikkitiedostoja (katso\n"
+"http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) LilyPond syötteeksi"
-#: abc2ly.py:1354
+#: abc2ly.py:1360
msgid "set output filename to FILE"
msgstr "tulosta tiedostoon TIEDOSTO"
-#: abc2ly.py:1356
+#: abc2ly.py:1362
msgid "be strict about succes"
msgstr "ole tarkka onnistumisesta"
-#: abc2ly.py:1358
+#: abc2ly.py:1364
msgid "preserve ABC's notion of beams"
msgstr "säilytä ABC:n palkkimerkinnät"
-#: convert-ly.py:41
+#: convert-ly.py:49
msgid ""
"Update LilyPond input to newer version. By default, update from the\n"
"version taken from the \\version command, to the current LilyPond version.\n"
" convert-ly -e old.ly\n"
" convert-ly --from=2.3.28 --to 2.5.21 foobar.ly\n"
-#: convert-ly.py:57 lilypond-book.py:97 warn.cc:48 input.cc:90
+#: convert-ly.py:67 lilypond-book.py:115 warn.cc:48 input.cc:81
#, c-format, python-format
msgid "warning: %s"
msgstr "varoitus: %s"
-#: convert-ly.py:60 lilypond-book.py:100 warn.cc:54 input.cc:96 input.cc:104
+#: convert-ly.py:70 lilypond-book.py:118 warn.cc:54 input.cc:87 input.cc:95
#, c-format, python-format
msgid "error: %s"
msgstr "virhe: %s"
-#: convert-ly.py:76 etf2ly.py:1190 lilypond-book.py:120 midi2ly.py:98
+#: convert-ly.py:86 etf2ly.py:1200 lilypond-book.py:138 midi2ly.py:114
msgid "Distributed under terms of the GNU General Public License."
msgstr "Levitettävissä ehdoilla GNU General Public License."
-#: convert-ly.py:77 etf2ly.py:1191 lilypond-book.py:121 midi2ly.py:99
+#: convert-ly.py:87 etf2ly.py:1201 lilypond-book.py:139 midi2ly.py:115
msgid "It comes with NO WARRANTY."
msgstr "Se toimitetaan ILMAN TAKUUTA."
-#: convert-ly.py:88 convert-ly.py:108
+#: convert-ly.py:98 convert-ly.py:118
msgid "VERSION"
msgstr "VERSIO"
-#: convert-ly.py:90
+#: convert-ly.py:100
msgid "start from VERSION [default: \\version found in file]"
msgstr "aloita versiosta VERSIO [oletus: \\version joka on tiedostossa]"
-#: convert-ly.py:93
+#: convert-ly.py:103
msgid "edit in place"
msgstr "editoi paikassaan"
-#: convert-ly.py:96
+#: convert-ly.py:106
msgid "do not add \\version command if missing"
msgstr "älä lisää \\version komentoa jos se puuttuu"
-#: convert-ly.py:102
+#: convert-ly.py:112
msgid "print rules [default: --from=0, --to=@TOPLEVEL_VERSION@]"
msgstr "tulosta säännöt [oletus: --from=0, --to=@TOPLEVEL_VERSION@]"
-#: convert-ly.py:107
+#: convert-ly.py:117
msgid "convert to VERSION [default: @TOPLEVEL_VERSION@]"
msgstr "muunnaa versioon VERSIO [oletus: @TOPLEVEL_VERSION@]"
-#: convert-ly.py:154
+#: convert-ly.py:164
msgid "Applying conversion: "
msgstr "Toteutetaan muunnos: "
-#: convert-ly.py:166
+#: convert-ly.py:176
msgid "error while converting"
msgstr "virhe muunnettaessa"
-#: convert-ly.py:168 score-engraver.cc:74
+#: convert-ly.py:178 score-engraver.cc:73
msgid "Aborting"
msgstr "Keskeytetään"
-#: convert-ly.py:192
+#: convert-ly.py:202
#, python-format
msgid "Processing `%s'... "
-msgstr "Prosessoidaan `%s'... "
+msgstr "Prosessoidaan `%s'..."
-#: convert-ly.py:279 source-file.cc:54
+#: convert-ly.py:289 source-file.cc:56
#, c-format, python-format
msgid "can't open file: `%s'"
msgstr "tiedostoa ei voitu avata: `%s'"
-#: convert-ly.py:286
+#: convert-ly.py:296
#, python-format
msgid "can't determine version for `%s'. Skipping"
msgstr "ei voitu määrittää `%s':lle versiota. Sivuutetaan"
-#: etf2ly.py:1198
+#: etf2ly.py:1208
msgid ""
"Enigma Transport Format is a format used by Coda Music Technology's\n"
"Finale product. This program will convert a subset of ETF to a\n"
"tallennusmuoto. Tämä ohjelma muuntaa ETF-muodon osajoukon\n"
"LilyPondilla käytettäväksi."
-#: etf2ly.py:1201 midi2ly.py:885
+#: etf2ly.py:1211 midi2ly.py:901
msgid "write output to FILE"
msgstr "tulosta tiedostoon TIEDOSTO"
-#: etf2ly.py:1202 midi2ly.py:886 main.cc:173 main.cc:179
+#: etf2ly.py:1212 midi2ly.py:902 main.cc:172 main.cc:178
msgid "FILE"
msgstr "TIEDOSTO"
-#: etf2ly.py:1204 midi2ly.py:899
+#: etf2ly.py:1214 midi2ly.py:915
msgid "show warranty"
msgstr "näytä takuusitoumus"
-#: lilypond-book.py:70
+#: lilypond-book.py:88
msgid ""
"Process LilyPond snippets in hybrid HTML, LaTeX, or texinfo document.\n"
"\n"
"Example usage:\n"
"\n"
-" lilypond-book --filter=\"tr '[a-z]' '[A-Z]'\" BOOK\n"
-" lilypond-book --filter=\"convert-ly --no-version --from=2.0.0 -\" BOOK\n"
-" lilypond-book --process='lilypond -I include' BOOK\n"
+" lilypond-book --filter=\"tr '[a-z]' '[A-Z]'\" BOOK\n"
+" lilypond-book --filter=\"convert-ly --no-version --from=2.0.0 -\" BOOK\n"
+" lilypond-book --process='lilypond -I include' BOOK\n"
msgstr ""
"Käsittele HTML, LaTeX, tai texinfo -documenttiin sisällytetyt LilyPond "
"palaset.\n"
"\n"
" lilypond-book --filter=\"tr '[a-z]' '[A-Z]'\" BOOK\n"
" lilypond-book --filter=\"convert-ly --no-version --from=2.0.0 -\" BOOK\n"
-" lilypond-book --process='lilypond -I include' BOOK\n"
+" lilypond-book --process='lilypond-bin -I include' BOOK\n"
-#: lilypond-book.py:86
+#: lilypond-book.py:104
#, python-format
msgid "Exiting (%d)..."
msgstr "Lopetetaan (%d)..."
-#: lilypond-book.py:118
+#: lilypond-book.py:136
#, python-format
msgid "Copyright (c) %s by"
msgstr "Copyright (c) %s by"
-#: lilypond-book.py:129
+#: lilypond-book.py:147
msgid "FILTER"
msgstr "FILTER"
-#: lilypond-book.py:132
+#: lilypond-book.py:150
msgid "pipe snippets through FILTER [convert-ly -n -]"
msgstr "putkita palaset kohteen FILTER läpi [convert-ly -n -]"
-#: lilypond-book.py:135
+#: lilypond-book.py:152
msgid "use output format FORMAT (texi [default], texi-html, latex, html)"
-msgstr "käytä tulostusmuotona formaattia FMT (texi [oletus], texi-html, latex, html)"
+msgstr ""
+"käytä tulostusmuotona formaattia FMT (texi [oletus], texi-html, latex, html)"
-#: lilypond-book.py:138
+#: lilypond-book.py:154
msgid "add DIR to include path"
msgstr "lisää HAKEMISTO hakupolkuun"
-#: lilypond-book.py:143
+#: lilypond-book.py:159
msgid "write output to DIR"
msgstr "tulosta polkuun HAKEMISTO"
-#: lilypond-book.py:147
+#: lilypond-book.py:162
msgid "COMMAND"
msgstr "KOMENTO"
-#: lilypond-book.py:148
+#: lilypond-book.py:163
msgid "process ly_files using COMMAND FILE..."
msgstr "prosessoi ly_tiedostot käyttäen komentoa COMMAND FILE..."
-#: lilypond-book.py:159
+#: lilypond-book.py:168
msgid ""
"extract all PostScript fonts into INPUT.psfonts for LaTeXmust use this with "
"dvips -h INPUT.psfonts"
"poimi kaikki PostScript fontit tiedostoon INPUT.psfonts LaTeX:ia varten\n"
"\t tätä täytyy käyttää dvips -h INPUT.psfonts :in kanssa"
-#: lilypond-book.py:162 midi2ly.py:896 main.cc:183
+#: lilypond-book.py:171 midi2ly.py:912 main.cc:182
msgid "be verbose"
msgstr "tulosta runsaasti käsittelytietoa"
-#: lilypond-book.py:168 main.cc:184
+#: lilypond-book.py:177 main.cc:183
msgid "show warranty and copyright"
msgstr "näytä takuu ja copyright"
-#: lilypond-book.py:721
+#: lilypond-book.py:734
#, python-format
msgid "file not found: %s"
msgstr "tiedostoa %s ei löydy"
-#: lilypond-book.py:952
+#: lilypond-book.py:963
#, python-format
msgid "deprecated ly-option used: %s=%s"
msgstr "vanhentunut ly-optio käytössä: %s=%s"
-#: lilypond-book.py:955
+#: lilypond-book.py:966
#, python-format
msgid "compatibility mode translation: %s=%s"
msgstr "yhteensopivuusmuodon käännös: %s=%s"
-#: lilypond-book.py:959
+#: lilypond-book.py:970
#, python-format
msgid "deprecated ly-option used: %s"
msgstr "vanhentunut ly-optio käytössä: %s"
-#: lilypond-book.py:962
+#: lilypond-book.py:973
#, python-format
msgid "compatibility mode translation: %s"
msgstr "yhteensopivuusmuodon käännös: %s"
-#: lilypond-book.py:981
+#: lilypond-book.py:992
#, python-format
msgid "ignoring unknown ly option: %s"
msgstr "sivuutetaan tuntematon ly -optio: %s"
-#: lilypond-book.py:1318
+#: lilypond-book.py:1327
#, python-format
msgid "Opening filter `%s'"
msgstr "Avataan filtteri `%s'"
-#: lilypond-book.py:1335
+#: lilypond-book.py:1344
#, python-format
msgid "`%s' failed (%d)"
msgstr "`%s' epäonnistui (%d)"
-#: lilypond-book.py:1336
+#: lilypond-book.py:1345
msgid "The error log is as follows:"
msgstr "Virheloki on seuraava:"
-#: lilypond-book.py:1405
-msgid "Can't find \\begin{document} in LaTeX document"
-msgstr "Ei voitu löytää \\begin{document} LaTeX-documentista"
-
-#: lilypond-book.py:1513
+#: lilypond-book.py:1512
msgid "Writing snippets..."
msgstr "Kirjoitetaan palasia..."
-#: lilypond-book.py:1518
+#: lilypond-book.py:1517
msgid "Processing..."
msgstr "Prosessoidaan..."
-#: lilypond-book.py:1522
+#: lilypond-book.py:1521
msgid "All snippets are up to date..."
-msgstr "Kaikki palaset on päivitetty..."
+msgstr "Kaikki palaset on päivitetty"
-#: lilypond-book.py:1532
+#: lilypond-book.py:1531
#, python-format
msgid "can't determine format for: %s"
msgstr "ei löytynyt formaattia: %s"
-#: lilypond-book.py:1543
+#: lilypond-book.py:1542
#, python-format
msgid "%s is up to date."
msgstr "%s on päivitetty."
-#: lilypond-book.py:1549
+#: lilypond-book.py:1548
#, python-format
msgid "Writing `%s'..."
msgstr "Kirjoitetaan `%s'..."
-#: lilypond-book.py:1604
+#: lilypond-book.py:1595
msgid "Output would overwrite input file; use --output."
msgstr "Tuloste kirjautuisi syötetiedoston päälle; käytä --output."
-#: lilypond-book.py:1608
+#: lilypond-book.py:1599
#, python-format
msgid "Reading %s..."
msgstr "Luetaan %s..."
-#: lilypond-book.py:1627
+#: lilypond-book.py:1618
msgid "Dissecting..."
msgstr "Analysoidaan..."
-#: lilypond-book.py:1643
+#: lilypond-book.py:1634
#, python-format
msgid "Compiling %s..."
msgstr "Kootaan %s..."
-#: lilypond-book.py:1652
+#: lilypond-book.py:1643
#, python-format
msgid "Processing include: %s"
msgstr "Prosessoidaan sisällytetävä: %s"
-#: lilypond-book.py:1666
+#: lilypond-book.py:1657
#, python-format
msgid "Removing `%s'"
msgstr "Poistetaan `%s'"
-#: lilypond-book.py:1743
+#: lilypond-book.py:1717
#, python-format
msgid "Writing fonts to %s..."
msgstr "Kirjoitetaan fontteja hakemistoon %s..."
-#: lilypond-book.py:1758
+#: lilypond-book.py:1729
msgid "option --psfonts not used"
msgstr "optiota --psfonts=FILE ei käytetty"
-#: lilypond-book.py:1759
+#: lilypond-book.py:1730
msgid "processing with dvips will have no fonts"
msgstr "prosessointi dvips:illä ei sisällä fontteja"
-#: lilypond-book.py:1762
+#: lilypond-book.py:1736
msgid "DVIPS usage:"
msgstr "DVIPS käyttö:"
-#: midi2ly.py:106 lily-library.scm:541 lily-library.scm:549
+#: midi2ly.py:122 lily-library.scm:489 lily-library.scm:497
msgid "warning: "
msgstr "varoitus: "
-#: midi2ly.py:109 midi2ly.py:925
+#: midi2ly.py:125 midi2ly.py:941
msgid "error: "
msgstr "virhe: "
-#: midi2ly.py:110
+#: midi2ly.py:126
msgid "Exiting ... "
msgstr "Lopettaa ... "
-#: midi2ly.py:857
+#: midi2ly.py:873
#, python-format
msgid "%s output to `%s'..."
msgstr "%s tulostetaan paikkaan `%s'..."
-#: midi2ly.py:871
+#: midi2ly.py:887
msgid "Convert MIDI to LilyPond source."
msgstr "Muunna MIDI LilyPond -muotoon."
-#: midi2ly.py:875
+#: midi2ly.py:891
msgid "print absolute pitches"
msgstr "tulosta tarkat äänenkorkeudet"
-#: midi2ly.py:877 midi2ly.py:889
+#: midi2ly.py:893 midi2ly.py:905
msgid "DUR"
msgstr "PIT"
-#: midi2ly.py:878
+#: midi2ly.py:894
msgid "quantise note durations on DUR"
msgstr "kvantisoi nuottipituuden PIT perusteella"
# tulosta yksikäsitteiset nuottipituudet
-#: midi2ly.py:881
+#: midi2ly.py:897
msgid "print explicit durations"
msgstr "tulosta yksikäsitteiset nuottipituudet"
-#: midi2ly.py:882
+#: midi2ly.py:898
msgid "set key: ALT=+sharps|-flats; MINOR=1"
msgstr "aseta sävellaji: ETUMERKIT=+ylennykset|-alennukset; MOLLI=1"
-#: midi2ly.py:883
+#: midi2ly.py:899
msgid "ALT[:MINOR]"
msgstr "ETUMERKIT[:MOLLI]"
-#: midi2ly.py:888
+#: midi2ly.py:904
msgid "quantise note starts on DUR"
msgstr "nuottien kvantisointi alkukohtana PIT"
-#: midi2ly.py:891
+#: midi2ly.py:907
msgid "DUR*NUM/DEN"
msgstr "PIT*OSOITTAJA/NIMITTÄJÄ"
# tuplet = Wertaufteilung nach: Peter Giger: Die Kunst des Rhythmus, Seite 25
-#: midi2ly.py:894
+#: midi2ly.py:910
msgid "allow tuplet durations DUR*NUM/DEN"
msgstr "salli tupletti -pituudet PIT*OSOITTAJA/NIMITTÄJÄ"
-#: midi2ly.py:902
+#: midi2ly.py:918
msgid "treat every text as a lyric"
msgstr "käsittele kaikki tekstit lyriikkana"
-#: midi2ly.py:905
+#: midi2ly.py:921
msgid "example"
msgstr "esimerkki"
-#: midi2ly.py:926
+#: midi2ly.py:942
msgid "no files specified on command line."
msgstr "tiedostoja ei annettu komentorivillä."
msgid "invalid argument `%s' to option `%s'"
msgstr "epäkelpo argumentti `%s' optiolle `%s'"
-#: warn.cc:68 grob.cc:552 input.cc:82
+#: warn.cc:68 grob.cc:462
#, c-format
msgid "programming error: %s"
msgstr "ohjelmointivirhe: %s"
-#: warn.cc:69 input.cc:83
+#: warn.cc:69
msgid "continuing, cross fingers"
msgstr "jatketaan, ristitään kädet"
msgid "pair or context-name expected for accidental rule, found %s"
msgstr "pari tai konteksti-nimi oletettiin korotusmerkkisäännölle, löytyi %s"
-#: accidental.cc:243 key-signature-interface.cc:124
+#: accidental.cc:239 key-signature-interface.cc:124
#, c-format
msgid "accidental `%s' not found"
msgstr "korotusmerkkiä `%s' ei löydy"
-#: align-interface.cc:164
+#: align-interface.cc:160
msgid ""
"vertical alignment called before line-breaking.\n"
"Only do cross-staff spanners with PianoStaff."
msgstr ""
"pystysyora sijoittelu kutsuttiin ennen rivinkatkaisua.\n"
-"Viivaston ylittävät ladokkeet tehdään vain PianoStaff:in yhteydessä."
+"Viivaston ylittävät ladokkeet tehdään vain PianoStaff:in yhteydessä"
-#: align-interface.cc:314
-msgid "tried to get a translation for something that isn't my child"
-msgstr "yritettiin saada käännösteksti jollekin, joka ei ole lapseni"
-
-#: all-font-metrics.cc:164
+#: all-font-metrics.cc:213
#, c-format
msgid "can't find font: `%s'"
msgstr "ei löytynyt fonttia: `%s'"
-#: all-font-metrics.cc:165
+#: all-font-metrics.cc:214
msgid "loading default font"
msgstr "ladataan oletusfontti"
-#: all-font-metrics.cc:172
+#: all-font-metrics.cc:224
#, c-format
msgid "can't find default font: `%s'"
msgstr "ei löytynyt oletusfonttia: `%s'"
-#: all-font-metrics.cc:173 includable-lexer.cc:62 lily-parser-scheme.cc:108
+#: all-font-metrics.cc:225 includable-lexer.cc:62 lily-parser-scheme.cc:97
#, c-format
msgid "(search path: `%s')"
msgstr "(hakupolku: `%s')"
-#: all-font-metrics.cc:174 volta-engraver.cc:158
+#: all-font-metrics.cc:226 volta-engraver.cc:157
msgid "giving up"
msgstr "luovutetaan"
-#: apply-context-iterator.cc:31
+#: apply-context-iterator.cc:34
msgid "\\applycontext argument is not a procedure"
msgstr "\\applycontext vaatii funktioargumentin"
msgid "removing this vertical group"
msgstr "poistetaan tämä vertikaaliryhmä"
-#: axis-group-interface.cc:94
-msgid "tried to calculate pure-height at a non-breakpoint"
-msgstr "yritettiin laskea korkeus ei-katkaisukohdassa"
-
#: bar-check-iterator.cc:73
#, c-format
msgid "barcheck failed at: %s"
msgstr "tahtiviivan tarkistus epäonnistui kohdassa: %s"
-#: beam-engraver.cc:128
+#: beam-engraver.cc:136
msgid "already have a beam"
msgstr "palkki löytyi jo"
-#: beam-engraver.cc:196
+#: beam-engraver.cc:205
msgid "unterminated beam"
msgstr "päättämätön palkki"
-#: beam-engraver.cc:237 chord-tremolo-engraver.cc:134
+#: beam-engraver.cc:246 chord-tremolo-engraver.cc:162
msgid "stem must have Rhythmic structure"
msgstr "varrella on oltava Rhytmic -rakenne"
-#: beam-engraver.cc:245
+#: beam-engraver.cc:259
msgid "stem doesn't fit in beam"
msgstr "varsi ei sovi palkkiin"
-#: beam-engraver.cc:246
+#: beam-engraver.cc:260
msgid "beam was started here"
msgstr "palkki aloitettiin täältä"
msgid "no feasible beam position"
msgstr "ei löytynyt sopivaa palkin paikkaa"
-#: beam.cc:144
-msgid "removing beam with no stems"
-msgstr "poistetaan palkki jolla ei ole parrua"
+#: beam.cc:126
+msgid "removing beam with less than two stems"
+msgstr "poistetaan palkki jolla olisi vähemmän kuin kaksi pystyviivaa"
-#: beam.cc:995
+#: beam.cc:981
msgid "no viable initial configuration found: may not find good beam slope"
msgstr "toimivaa alkuasettelua ei löytynyt: hyvää palkkikaltevuuta ei löytyne"
-#: break-align-interface.cc:208
+#: break-align-interface.cc:194
#, c-format
msgid "No spacing entry from %s to `%s'"
msgstr "Ei välistyksen syöttöä paikasta %s paikkaan `%s'"
msgid "none of these in my family"
msgstr "ei yksikään näistä perheessäni"
-#: chord-tremolo-engraver.cc:88
-msgid "No tremolo to end"
-msgstr "Ei löytynyt päätettävää tremoloa"
+#: chord-tremolo-engraver.cc:96
+#, c-format
+msgid "expect 2 elements for chord tremolo, found %d"
+msgstr "odotettiin 2 elementtiä sointutremololle, löytyi %d"
-#: chord-tremolo-engraver.cc:110
+#: chord-tremolo-engraver.cc:132
msgid "unterminated chord tremolo"
msgstr "päättämätön sointutremolo"
-#: chord-tremolo-iterator.cc:33
-#, c-format
-msgid "expect 2 elements for chord tremolo, found %d"
-msgstr "odotettiin 2 elementtiä sointutremololle, löytyi %d"
+#: chord-tremolo-iterator.cc:60
+msgid "no one to print a tremolos"
+msgstr "tremoloa ei voitu tulostaa"
#: clef.cc:55
#, c-format
msgid "junking empty cluster"
msgstr "heitetään pois tyhjä klusteri"
-#: coherent-ligature-engraver.cc:106
+#: coherent-ligature-engraver.cc:86
+#, c-format
+msgid "gotcha: ptr=%ul"
+msgstr "löytyi: ptr=%ul"
+
+#: coherent-ligature-engraver.cc:93
+msgid "distance undefined, assuming 0.1"
+msgstr "etäisyys määrittämättä, oletetaan 0.1"
+
+#: coherent-ligature-engraver.cc:96
+#, c-format
+msgid "distance=%f"
+msgstr "etäisyys=%f"
+
+#: coherent-ligature-engraver.cc:136
#, c-format
msgid "Coherent_ligature_engraver: setting `spacing-increment=0.01': ptr=%ul"
-msgstr "Coherent_ligature_engraver: asetetaan `spacing-increment=0.01': ptr=%ul"
+msgstr ""
+"Coherent_ligature_engraver: asetetaan `spacing-increment=0.01': ptr=%ul"
+
+#: constrained-breaking.cc:124
+msgid "no system number set in constrained-breaking"
+msgstr "viivastojen määrää ei asetettu pakotetussa katkaisussa"
#. if we get to here, just put everything on one line
-#: constrained-breaking.cc:176 constrained-breaking.cc:193
+#: constrained-breaking.cc:225 constrained-breaking.cc:241
msgid "couldn't find line breaking that satisfies constraints"
msgstr "ei löytynyt rivinkatkaisukohtaa joka täyttäisi ehdot"
-#: context-def.cc:128
+#: context-def.cc:123
#, c-format
msgid "program has no such type: `%s'"
msgstr "ohjelmalla ei ole tyyppiä: `%s'"
+#: context-def.cc:311
+#, c-format
+msgid "can't find: `%s'"
+msgstr "ei löytynyt `%s'"
+
#: context-property.cc:77
msgid "need symbol arguments for \\override and \\revert"
msgstr "tarvitaan symboliargumentti funktioille \\override ja \\revert"
-#: context.cc:151
+#: context.cc:160
#, c-format
msgid "can't find or create new `%s'"
msgstr "ei löydetty tai ei luotu uutta `%s'"
-#: context.cc:213
+#: context.cc:222
#, c-format
msgid "can't find or create `%s' called `%s'"
msgstr "ei löydetty tai ei luotu `%s' nimeltä `%s'"
#: context.cc:276
#, c-format
-msgid "Invalid CreateContext event: Cannot create %s context"
-msgstr "Epäkelpo CreateContext-tapahtuma: Ei voitu luoda %s-kontekstia"
-
-#: context.cc:388
-#, c-format
msgid "can't find or create: `%s'"
msgstr "ei löydetty tai ei luotu: `%s'"
msgid "custos `%s' not found"
msgstr "custos `%s' ei löytynyt"
-#: dispatcher.cc:72
-msgid "Event class should be a symbol"
-msgstr "Tapamahtumaluokan tulisi olla symboli"
-
-#: dispatcher.cc:79
-#, c-format
-msgid "Unknown event class %s"
-msgstr "Tuntematon tapahtumaluokka %s"
-
-#: dynamic-engraver.cc:186 span-dynamic-performer.cc:87
+#: dynamic-engraver.cc:181 span-dynamic-performer.cc:84
msgid "can't find start of (de)crescendo"
msgstr "ei löytynyt alkua (de)crescendolle"
-#: dynamic-engraver.cc:195
+#: dynamic-engraver.cc:190
msgid "already have a decrescendo"
msgstr "decresendo jo käytössä"
-#: dynamic-engraver.cc:197
+#: dynamic-engraver.cc:192
msgid "already have a crescendo"
msgstr "crescendo jo käytössä"
-#: dynamic-engraver.cc:200
+#: dynamic-engraver.cc:195
msgid "cresc starts here"
msgstr "cresc aloitettiin tästä"
-#: dynamic-engraver.cc:323
+#: dynamic-engraver.cc:318
msgid "unterminated (de)crescendo"
msgstr "päättämätön (de)crescendo"
-#: engraver.cc:102
-msgid "not setting creation callback: not a procedure"
-msgstr "ei aseteta luonnin takaisinkutsua: ei ole proseduuri"
+#: event-chord-iterator.cc:53 output-property-music-iterator.cc:31
+#, c-format
+msgid "junking event: `%s'"
+msgstr "hylätään tapahtuma: `%s'"
-#: extender-engraver.cc:130 extender-engraver.cc:139
+#: extender-engraver.cc:131 extender-engraver.cc:140
msgid "unterminated extender"
msgstr "päättämätön pidennys"
+#: folded-repeat-iterator.cc:63
+msgid "no one to print a repeat brace"
+msgstr "kukaan ei voinut tulostaa toistoa"
+
#: font-config.cc:28
msgid "Initializing FontConfig..."
msgstr "Alustetaan FontConfig..."
-#: font-config.cc:44
-#, c-format
-msgid "Rebuilding FontConfig cache %s, this may take a while..."
-msgstr "Käännetään uudelleen FontConfig-välimuisti %s. tämä voi kestää hetken..."
-
-#: font-config.cc:55
+#: font-config.cc:38
#, c-format
-msgid "failed adding font directory: %s"
-msgstr "ei onnistuttu lisäämään fonttihakemistoa: %s"
+msgid "Rebuilding FontConfig cache %s. this may take a while..."
+msgstr ""
+"Käännetään uudelleen FontConfig välimuisti %s. tämä voi kestää hetken..."
-#: font-config.cc:57
+#: font-config.cc:49 font-config.cc:51
#, c-format
msgid "adding font directory: %s"
msgstr "lisätään fonttihakemisto: %s"
msgid "unterminated glissando"
msgstr "päättämätön glissando"
-#: global-context-scheme.cc:91 global-context-scheme.cc:107
+#: global-context-scheme.cc:50 global-context-scheme.cc:77
msgid "no music found in score"
msgstr "Laita musiikkia viivastolle"
-#: global-context-scheme.cc:97
+#: global-context-scheme.cc:68
msgid "Interpreting music... "
-msgstr "Tulkitaan musiikkia... "
+msgstr "Tulkitaan musiikkia..."
-#: global-context-scheme.cc:120
+#: global-context-scheme.cc:88
#, c-format
msgid "elapsed time: %.2f seconds"
msgstr "kulunut aika: %.2f sekuntia"
-#: gregorian-ligature-engraver.cc:59
+#: global-context.cc:159
+#, c-format
+msgid "can't find `%s' context"
+msgstr "ei löytynyt kontekstia `%s'"
+
+#: gourlay-breaking.cc:202
+#, c-format
+msgid "Optimal demerits: %f"
+msgstr "Optimaalinen heikennys: %f"
+
+#: gourlay-breaking.cc:207
+msgid "no feasible line breaking found"
+msgstr "Ei löytynyt sopivaa viivan katkaisukohtaa"
+
+#: gourlay-breaking.cc:215
+msgid "can't find line breaking that satisfies constraints"
+msgstr "ei löytynyt sopivaa rivin katkaisukohtaa joka täyttäisi ehdot"
+
+#: gregorian-ligature-engraver.cc:61
#, c-format
msgid "\\%s ignored"
msgstr "\\%s sivuutettiin"
-#: gregorian-ligature-engraver.cc:64
+#: gregorian-ligature-engraver.cc:66
#, c-format
msgid "implied \\%s added"
msgstr "lisättiin vihjattu \\%s"
#. ligature may not start with 2nd head of pes or flexa
-#: gregorian-ligature-engraver.cc:212
+#: gregorian-ligature-engraver.cc:214
msgid "can't apply `\\~' on first head of ligature"
msgstr "di voitu käyttää `\\~' ligaturen alkupäässä"
#. (pitch == prev_pitch)
-#: gregorian-ligature-engraver.cc:224
+#: gregorian-ligature-engraver.cc:226
msgid "can't apply `\\~' on heads with identical pitch"
msgstr "ei voitu käyttää `\\~' identtisien nuotinkorkeuksien päissä"
msgid "Grob `%s' has no interface for property `%s'"
msgstr "Ladokkeella `%s' ei ole rajapintaa ominaisuudella `%s'"
-#: grob-property.cc:36
-msgid "not setting modification callback: not a procedure"
-msgstr "ei aseteta muutoksen takaisinkutsua: ei ole proseduuri"
-
-#: grob.cc:253
+#: grob.cc:242
msgid "Infinity or NaN encountered"
msgstr "ääretön tai NaN kohdattiin"
-#: hairpin.cc:179
+#: hairpin.cc:149
msgid "decrescendo too small"
msgstr "liian lyhyt decrescendo"
-#: hairpin.cc:180
+#: hairpin.cc:150
msgid "crescendo too small"
msgstr "liian lyhyt crescendo"
msgid "include files are not allowed in safe mode"
msgstr "sisällytettävät tiedostot eivät ole sallittuja turvatilassa"
-#: includable-lexer.cc:60 lily-guile.cc:96 lily-parser-scheme.cc:115
+#: includable-lexer.cc:60 lily-guile.cc:96 lily-parser-scheme.cc:104
#, c-format
msgid "can't find file: `%s'"
msgstr "tiedostoa ei löydy: `%s'"
-#: input.cc:112 source-file.cc:168 source-file.cc:183
+#: input.cc:103 source-file.cc:153 source-file.cc:168
msgid "position unknown"
-msgstr "sijainti tuntematon"
+msgstr "sijainti tuntematon:"
-#: ligature-engraver.cc:95
+#: ligature-engraver.cc:100
msgid "can't find start of ligature"
msgstr "ei löytynyt alkua ligature:lle"
-#: ligature-engraver.cc:100
+#: ligature-engraver.cc:105
msgid "no right bound"
msgstr "ei oikeata reunaa"
-#: ligature-engraver.cc:122
+#: ligature-engraver.cc:127
msgid "already have a ligature"
msgstr "ligature löytyi jo"
-#: ligature-engraver.cc:131
+#: ligature-engraver.cc:136
msgid "no left bound"
msgstr "ei vasenta reunaa"
-#: ligature-engraver.cc:175
+#: ligature-engraver.cc:180
msgid "unterminated ligature"
msgstr "päättämätön ligature"
-#: ligature-engraver.cc:204
+#: ligature-engraver.cc:209
msgid "ignoring rest: ligature may not contain rest"
msgstr "ligature ei voi sisältää taukoa; sivuutetaan tauko"
-#: ligature-engraver.cc:205
+#: ligature-engraver.cc:210
msgid "ligature was started here"
msgstr "ligature alkoi tästä"
msgid "(load path: `%s')"
msgstr "(hakupolku: `%s')"
-#: lily-guile.cc:439
+#: lily-guile.cc:441
#, c-format
msgid "can't find property type-check for `%s' (%s)."
msgstr "Ei löytynyt tyyppitarkistusta ominaisuudelle `%s' (%s)."
-#: lily-guile.cc:442
+#: lily-guile.cc:444
msgid "perhaps a typing error?"
msgstr "ehkä näppäilyvirhe?"
-#: lily-guile.cc:448
+#: lily-guile.cc:450
msgid "doing assignment anyway"
msgstr "suoritetaan tehtävä joka tapauksessa"
-#: lily-guile.cc:460
+#: lily-guile.cc:462
#, c-format
msgid "type check for `%s' failed; value `%s' must be of type `%s'"
msgstr "tyypin `%s' tarkistus epäonnistui; arvon `%s' on oltava tyyppiä `%s'"
-#: lily-lexer.cc:222
+#: lily-lexer.cc:223
#, c-format
msgid "identifier name is a keyword: `%s'"
msgstr "tunnistenimi on avainsana: `%s'"
-#: lily-lexer.cc:237
+#: lily-lexer.cc:238
#, c-format
msgid "error at EOF: %s"
msgstr "virhe tiedoston lopussa (EOF): %s"
-#: lily-parser-scheme.cc:30
+#: lily-parser-scheme.cc:29
#, c-format
msgid "deprecated function called: %s"
msgstr "vanhentunut funktiokutsu: %s"
-#: lily-parser-scheme.cc:89
+#: lily-parser-scheme.cc:76
#, c-format
msgid "Changing working directory to `%s'"
msgstr "Vaihdetaan työhakemistoksi `%s'"
-#: lily-parser-scheme.cc:107
+#: lily-parser-scheme.cc:96
#, c-format
msgid "can't find init file: `%s'"
msgstr "tiedostoa ei löydy: `%s'"
-#: lily-parser-scheme.cc:125
+#: lily-parser-scheme.cc:114
#, c-format
msgid "Processing `%s'"
-msgstr "Prosessoidaan `%s'"
+msgstr "Prosessoidaan `%s'..."
#: lily-parser.cc:97
msgid "Parsing..."
msgid "braces don't match"
msgstr "aaltosulkumerkit eivät täsmää"
-#: lyric-combine-music-iterator.cc:286
+#: lyric-combine-music-iterator.cc:256
#, c-format
msgid "cannot find Voice `%s'"
msgstr "ei löydetty Voice `%s'"
-#: main.cc:117
+#: main.cc:116
#, c-format
msgid ""
"This program is free software. It is covered by the GNU General Public\n"
"ja olet tervetullut muuttamaan ohjelmaa ja/tai levittämään siitä kopioita\n"
"tietyillä ehdoilla. Suorita `%s --warranty' saadaksesi lisäinformaatiota.\n"
-#: main.cc:123
+#: main.cc:122
msgid ""
" This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public License version 2\n"
"Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
"Boston, MA 02111-1307, USA.\n"
-#: main.cc:154
+#: main.cc:153
msgid "BACK"
msgstr "PÄÄ"
-#: main.cc:154
+#: main.cc:153
msgid ""
"use backend BACK (gnome, ps,eps,\n"
"scm, svg, tex, texstr)\n"
"scm, svg, tex, texstr)\n"
"default: PS"
-#: main.cc:156
+#: main.cc:155
msgid "SYM=VAL"
msgstr "SYM=VAL"
-#: main.cc:157
+#: main.cc:156
msgid ""
"set a Scheme program option. Uses #t if VAL is not specified\n"
"Try -dhelp for help."
"aseta Scheme -ohjelman optio. Käyttää #t jos VAL ei ole määritelty\n"
"Koeta -dhelp saadaksesi lisäapua."
-#: main.cc:160
+#: main.cc:159
msgid "EXPR"
msgstr "LAUSEKE"
-#: main.cc:160
+#: main.cc:159
msgid "evaluate scheme code"
msgstr "suorita scheme koodi"
#. Bug in option parser: --output =foe is taken as an abbreviation
#. for --output-format.
-#: main.cc:163
+#: main.cc:162
msgid "FORMATs"
msgstr "FORMAATIT"
-#: main.cc:163
+#: main.cc:162
msgid "dump FORMAT,... Also as separate options:"
msgstr "vedosta FORMAATTI,... Myös erilliset optiot:"
-#: main.cc:164
+#: main.cc:163
msgid "generate DVI (tex backend only)"
msgstr "tuota DVI (vain käytettäessä tex -päätä)"
-#: main.cc:165
+#: main.cc:164
msgid "relocate using directory of lilypond program"
msgstr "paikallista käyttäen lilypond ohjelman hakemistoa"
-#: main.cc:166
+#: main.cc:165
msgid "generate PDF (default)"
msgstr "tuota PDF (oletus)"
-#: main.cc:167
+#: main.cc:166
msgid "generate PNG"
msgstr "tuota PNG"
-#: main.cc:168
+#: main.cc:167
msgid "generate PostScript"
msgstr "tuota PostScript"
-#: main.cc:169
+#: main.cc:168
msgid "generate TeX (tex backend only)"
msgstr "tuota TeX (vain käytettäessä tex -päätä)"
-#: main.cc:170
+#: main.cc:169
msgid "print this help"
msgstr "näytä tämä opaste"
-#: main.cc:171
+#: main.cc:170
msgid "FIELD"
msgstr "KENTTÄ"
-#: main.cc:171
+#: main.cc:170
msgid "dump a header field to file BASENAME.FIELD"
msgstr "kirjoita otsake tiedostoon PERUSNIMI.KENTTÄ"
-#: main.cc:172
+#: main.cc:171
msgid "DIR"
msgstr "HAKEMISTO"
-#: main.cc:172
+#: main.cc:171
msgid "add DIR to search path"
msgstr "lisää HAKEMISTO hakupolkuun"
-#: main.cc:173
+#: main.cc:172
msgid "use FILE as init file"
msgstr "käytä TIEDOSTO alustustiedostona"
-#: main.cc:175
+#: main.cc:174
msgid "USER,GROUP,JAIL,DIR"
msgstr "USER,GROUP,JAIL,DIR"
-#: main.cc:175
+#: main.cc:174
msgid ""
"chroot to JAIL, become USER:GROUP\n"
"and cd into DIR"
"käytä chroot-hakemistona JAIL, ole USER:GROUP\n"
"ja siirry hakemistoon DIR"
-#: main.cc:178
+#: main.cc:177
msgid "do not generate printed output"
msgstr "älä tuota tulostetta"
-#: main.cc:179
+#: main.cc:178
msgid "write output to FILE (suffix will be added)"
msgstr "tulosta tiedostoon TIEDOSTO (pääte lisätään)"
-#: main.cc:180
+#: main.cc:179
msgid "generate a preview of the first system"
msgstr "tee kuva ensimmäisestä kokonaisuudesta"
-#: main.cc:181
+#: main.cc:180
msgid "disallow unsafe Scheme and PostScript operations"
msgstr "älä salli turvattomia Scheme ja PostScript -operaatioita"
-#: main.cc:182
+#: main.cc:181
msgid "print version number"
msgstr "tulosta versionumero"
-#: main.cc:223
+#: main.cc:221
#, c-format
msgid ""
"Copyright (c) %s by\n"
"%s ja muut."
#. No version number or newline here. It confuses help2man.
-#: main.cc:250
+#: main.cc:248
#, c-format
msgid "Usage: %s [OPTION]... FILE..."
msgstr "Käyttö: %s [OPTIO]... TIEDOSTO..."
-#: main.cc:252
+#: main.cc:250
#, c-format
msgid "Typeset music and/or produce MIDI from FILE."
msgstr "Lado musiikki ja/tai tuota MIDI tiedostosta TIEDOSTO."
-#: main.cc:254
+#: main.cc:252
#, c-format
msgid "LilyPond produces beautiful music notation."
msgstr "LilyPond tuottaa kaunista musiikkinotaatiota."
-#: main.cc:256
+#: main.cc:254
#, c-format
msgid "For more information, see %s"
-msgstr "Lisätietoja varten, katso %s"
+msgstr "Lisätietoja varten, katso %s."
-#: main.cc:258
+#: main.cc:256
#, c-format
msgid "Options:"
msgstr "Optiot:"
-#: main.cc:262
+#: main.cc:260
#, c-format
msgid "Report bugs via %s"
-msgstr "Raportoi virheet osoitteeseen %s"
+msgstr "Raportoi virheet osoitteeseen %s."
-#: main.cc:308
-#, c-format
+#: main.cc:306
+#, fuzzy, c-format
msgid "expected %d arguments with jail, found: %u"
-msgstr "odotettiin %d argumenttia chroot-vankilalle, löytyi: %u"
+msgstr "odotettiin %d argumenttia jail:ille, löytyi: %d"
-#: main.cc:322
+#: main.cc:320
#, c-format
msgid "no such user: %s"
msgstr "käyttäjää ei löydy: `%s'"
-#: main.cc:324
+#: main.cc:322
#, c-format
msgid "can't get user id from user name: %s: %s"
msgstr "ei saatu käyttäjä-id:tä käyttäjänimestä: %s: %s"
-#: main.cc:339
+#: main.cc:337
#, c-format
msgid "no such group: %s"
msgstr "ryhmää ei ole: %s"
-#: main.cc:341
+#: main.cc:339
#, c-format
msgid "can't get group id from group name: %s: %s"
msgstr "ei voitu saada ryhmä -id:tä ryhmänimestä: %s: %s"
-#: main.cc:349
+#: main.cc:347
#, c-format
msgid "can't chroot to: %s: %s"
msgstr "chroot ei onnistunut: %s: %s"
-#: main.cc:356
+#: main.cc:354
#, c-format
msgid "can't change group id to: %d: %s"
msgstr "ei voitu korvata ryhmän id:tä : %d: %s"
-#: main.cc:362
+#: main.cc:360
#, c-format
msgid "can't change user id to: %d: %s"
msgstr "ei voitu vaihtaa käyttäjä-id:tä : %d: %s"
-#: main.cc:368
+#: main.cc:366
#, c-format
msgid "can't change working directory to: %s: %s"
msgstr "työhakemiston vaihto ei onnistunut: %s: %s"
-#: main.cc:415
+#: main.cc:413
#, c-format
msgid "Evaluating %s"
msgstr "Määritetään %s"
-#: main.cc:638
+#: main.cc:627
#, c-format
msgid "exception caught: %s"
msgstr "napattiin poikkeus: %s"
#. FIXME: constant error message.
-#: mark-engraver.cc:154
+#: mark-engraver.cc:131
msgid "rehearsalMark must have integer value"
msgstr "rehearsalMark vaatii kokonaislukuargumentin"
-#: mark-engraver.cc:160
+#: mark-engraver.cc:137
msgid "mark label must be a markup object"
msgstr "merkinnän on oltava markup -objekti"
-#: mensural-ligature-engraver.cc:88
+#: mensural-ligature-engraver.cc:77
msgid "ligature with less than 2 heads -> skipping"
msgstr "ligatuuri vähemmällä kuin 2:lla nuottipäällä -> ohitetaan"
-#: mensural-ligature-engraver.cc:115
+#: mensural-ligature-engraver.cc:104
msgid "cannot determine pitch of ligature primitive -> skipping"
msgstr "ei voitu määrittää nuottikorkeutta ligatuurin osalle -> ohitetaan"
-#: mensural-ligature-engraver.cc:129
+#: mensural-ligature-engraver.cc:118
msgid "single note ligature - skipping"
msgstr "priimi-intervalli ligatuurissa -> ohitetaan"
-#: mensural-ligature-engraver.cc:141
+#: mensural-ligature-engraver.cc:130
msgid "prime interval within ligature -> skipping"
msgstr "priimi-intervalli ligatuurissa -> ohitetaan"
-#: mensural-ligature-engraver.cc:153
+#: mensural-ligature-engraver.cc:142
msgid "mensural ligature: duration none of Mx, L, B, S -> skipping"
msgstr "mensuraaliligatuuri: kesto ei ollut Mx, L, B tai S -> ohitetaan"
-#: mensural-ligature-engraver.cc:201
+#: mensural-ligature-engraver.cc:190
msgid "semibrevis must be followed by another one -> skipping"
msgstr "semibrevis vaatii samantyyppisen seuraavaksi -> ohitetaan"
-#: mensural-ligature-engraver.cc:212
+#: mensural-ligature-engraver.cc:201
msgid ""
"semibreves can only appear at the beginning of a ligature,\n"
"and there may be only zero or two of them"
"semibreve:t voivat esiintyä vain ligaturen alussa,\n"
"ja niitä voi olla vain nolla tai kaksi"
-#: mensural-ligature-engraver.cc:239
+#: mensural-ligature-engraver.cc:228
msgid ""
"invalid ligatura ending:\n"
"when the last note is a descending brevis,\n"
"toiseksi viimeisen nuotin on oltava joku muu,\n"
"tai ligaturan täytyy olla LB tai SSB"
-#: mensural-ligature-engraver.cc:359
+#: mensural-ligature-engraver.cc:348
msgid "unexpected case fall-through"
msgstr "odottamaton tapauksen raukeaminen"
msgid "no such MIDI instrument: `%s'"
msgstr "ei löytynyt MIDI-instrumenttia: `%s'"
-#: midi-item.cc:273
+#: midi-item.cc:264
msgid "silly pitch"
msgstr "sekava äänenkorkeus"
-#: midi-item.cc:289
+#: midi-item.cc:280
#, c-format
msgid "experimental: temporarily fine tuning (of %d cents) a channel."
msgstr "kokeellinen: viritetään väliaisesti (%d senttiä) kanavaa."
msgid "can't write to file: `%s'"
msgstr "tiedostoon ei voitu kirjoittaa: `%s'"
-#: music-iterator.cc:172
-msgid "Sending non-event to context"
-msgstr "Lähetetään ei-tapahtuma kontekstille"
-
-#: music.cc:142
+#: music.cc:140
#, c-format
-msgid "octave check failed; expected \"%s\", found: %s"
-msgstr "oktaavitarkistus epäonnistui; oletettiin \"%s\", löydettiin: %s"
+msgid "octave check failed; expected %s, found: %s"
+msgstr "oktaavitarkistus epäonnistui; oletettiin %s, löydettiin: %s"
-#: music.cc:208
+#: music.cc:203
#, c-format
msgid "transposition by %s makes alteration larger than double"
msgstr "transponointi %s:N verran tekee muutokset suuremmaksi kuin kaksi"
-#: new-fingering-engraver.cc:87
+#: new-fingering-engraver.cc:84
msgid "can't add text scripts to individual note heads"
msgstr "ei voitu lisätä tekstinpätkiä yksittäisiin nuotteihin"
-#: new-fingering-engraver.cc:246
+#.
+#. music for the softenon children?
+#.
+#: new-fingering-engraver.cc:153
+msgid "music for the martians."
+msgstr "musiikkia marsilaisille."
+
+#: new-fingering-engraver.cc:261
msgid "no placement found for fingerings"
msgstr "sormitukselle ei löytynyt paikkaa"
-#: new-fingering-engraver.cc:247
+#: new-fingering-engraver.cc:262
msgid "placing below"
msgstr "sijoitetaan alle"
-#: note-collision.cc:415
+#: note-collision.cc:405
msgid "ignoring too many clashing note columns"
msgstr "liian monta törmäävää nuottisaraketta"
msgid "can't have note heads and rests together on a stem"
msgstr "ei voinut olla nuotinpäitä ja taukoja yhtäaikaa palkissa"
-#: note-head.cc:65
+#: note-head.cc:67
#, c-format
msgid "note head `%s' not found"
msgstr "nuottipäätä `%s' ei löytynyt"
-#: note-heads-engraver.cc:63
+#: note-heads-engraver.cc:84
msgid "NoteEvent without pitch"
msgstr "NoteEvent ilman nuottikorkeutta"
msgid "can't load font table: %s"
msgstr "ei voitu ladata fonttitaulukkoa: `%s'"
-#: open-type-font.cc:96
+#: open-type-font.cc:108
#, c-format
msgid "unsupported font format: %s"
msgstr "tukematon fonttimuoto: %s"
-#: open-type-font.cc:98
+#: open-type-font.cc:110
#, c-format
msgid "unknown error: %d reading font file: %s"
msgstr "tuntematon virhe: %d lukee fonttitiedostoa: %s"
-#: open-type-font.cc:171 open-type-font.cc:295
+#: open-type-font.cc:183 open-type-font.cc:307
#, c-format
msgid "FT_Get_Glyph_Name() returned error: %d"
msgstr "FT_Get_Glyph_Name() palautti virheen: %d"
-#: page-turn-page-breaking.cc:227
-msgid ""
-"couldn't fit the first page turn onto a single page. Consider setting first-"
-"page-number to an even number."
-msgstr ""
-"Ei voitu sovittaa ensimmäistä sivunkääntöä yhdelle sivulle. Harkitse "
-"ensimmäisen sivunumeron (first-page-number) asettamista parittomaksi."
-
-#: page-turn-page-breaking.cc:240
-#, c-format
-msgid "Calculating page and line breaks (%d possible page breaks)..."
-msgstr "Lasketaan sivujen ja rivien katkaisuja (%d mahdollista sivunkatkaisua)..."
-
-#: page-turn-page-breaking.cc:258 paper-score.cc:154
-msgid "Drawing systems..."
-msgstr "Piirretään tahteja..."
-
-#: pango-font.cc:215
+#: pango-font.cc:157
#, c-format
msgid "no PostScript font name for font `%s'"
msgstr "ei PostScript fonttinimeä fontille `%s'"
-#: pango-font.cc:263
+#: pango-font.cc:205
msgid "FreeType face has no PostScript font name"
msgstr "FreeType muodolla ei ollut PostScript fonttinimeä"
msgid "Layout output to `%s'..."
msgstr "Aseta tulostus paikkaan `%s'..."
-#: paper-score.cc:105
-msgid "Calculating line breaks..."
-msgstr "Lasketaan rivinvaihtoja..."
-
-#: paper-score.cc:118
+#: paper-score.cc:104
#, c-format
msgid "Element count %d (spanners %d) "
msgstr "Elementtien määrä: %d (ladokkeita: %d)"
-#: paper-score.cc:122
+#: paper-score.cc:108
msgid "Preprocessing graphical objects..."
msgstr "Esiprosessoidaan graafisia kohteita..."
msgid "GUILE signaled an error for the expression beginning here"
msgstr "GUILE antoi virheen lausekkeelle, joka alkoi täältä"
-#: percent-repeat-engraver.cc:200
+#: percent-repeat-engraver.cc:209
msgid "unterminated percent repeat"
msgstr "päättämätön prosenttitoisto"
-#: performance.cc:45
+#: percent-repeat-iterator.cc:52
+msgid "no one to print a percent"
+msgstr "kukaan ei voinut tulostaa prosenttia"
+
+#: performance.cc:46
msgid "Track..."
msgstr "Jälki..."
-#: performance.cc:66
+#: performance.cc:70
msgid "MIDI channel wrapped around"
msgstr "MIDI kanava kietaistiin ympäri"
-#: performance.cc:67
+#: performance.cc:71
msgid "remapping modulo 16"
msgstr "kuvataan uudelleen modulo 16"
-#: performance.cc:95
+#: performance.cc:90
+msgid "Creator: "
+msgstr "Tekijä: "
+
+#: performance.cc:110
+msgid "at "
+msgstr "kohdassa "
+
+#: performance.cc:162
#, c-format
msgid "MIDI output to `%s'..."
msgstr "Tehdään MIDI-tuloste `%s'..."
-#: phrasing-slur-engraver.cc:146
+#: phrasing-slur-engraver.cc:170
msgid "unterminated phrasing slur"
msgstr "päättämätön fraaseerauskaari"
-#: piano-pedal-engraver.cc:304
+#: piano-pedal-engraver.cc:223
#, c-format
msgid "expect 3 strings for piano pedals, found: %ld"
msgstr "odotettiin 3 merkkijonoa pianopedaalille, löytyi: %ld"
-#: piano-pedal-engraver.cc:319 piano-pedal-engraver.cc:330
-#: piano-pedal-performer.cc:93
+#: piano-pedal-engraver.cc:238 piano-pedal-engraver.cc:249
+#: piano-pedal-performer.cc:82
#, c-format
msgid "can't find start of piano pedal: `%s'"
msgstr "ei löydetty alkua pianopedaalille: `%s'"
-#: piano-pedal-engraver.cc:377
+#: piano-pedal-engraver.cc:296
#, c-format
msgid "can't find start of piano pedal bracket: `%s'"
msgstr "ei löydetty alkua pianopedaalimerkinnälle: `%s'"
msgid "no such internal option: %s"
msgstr "tuntematon sisäinen optio: %s"
-#: property-iterator.cc:74
+#: property-iterator.cc:81
#, c-format
msgid "not a grob name, `%s'"
-msgstr "ei ole graafisen objektin (grob) nimi, `%s'"
+msgstr "ei ole graafisen objektin (grob) nimi: `%s'."
+
+#: quote-iterator.cc:255
+#, c-format
+msgid "in quotation: junking event %s"
+msgstr "sitaatissa: hylätään tapahtuma `%s'"
#: relative-octave-check.cc:39
msgid "Failed octave check, got: "
msgstr "Oktaavitarkistus epäonnistui, saatiin: "
-#: relocate.cc:44
-#, c-format
-msgid "Setting %s to %s\n"
-msgstr "Asetetaan %s kohtaan %s\n"
-
-#: relocate.cc:58
+#: relocate.cc:52
#, c-format
msgid "no such file: %s for %s"
msgstr "tiedostoa ei löydy: %s kohteelle %s"
-#: relocate.cc:68 relocate.cc:86
+#: relocate.cc:62 relocate.cc:80
#, c-format
msgid "no such directory: %s for %s"
msgstr "hakemistoa ei löydy: %s kohteelle %s"
-#: relocate.cc:78
+#: relocate.cc:72
#, c-format
msgid "%s=%s (prepend)\n"
msgstr "%s=%s (painota)\n"
-#: relocate.cc:98
+#: relocate.cc:104
#, c-format
msgid "Relocation: compile prefix=%s, new prefix=%s"
msgstr "Paikantaminen: käännös-etuliite=%s, uusi etuliite=%s"
-#: relocate.cc:128
+#: relocate.cc:130
#, c-format
msgid "Relocation: framework_prefix=%s"
msgstr "Paikantaminen: framework_prefix=%s"
-#: relocate.cc:168
+#: relocate.cc:212
#, c-format
msgid "Relocation: is absolute: argv0=%s"
msgstr "Paikantaminen: absoluuttinen: argv0=%s"
-#: relocate.cc:175
+#: relocate.cc:219
#, c-format
msgid "Relocation: from cwd: argv0=%s"
msgstr "Paikantaminen: nykyisestä polusta: argv0=%s"
-#: relocate.cc:184
+#: relocate.cc:228
#, c-format
msgid ""
"Relocation: from PATH=%s\n"
"Paikantaminen: polusta PATH=%s\n"
"argv0=%s"
-#: relocate.cc:353
-#, c-format
-msgid "Relocation file %s\n"
-msgstr "Paikannustiedosto %s\n"
-
-#: relocate.cc:358
-#, c-format
-msgid "can't open file %s"
-msgstr "ei voitu avata tiedostoa %s"
-
-#: relocate.cc:388
-#, c-format
-msgid "Unknown relocation command %s"
-msgstr "Tuntematon paikannuskomento %s"
-
-#: rest-collision.cc:150
+#: rest-collision.cc:149
msgid "can't resolve rest collision: rest direction not set"
msgstr "ei voida määrittää taukojen törmäystä: tauon suuntaa ei asetettu"
-#: rest-collision.cc:164 rest-collision.cc:209
+#: rest-collision.cc:163 rest-collision.cc:208
msgid "too many colliding rests"
msgstr "liian monta törmäävää taukoa"
msgid "rest `%s' not found"
msgstr "taukoa `%s' ei löytynyt, "
-#: score-engraver.cc:68
+#: score-engraver.cc:67
#, c-format
msgid "cannot find `%s'"
msgstr "`%s' ei lyötynyt"
-#: score-engraver.cc:70
+#: score-engraver.cc:69
msgid "Music font has not been installed properly."
msgstr "Fontteja ei oltu asennettu kunnolla."
-#: score-engraver.cc:72
+#: score-engraver.cc:71
#, c-format
msgid "Search path `%s'"
msgstr "Hakupolku `%s'"
-#: score.cc:222
+#: score.cc:211
msgid "already have music in score"
msgstr "viivastolla on jo musiikkia"
-#: score.cc:223
+#: score.cc:212
msgid "this is the previous music"
msgstr "tämä on edellinen musiikki"
-#: score.cc:228
+#: score.cc:217
msgid "errors found, ignoring music expression"
msgstr "virheitä löytyi, sivuutetaan musiikki-ilmaisu"
#. FIXME:
-#: script-engraver.cc:102
+#: script-engraver.cc:105
msgid "don't know how to interpret articulation: "
msgstr "ei tiedetä kuinka tulkita artikulaatio: "
-#: script-engraver.cc:103
+#: script-engraver.cc:106
msgid "scheme encoding: "
msgstr "scheme koodaus: "
-#: simple-spacer.cc:375
+#: simple-spacer.cc:406
#, c-format
msgid "No spring between column %d and next one"
msgstr "Ei jousta sarakkeen %d ja sitä seuraavan välillä"
-#: slur-engraver.cc:83
-msgid "Invalid direction of slur-event"
-msgstr "Tuntematon kaari-tapahtuman suunta"
-
-#: slur-engraver.cc:156
+#: slur-engraver.cc:176
msgid "unterminated slur"
msgstr "päättämätön kaari"
-#: slur-engraver.cc:165
+#: slur-engraver.cc:185
msgid "can't end slur"
msgstr "ei löytynyt kaaren loppua"
msgid "expected to read %d characters, got %d"
msgstr "odotettiin %d merkkiä, saatiin %d"
-#: staff-symbol-engraver.cc:62
-msgid "staff-span event has no direction"
-msgstr "viivastot ylittävällä tapahtumalla ei ole suuntaa"
+#: spacing-spanner.cc:48
+#, c-format
+msgid "Global shortest duration is %s"
+msgstr "Yleinen lyhin kesto on %s"
-#: stem-engraver.cc:95
+#: stem-engraver.cc:93
msgid "tremolo duration is too long"
msgstr "tremolon kesto on liian pitkä"
#. FIXME:
-#: stem-engraver.cc:132
+#: stem-engraver.cc:130
#, c-format
msgid "adding note head to incompatible stem (type = %d)"
msgstr "lisätään nuottipää sopimattomaan varteen (tyyppi = %d)"
-#: stem-engraver.cc:134
+#: stem-engraver.cc:132
msgid "maybe input should specify polyphonic voices"
msgstr "ehkä syötteen täytyisi määrittää moniäänisiä ääniä"
-#: stem.cc:104
+#: stem.cc:98
msgid "weird stem size, check for narrow beams"
msgstr "outo varren koko, koeta lyhyempiä palkkeja"
-#: stem.cc:627
+#: stem.cc:592
#, c-format
msgid "flag `%s' not found"
msgstr "lippua `%s' ei löydetty"
-#: stem.cc:638
+#: stem.cc:603
#, c-format
msgid "flag stroke `%s' not found"
msgstr "lipun piirtoa `%s' ei löytynyt"
-#: system.cc:178
+#: system.cc:181
#, c-format
msgid "Element count %d."
msgstr "Elementtien määrä: %d."
-#: system.cc:270
+#: system.cc:268
#, c-format
msgid "Grob count %d"
msgstr "Graafisien objektien (grob) määrä: %d "
-#: text-spanner-engraver.cc:60
+#: system.cc:289
+msgid "Calculating line breaks..."
+msgstr "Lasketaan rivinvaihtoja..."
+
+#: text-spanner-engraver.cc:62
msgid "can't find start of text spanner"
msgstr "ei löydetty alkua tekstileikkeelle"
-#: text-spanner-engraver.cc:72
+#: text-spanner-engraver.cc:74
msgid "already have a text spanner"
msgstr "tekstileike löytyi jo"
-#: text-spanner-engraver.cc:132
+#: text-spanner-engraver.cc:134
msgid "unterminated text spanner"
msgstr "päättämätön tekstileike"
-#: tie-engraver.cc:257
+#. Not using ngettext's plural feature here, as this message is
+#. more of a programming error.
+#: tfm-reader.cc:107
+#, c-format
+msgid "TFM header of `%s' has only %u word (s)"
+msgstr "TFM-otsakkeessa `%s' on vain %u sana(a)"
+
+#: tfm-reader.cc:140
+#, c-format
+msgid "%s: TFM file has %u parameters, which is more than the %u I can handle"
+msgstr ""
+"%s: TFM-tiedostossa on %u parametria, mikä on enemmän kuin maksimimäärä %u"
+
+#: tfm.cc:72
+#, c-format
+msgid "can't find ascii character: %d"
+msgstr "ei löydetty ASCII-merkkiä: %d"
+
+#: tie-engraver.cc:181
msgid "lonely tie"
msgstr "yksinäinen sidos"
+#: time-scaled-music-iterator.cc:24
+msgid "no one to print a tuplet start bracket"
+msgstr "ketään ei löytynyt tulostamaan tupletin alkusulkua"
+
#.
#. Todo: should make typecheck?
#.
msgid "unknown translator: `%s'"
msgstr "tuntematon tulkitsija: `%s'"
-#: translator-group.cc:152
-#, c-format
-msgid "can't find: `%s'"
-msgstr "ei löytynyt `%s'"
-
-#: translator.cc:310
-#, c-format
-msgid "Two simultaneous %s events, junking this one"
-msgstr "Kaksi samanaikaista %s-tapahtumaa, hylätään tämä"
-
-#: translator.cc:311
-#, c-format
-msgid "Previous %s event here"
-msgstr "Edellinen %s-tapahtuma täällä"
-
-#: trill-spanner-engraver.cc:67
+#: trill-spanner-engraver.cc:71
msgid "can't find start of trill spanner"
msgstr "ei löydetty alkua trilliladokkeelle"
-#: trill-spanner-engraver.cc:79
+#: trill-spanner-engraver.cc:83
msgid "already have a trill spanner"
msgstr "trilliladoke löytyi jo"
-#: tuplet-engraver.cc:72
-msgid "invalid direction of tuplet-span-event"
-msgstr "tuntematon tuplettiväli-tapahtuman suunta"
+#: trill-spanner-engraver.cc:142
+msgid "unterminated trill spanner"
+msgstr "päättymätön trilliladoke"
-#: vaticana-ligature-engraver.cc:364
+#: vaticana-ligature-engraver.cc:347
#, c-format
msgid ""
"ignored prefix (es) `%s' of this head according to restrictions of the "
"sivuutetaan prefiksi (t) `%s' tälle nuottipäälle valitun ligatuurityylin "
"mukaisesti"
-#: vaticana-ligature-engraver.cc:601
+#: vaticana-ligature-engraver.cc:584
#, c-format
msgid "Vaticana_ligature_engraver: setting `spacing-increment = %f': ptr =%ul"
-msgstr "Vaticana_ligature_engraver: asetetaan `spacing-increment = %f': ptr=%ul"
+msgstr ""
+"Vaticana_ligature_engraver: asetetaan `spacing-increment = %f': ptr=%ul"
#: vaticana-ligature.cc:84
msgid "flexa-height undefined; assuming 0"
msgstr "Vaticana_ligature: nollayhdiste (delta_pitch == 0)"
#. fixme: be more verbose.
-#: volta-engraver.cc:143
+#: volta-engraver.cc:142
msgid "can't end volta spanner"
msgstr "ei löydetty loppua volta ladokkeelle"
-#: volta-engraver.cc:153
+#: volta-engraver.cc:152
msgid "already have a volta spanner, ending that one prematurely"
msgstr "löytyi ja volta-ladoke, lopetetaan se ennenaikaisesti"
-#: volta-engraver.cc:157
+#: volta-engraver.cc:156
msgid "also already have an ended spanner"
msgstr "myös tekstileike päätettiin jo"
-#: parser.yy:704 parser.yy:710
+#. no longer valid with dashes in \paper{} block.
+#: parser.yy:535
+msgid "identifier should have alphabetic characters only"
+msgstr "tunnisteessa saa olla vain aakkosellisia merkkejä"
+
+#: parser.yy:705
msgid "\\paper cannot be used in \\score, use \\layout instead"
msgstr "\\paper ei voi olla käytössä \\score:ssa, käytä \\layout sen sijaan"
-#: parser.yy:728 parser.yy:734
+#: parser.yy:729
msgid "need \\paper for paper block"
msgstr "tarvitaan \\paper paperiryhmälle"
-#: parser.yy:1174 parser.yy:1204
+#: parser.yy:879
+msgid "more alternatives than repeats"
+msgstr "enemmän vaihtoehtoja kuin kertauksia"
+
+#: parser.yy:916
+#, c-format
+msgid "expect 2 elements for Chord tremolo, found %d"
+msgstr "odotetaan 2 elementtiä Chord tremololle, löytyi %d"
+
+#: parser.yy:1316
msgid "Grob name should be alphanumeric"
msgstr "Graafiseen objectiin täytyy olla kirjain tai numero"
-#: parser.yy:1481 parser.yy:1497
+#: parser.yy:1681
msgid "second argument must be pitch list"
msgstr "toisen argumentin on oltava äänenkorkeuslista"
-#: parser.yy:1508 parser.yy:1513 parser.yy:1988 parser.yy:1524 parser.yy:1529
-#: parser.yy:2004
+#: parser.yy:1724 parser.yy:1729 parser.yy:2235
msgid "have to be in Lyric mode for lyrics"
msgstr "täytyy olla Lyrics -moodissa lyriikkaa varten"
-#: parser.yy:1612 parser.yy:1628
+#: parser.yy:1822
msgid "expecting string as script definition"
msgstr "oletetaan merkkijonon olevan skriptimäärittely"
-#: parser.yy:1770 parser.yy:1820 parser.yy:1786 parser.yy:1836
+#: parser.yy:1981 parser.yy:2031
#, c-format
msgid "not a duration: %d"
msgstr "ei ole kesto: %d"
-#: parser.yy:1940 parser.yy:1956
+#: parser.yy:2154
msgid "have to be in Note mode for notes"
msgstr "täytyy olla Note -moodissa nuotteja varten"
-#: parser.yy:2004 parser.yy:2020
+#: parser.yy:2248
msgid "have to be in Chord mode for chords"
msgstr "täytyy olla Chord -moodissa sointuja varten"
-#: lexer.ll:177 lexer.ll:159
+#: parser.yy:2730
+msgid "music head function must return Music object"
+msgstr "päämusiikkifuntion täytyy palauttaa Music objecti"
+
+#: lexer.ll:158
msgid "stray UTF-8 BOM encountered"
msgstr "satunnainen UTF-8 BOM (osaluettelo) havaittu"
-#: lexer.ll:181 lexer.ll:163
+#: lexer.ll:162
msgid "Skipping UTF-8 BOM"
msgstr "Sivuutetaan UTF-8 BOM (osaluettelo)"
-#: lexer.ll:236 lexer.ll:218
+#: lexer.ll:206
#, c-format
msgid "Renaming input to: `%s'"
msgstr "Avataan syöte: `%s'"
-#: lexer.ll:254 lexer.ll:236
+#: lexer.ll:214
msgid "quoted string expected after \\version"
msgstr "lainausmerkittyä merkkijonoa ei löytynyt kohteen \\version jälkeen"
-#: lexer.ll:258 lexer.ll:240
+#: lexer.ll:218
msgid "quoted string expected after \\sourcefilename"
msgstr "odotettiin lainausmerkittyä merkkijonoa \\sourcefilename:n jälkeen"
-#: lexer.ll:262 lexer.ll:244
-msgid "integer expected after \\sourcefileline"
-msgstr "odotettiin kokonaislukua \\sourcefilename:n jälkeen"
-
-#: lexer.ll:275 lexer.ll:257
+#: lexer.ll:231
msgid "EOF found inside a comment"
msgstr "EOF löytyi kommentin sisältä"
-#: lexer.ll:290 lexer.ll:272
+#: lexer.ll:246
msgid "\\maininput not allowed outside init files"
msgstr "\\maininput ei ole sallittu init-alustustiedoston ulkopuolella"
-#: lexer.ll:314 lexer.ll:296
+#: lexer.ll:270
#, c-format
msgid "wrong or undefined identifier: `%s'"
msgstr "väärä tai määrittämätön tunniste: `%s'"
#. backup rule
-#: lexer.ll:323 lexer.ll:305
+#: lexer.ll:279
msgid "end quote missing"
msgstr "jälkimmäinen lainaismerkki puuttuu"
-#: lexer.ll:468 lexer.ll:450
+#: lexer.ll:441
msgid "Brace found at end of lyric. Did you forget a space?"
msgstr "Sulkumerkki löytyi lyriikan lopussa. Unohditko välilyönnin?"
-#: lexer.ll:561 lexer.ll:543
+#: lexer.ll:540
msgid "Brace found at end of markup. Did you forget a space?"
msgstr "Sulkumerkki löytyi lyriikan lopussa. Unohditko välilyönnin?"
-#: lexer.ll:661 lexer.ll:643
+#: lexer.ll:640
#, c-format
msgid "invalid character: `%c'"
msgstr "epäkelpo merkki: `%c'"
-#: lexer.ll:776 lexer.ll:731
+#: lexer.ll:727
#, c-format
msgid "unknown escaped string: `\\%s'"
msgstr "tuntematon koodinvaihtomerkillinen merkkijono: `\\\\%s'"
-#: lexer.ll:882 lexer.ll:828
+#: lexer.ll:824
#, c-format
msgid "Incorrect lilypond version: %s (%s, %s)"
msgstr "Epäkelpo lilypond versio: %s (%s, %s)"
-#: lexer.ll:883 lexer.ll:829
+#: lexer.ll:825
msgid "Consider updating the input with the convert-ly script"
msgstr "Harkitse syötteen päivittämistä convert-ly scriptillä"
-#: lexer.ll:931
+#. TODO: print location
+#: lexer.ll:945
msgid "can't find signature for music function"
msgstr "ei löytynyt aikamerkintää musiikkifunktiolle"
-#: backend-library.scm:19 lily.scm:479 ps-to-png.scm:88
+#: backend-library.scm:19 lily.scm:439 ps-to-png.scm:88
#, lisp-format
msgid "Invoking `~a'..."
msgstr "Kutsutaan `~a'..."
msgid "`~a' failed (~a)"
msgstr "`~a' epäonnistui (~a)"
-#: backend-library.scm:95 framework-tex.scm:343 framework-tex.scm:368
+#: backend-library.scm:84 framework-tex.scm:339 framework-tex.scm:364
#, lisp-format
msgid "Converting to `~a'..."
msgstr "Muunnetaan kohteeksi `~a'..."
-#: backend-library.scm:110
+#: backend-library.scm:100
#, lisp-format
msgid "Converting to ~a..."
msgstr "Muunnetaan kohteeksi `~a'..."
-#: backend-library.scm:156
+#: backend-library.scm:145
#, lisp-format
msgid "Writing header field `~a' to `~a'..."
msgstr "Kirjoitetaan otsaketietue `~a' kohteeseen `~a'..."
-#: define-context-properties.scm:20 define-grob-properties.scm:10
+#: define-context-properties.scm:13 define-grob-properties.scm:10
#: define-music-properties.scm:10
#, lisp-format
msgid "symbol ~S redefined"
msgstr "symbol ~S määriteltiin uudelleen"
-#: define-event-classes.scm:116
-#, lisp-format
-msgid "event class ~A seems to be unused"
-msgstr "tapahtumaluokka ~A näkyy olevan käyttämätön"
-
-#. should be programming-error
-#: define-event-classes.scm:122
-#, lisp-format
-msgid "translator listens to nonexisting event class ~A"
-msgstr "kääntäjä kuuntelee olematonta tapahtumaluokkaa ~A"
-
-#: define-markup-commands.scm:256
+#: define-markup-commands.scm:251
msgid "no systems found in \\score markup, does it have a \\layout block?"
-msgstr "systeemejä ei löytynyt \\score merkinnässä, onko siinä \\layout blokkia?"
+msgstr ""
+"systeemejä ei löytynyt \\score merkinnässä, onko siinä \\layout blokkia?"
-#: define-markup-commands.scm:1249
+#: define-markup-commands.scm:1205
#, lisp-format
msgid "not a valid duration string: ~a"
msgstr "ei ole sallittu keston merkkijono: ~a"
-#: define-music-types.scm:734
+#: define-music-types.scm:738
#, lisp-format
msgid "symbol expected: ~S"
msgstr "odotettiin symboli: ~S"
-#: define-music-types.scm:737
+#: define-music-types.scm:741
#, lisp-format
msgid "can't find music object: ~S"
msgstr "ei löytynyt musiikkiobjektia: ~S"
-#: define-music-types.scm:757
+#: define-music-types.scm:761
#, lisp-format
msgid "unknown repeat type `~S'"
msgstr "tuntematon toistotyyppi `~S'"
-#: define-music-types.scm:758
+#: define-music-types.scm:762
msgid "See music-types.scm for supported repeats"
msgstr "Katso tiedostosta music-types.scm tuetut toistotyypit"
msgid "can't find description for property ~S (~S)"
msgstr "ei löytynyt kuvausta ominaisuudelle ~S (~S)"
-#: framework-eps.scm:77 framework-eps.scm:78
+#: framework-eps.scm:71 framework-eps.scm:72
#, lisp-format
msgid "Writing ~a..."
msgstr "Kirjoitetaan ~a..."
-#: framework-ps.scm:278
+#: framework-ps.scm:275
#, lisp-format
msgid "can't embed ~S=~S"
msgstr "ei voitu upottaa ~S=~S"
-#: framework-ps.scm:331
+#: framework-ps.scm:326
#, lisp-format
msgid "can't extract file matching ~a from ~a"
msgstr "Ei voitu poimia sopivaa tiedoa ~a:sta ~a:han"
-#: framework-ps.scm:348
+#: framework-ps.scm:343
#, lisp-format
msgid "don't know how to embed ~S=~S"
msgstr "ei tiedetä kuinka upottaa ~S=~S"
-#: framework-ps.scm:379
+#: framework-ps.scm:373
#, lisp-format
msgid "don't know how to embed font ~s ~s ~s"
msgstr "ei tiedetä kuinka sijoittaa fontti ~s ~s ~s"
-#: framework-ps.scm:610
+#: framework-ps.scm:579
#, lisp-format
msgid "can't convert <stdout> to ~S"
msgstr "ei voida konvertoida <stdout> ~S:ksi"
-#: framework-ps.scm:629 framework-ps.scm:632
+#: framework-ps.scm:596 framework-ps.scm:599
#, lisp-format
msgid "can't generate ~S using the postscript back-end"
msgstr "ei voida generoida ~S käyttäen postscript päänä"
-#: framework-ps.scm:639
+#: framework-ps.scm:606
msgid ""
"nThe PostScript backend does not support the 'classic'\n"
"framework. Use the EPS backend instead,\n"
"\n"
"tai poista lilypond-book -ominaiset asetukset syötteestä.\n"
-#: framework-tex.scm:360
+#: framework-tex.scm:356
#, lisp-format
msgid "TeX file name must not contain whitespace: `~a'"
msgstr "TeX -tiedostoniemessä ei saa olla välilyöntejä: `~a'"
msgid "Error in beam quanting. Expected ~S 0, found ~S."
msgstr "Virhe palkin laskennassa. Odotettiin ~S 0, löytyi ~S."
-#: layout-page-layout.scm:353
+#: layout-page-layout.scm:439
msgid "Calculating page breaks..."
msgstr "Lasketaan sivunvaihtoja..."
-#: lily-library.scm:510
+#: lily-library.scm:458
#, lisp-format
msgid "unknown unit: ~S"
msgstr "tuntematon yksikkö: ~S"
-#: lily-library.scm:543
+#: lily-library.scm:491
#, lisp-format
-msgid "no \\version statement found, please add~afor future compatibility"
-msgstr ""
-"ei löytynyt \\version-määrittelyä, ole hyvä ja lisää~a yhteensopivuuden "
-"varalle"
+msgid "no \\version statement found, add~afor future compatibility"
+msgstr "ei \\version määrittelyä löytynyt, lisää~ayhteensopivuuden varalle"
-#: lily-library.scm:550
+#: lily-library.scm:498
msgid "old relative compatibility not used"
msgstr "vanhaa relative -yhteensopivuutta ei käytetty"
-#: lily.scm:131
-#, lisp-format
-msgid "Can't find ~A"
-msgstr "Ei löydetty ~A"
-
-#: lily.scm:196
+#: lily.scm:172
#, lisp-format
msgid "wrong type for argument ~a. Expecting ~a, found ~s"
msgstr "väärä tyyppi argumentille ~a. Odotettiin ~a, löytyi ~s"
-#: lily.scm:409 lily.scm:469
+#: lily.scm:377 lily.scm:429
#, lisp-format
msgid "failed files: ~S"
msgstr "epäonniset tiedostot: ~S"
-#: lily.scm:459
+#: lily.scm:419
#, lisp-format
msgid "Redirecting output to ~a..."
msgstr "Ohjataan tulosteet paikkaan ~a..."
-#: ly-syntax-constructors.scm:40
-msgid "Music head function must return Music object"
-msgstr "Music-pääfunktion täytyy palauttaa Music-objekti"
-
-#: ly-syntax-constructors.scm:132
-#, lisp-format
-msgid "Invalid property operation ~a"
-msgstr "Tuntematon ominaisuustoiminta ~a"
-
#: markup.scm:88
#, lisp-format
msgid "Wrong number of arguments. Expect: ~A, found ~A: ~S"
msgid "Invalid argument in position ~A. Expect: ~A, found: ~S."
msgstr "Väärä argumentti paikassa ~A. Odotettiin: ~A, löytyi: ~S."
-#: music-functions.scm:210
-msgid "More alternatives than repeats. Junking excess alternatives"
-msgstr "Enemmän vaihtoehtoja kuin kertauksia. Hylätään ylimääräiset vaihtoehdot"
-
-#: music-functions.scm:229
-#, lisp-format
-msgid "expecting 2 elements for chord tremolo, found ~a"
-msgstr "odotettiin 2 elementtiä sointutremololle, löytyi ~a"
-
-#: music-functions.scm:535
+#: music-functions.scm:533
#, lisp-format
msgid "music expected: ~S"
msgstr "oletettiin musiikkia: ~S"
#. FIXME: uncomprehensable message
-#: music-functions.scm:586
+#: music-functions.scm:584
#, lisp-format
msgid "Bar check failed. Expect to be at ~a, instead at ~a"
msgstr "Tahtiviivan tarkistus epäonnistui. Odotettiin: ~a, löytyi: ~a"
-#: music-functions.scm:745
+#: music-functions.scm:739
#, lisp-format
msgid "can't find quoted music `~S'"
msgstr "ei löytynyt lainusmerkittyä musiikkai `~S'"
-#: music-functions.scm:953
+#: music-functions.scm:947
#, lisp-format
msgid "unknown accidental style: ~S"
msgstr "tuntematan kortusmerkkityyli: ~S"
-#: output-ps.scm:315
+#: output-ps.scm:282
msgid "utf-8-string encountered in PS backend"
msgstr "utf8-merkkijono havaittu PS päässä"
-#: output-svg.scm:42
+#: output-svg.scm:41
#, lisp-format
msgid "undefined: ~S"
msgstr "määrittämätön: ~S"
-#: output-svg.scm:132
+#: output-svg.scm:121
#, lisp-format
msgid "can't decypher Pango description: ~a"
msgstr "decypher ei onnistunut Pango kuvauksessa: ~a"
msgid "This is not a \\layout {} object, ~S"
msgstr "Tämä ei ole \\layout {} objekti, ~S"
-#: paper.scm:126
-#, lisp-format
-msgid "Unknown papersize: ~a"
-msgstr "Tuntematon paperikoko: ~a"
-
#. TODO: should raise (generic) exception with throw, and catch
#. that in parse-scm.cc
-#: paper.scm:141
+#: paper.scm:142
msgid "Must use #(set-paper-size .. ) within \\paper { ... }"
msgstr "Täytyy käyttää #(set-paper-size .. ) \\paper { ... } :n sisällä"
-#: parser-clef.scm:126
+#: parser-clef.scm:124
#, lisp-format
msgid "unknown clef type `~a'"
msgstr "tuntematon avaimen tyyppi: `~a'"
-#: parser-clef.scm:127
+#: parser-clef.scm:125
msgid "see scm/clef.scm for supported clefs"
msgstr "katso tiedostosta scm/clef.scm tuetut avaimet"
msgid "assertion failed"
msgstr "ajaminen epäonnistui"
+#~ msgid "Usage: %s [OPTIONS]... FILE"
+#~ msgstr "Käyttö: %s [OPTIOT]... TIEDOSTO"
+
+#~ msgid "Report bugs to %s."
+#~ msgstr "Raportoi virheet osoitteeseen %s."
+
+#~ msgid "Binary %s has version %s, looking for version %s"
+#~ msgstr "Binääritiedosto %s on versiota %s, etsitään versiota %s"
+
+#~ msgid "Opening pipe `%s'"
+#~ msgstr "Avataan putki `%s'"
+
+#~ msgid "`%s' failed (%s)"
+#~ msgstr "`%s' epäonnistui (%s)"
+
+#~ msgid "(ignored)"
+#~ msgstr "(sivuutetaan)"
+
+#~ msgid "Cleaning %s..."
+#~ msgstr "Siivotaan pois %s..."
+
+#~ msgid "%s exited with status: %d"
+#~ msgstr "%s lopetettiin tilassa %d"
+
+#~ msgid "print program version\""
+#~ msgstr "tulosta ohjelman versionumero\""
+
+#~ msgid "getopt says: `%s'"
+#~ msgstr "getopt sanoo: `%s'"
+
+#~ msgid "FMT"
+#~ msgstr "FMT"
+
+#~ msgid ""
+#~ "do not alter the number of newline characters in output\n"
+#~ "\t .tex files. Useful when the LaTeX package srcltx is used"
+#~ msgstr ""
+#~ "älä muuta uusi rivi -merkkien määrää tulostuksessa\n"
+#~ "\t .tex tiedostot. Käytännöllinen kun LaTeX paketti srcltx on käytössä"
+
+#~ msgid "print version information"
+#~ msgstr "tulosta versioinformaatio"
+
+#~ msgid "Report bugs via %s."
+#~ msgstr "Raportoi virheet osoitteeseen %s."
+
+#~ msgid "command exited with value %d"
+#~ msgstr "komento lopetettiin tilassa %d"
+
+#~ msgid "Convert mup to LilyPond source."
+#~ msgstr "Muunna mup LilyPond-muotoon."
+
+#~ msgid "debug"
+#~ msgstr "testaa"
+
+#~ msgid "define macro NAME [optional expansion EXP]"
+#~ msgstr "määritä makro NIMI [vaihtoehtoinen laajennus EXP]"
+
+#~ msgid "only pre-process"
+#~ msgstr "vain esiprosessointi"
+
+#~ msgid "no such context: %s"
+#~ msgstr "kontekstia ei ole: %s"
+
+#~ msgid "Processing `%s'..."
+#~ msgstr "Prosessoidaan `%s'..."
+
+#~ msgid "%s=%s\n"
+#~ msgstr "%s=%s\n"
+
+#~ msgid "parsing AFM file: `%s'"
+#~ msgstr "jäsennetään AFM-tiedostoa: `%s'"
+
+#~ msgid "checksum mismatch for font file: `%s'"
+#~ msgstr "virhesumma ei täsmää fonttitiedostolle: `%s'"
+
+#~ msgid "does not match: `%s'"
+#~ msgstr "ei täsmää: `%s'"
+
+#~ msgid "Rebuild all .afm files, and remove all .pk and .tfm files."
+#~ msgstr ""
+#~ "Uudista kaikki .afm -tiedosto, ja poista kaikki .pk ja .tfm -tiedostot."
+
+#~ msgid "Rerun with -V to show font paths."
+#~ msgstr "Aja uudelleen lisäten -V nähdäksesi fonttipolut."
+
+#~ msgid "A script for removing font-files is delivered with the source-code:"
+#~ msgstr ""
+#~ "Skripti fonttitiedostojen poistamista varten toimitetaan lähdekoodin "
+#~ "mukana:"
+
+#~ msgid "initializing FontConfig failed"
+#~ msgstr "FontConfig:in alustaminen epäonnistui"
+
+#~ msgid "no such file: %s"
+#~ msgstr "tiedostoa ei löydy: `%s'"
+
+#~ msgid "can't find bounding box of `~a'"
+#~ msgstr "ei löytynyt `~a':n rajauskehystä (bounding box)"
+
+#~ msgid "can't dlopen: %s: %s"
+#~ msgstr "tiedostoa ei voitu avata: %s: %s"
+
+#~ msgid "install package: %s or %s"
+#~ msgstr "asenna paketti: %s tai %s"
+
+#~ msgid "no such symbol: %s: %s"
+#~ msgstr "ei löytynyt symbolia: %s: %s"
+
+#~ msgid "error opening kpathsea library"
+#~ msgstr "virhe avatessa kpathsea kirjastoa"
+
+#~ msgid "aborting"
+#~ msgstr "keskeytetään"
+
+#~ msgid "run in safe mode"
+#~ msgstr "aja turvamoodissa"
+
+#~ msgid "tag must be symbol or list of symbols"
+#~ msgstr "merkinnän on oltava symboli tai lista symboleita"
+
+#~ msgid "unknown bar glyph: `~S'"
+#~ msgstr "tuntematon palkkityyli: `~S'"
# translation of fr.po to
-# Messages français pour LilyPond.
+# Messages français pour lilypond.
# Copyright © 2004 Free Software Foundation, Inc.
# Michel Robitaille <robitail@IRO.UMontreal.CA>, traducteur depuis/since 1996.
# revisité par Jean-Charles Malahieude <lilyfan@wanadoo.fr>,
-# et par John Mandereau <john.mandereau@free.fr>, 2006.
+# et par John Mandereau <john.mandereau@free.fr>
+# John Mandereau <john.mandereau@free.fr>, 2005.
msgid ""
msgstr ""
"Project-Id-Version: fr\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2006-03-20 12:53+0100\n"
-"PO-Revision-Date: 2006-06-20 10:23+0200\n"
-"Last-Translator: Jean-Charles Malahieude <lolyfan@wanadoo.fr>\n"
+"PO-Revision-Date: 2005-09-01 15:35+0200\n"
+"Last-Translator: John Mandereau <john.mandereau@free.fr>\n"
"Language-Team: <fr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: KBabel 1.10.2\n"
#: convertrules.py:9
#, python-format
msgid "Not smart enough to convert %s"
-msgstr "Pas assez intelligent pour convertir %s"
+msgstr "Pas assez d'intelligence pour convertir %s"
#: convertrules.py:10
msgid "Please refer to the manual for details, and update manually."
msgstr ""
-"SVP référez-vous au manuel pour plus de détails, \n"
-"et faites la mise à jour manuellement."
+"SVP référez-vous au manuel pour plus de détails, et faites la mise à jour "
+"manuellement."
#: convertrules.py:11
#, python-format
#: convertrules.py:2398
msgid "Try the texstrings backend"
-msgstr "Essayer le moteur texstrings (texstrings backend)"
+msgstr "Essayer le moteur \"texstrings\" (texstrings backend)"
#: convertrules.py:2401
#, python-format
#: lilylib.py:165
#, python-format
msgid "Usage: %s\n"
-msgstr "Utilisation : %s\n"
+msgstr ""
#: abc2ly.py:1357
msgid ""
"This program converts ABC music files (see\n"
"http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) to LilyPond input."
msgstr ""
-"Ce programme convertit les fichiers musicaux ABC (voir\n"
-"http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) vers le format LilyPond."
#: abc2ly.py:1360
+#, fuzzy
msgid "set output filename to FILE"
-msgstr "produire la sortie dans FICHIER"
+msgstr "produire la sortie dans le FICHIER"
#: abc2ly.py:1362
msgid "be strict about succes"
-msgstr "être strict sur la réussite"
+msgstr ""
#: abc2ly.py:1364
msgid "preserve ABC's notion of beams"
-msgstr "préserver la notion de lien de croches d'ABC"
+msgstr ""
#: convert-ly.py:49
+#, fuzzy
msgid ""
"Update LilyPond input to newer version. By default, update from the\n"
"version taken from the \\version command, to the current LilyPond version.\n"
" convert-ly -e old.ly\n"
" convert-ly --from=2.3.28 --to 2.5.21 foobar.ly\n"
msgstr ""
-"Mettre à jour le fichier source vers une version plus récente. Par défaut,\n"
-"de la version indiquée par la commande \\version vers la version courante\n"
-"de LilyPond.\n"
-"\n"
-"Exemples :\n"
-"\n"
-" convert-ly -e ancien.ly\\n\n"
-" convert-ly --from=2.3.28 --to=2.5.21 toto.ly\n"
+"Mettre à jour le fichier source vers une version plus récente. Par défaut, "
+"de la \n"
+"version indiquée par la commande \\version vers la version courante de "
+"LilyPond."
#: convert-ly.py:67 lilypond-book.py:115 warn.cc:48 input.cc:81
#, c-format, python-format
#: convert-ly.py:98 convert-ly.py:118
msgid "VERSION"
-msgstr "VERSION"
+msgstr ""
#: convert-ly.py:100
msgid "start from VERSION [default: \\version found in file]"
-msgstr "partir de la VERSION [par défaut : \\version trouvée dans le fichier]"
+msgstr ""
#: convert-ly.py:103
msgid "edit in place"
-msgstr "éditer le fichier d'origine"
+msgstr ""
#: convert-ly.py:106
msgid "do not add \\version command if missing"
-msgstr "ne pas ajouter la commande \\version si elle est absente"
+msgstr ""
#: convert-ly.py:112
msgid "print rules [default: --from=0, --to=@TOPLEVEL_VERSION@]"
-msgstr "afficher les règles [par défaut : --from=0, --to=@TOPLEVEL_VERSION@]"
+msgstr ""
#: convert-ly.py:117
msgid "convert to VERSION [default: @TOPLEVEL_VERSION@]"
-msgstr "convertir jusqu'à la VERSION [par défaut : @TOPLEVEL_VERSION@]"
+msgstr ""
#: convert-ly.py:164
msgid "Applying conversion: "
-msgstr "Conversion en cours : "
+msgstr "Conversion appliquée : "
#: convert-ly.py:176
+#, fuzzy
msgid "error while converting"
-msgstr "erreur lors de la conversion"
+msgstr "%s : erreur lors de la conversion"
#: convert-ly.py:178 score-engraver.cc:73
msgid "Aborting"
msgstr "impossible d'ouvrir le fichier : « %s »"
#: convert-ly.py:296
-#, python-format
+#, fuzzy, python-format
msgid "can't determine version for `%s'. Skipping"
-msgstr "impossible de déterminer la version pour « %s ». Au suivant !"
+msgstr "%s : impossible de déterminer la version pour « %s »"
#: etf2ly.py:1208
msgid ""
"Finale product. This program will convert a subset of ETF to a\n"
"ready-to-use lilypond file."
msgstr ""
-"Enigma Transport Format est utilisé par Finale, de Coda Music Technology.\n"
-"Ce programme convertit partiellement un fichier ETF en un fichier LilyPond exploitable."
#: etf2ly.py:1211 midi2ly.py:901
msgid "write output to FILE"
msgstr "FICHIER"
#: etf2ly.py:1214 midi2ly.py:915
+#, fuzzy
msgid "show warranty"
-msgstr "afficher la notice de garantie"
+msgstr "afficher les notices de garantie et du droit d'auteur"
#: lilypond-book.py:88
+#, fuzzy
msgid ""
"Process LilyPond snippets in hybrid HTML, LaTeX, or texinfo document.\n"
"\n"
" lilypond-book --filter=\"convert-ly --no-version --from=2.0.0 -\" BOOK\n"
" lilypond-book --process='lilypond -I include' BOOK\n"
msgstr ""
-"Traiter des extraits LilyPond dans un document hybride HTML, LaTeX ou Texinfo.\n"
+"Traiter les extraits de LilyPond dans un document hybride HTML, LaTeX ou "
+"TexInfo.\n"
"Exemples d'utilisation :\n"
"\n"
" lilypond-book --filter=\"tr '[a-z]' '[A-Z]'\" LIVRE\n"
#: lilypond-book.py:104
#, python-format
msgid "Exiting (%d)..."
-msgstr "Fin d'exécution (%d)..."
+msgstr "Fin d'exécution (%d)... "
#: lilypond-book.py:136
#, python-format
msgid "Copyright (c) %s by"
-msgstr "Copyright (c) %s détenu par"
+msgstr "Copyright (c) %s écrit par"
#: lilypond-book.py:147
msgid "FILTER"
msgstr "passer les extraits à travers le FILTRE [convert-ly -n -]"
#: lilypond-book.py:152
+#, fuzzy
msgid "use output format FORMAT (texi [default], texi-html, latex, html)"
-msgstr "utiliser le format de sortie FMT (texi (par défaut), texi-html, latex, html)"
+msgstr ""
+"utiliser le format de sortie FMT (texi (par défaut), texi-html,\n"
+"\t\tlatex, html)"
#: lilypond-book.py:154
msgid "add DIR to include path"
-msgstr "ajouter le RÉPERTOIRE au chemin de recherche des inclusions"
+msgstr "ajouter le RÉPERTOIRE à inclure au chemin de recherche"
#: lilypond-book.py:159
msgid "write output to DIR"
msgstr "traiter les fichiers_ly en utilisant COMMANDE FICHIER..."
#: lilypond-book.py:168
+#, fuzzy
msgid ""
"extract all PostScript fonts into INPUT.psfonts for LaTeXmust use this with "
"dvips -h INPUT.psfonts"
msgstr ""
-"extraire toutes les polices PostScript dans INPUT.psfonts\n"
-"pour LaTex. Ceci devra être accompagné de dvips -h INPUT.psfonts"
+"extraire toutes les polices PostScript dans le FICHIER\n"
+"pour LaTex qui devra les utiliser avec dvips -h FICHIER"
#: lilypond-book.py:171 midi2ly.py:912 main.cc:182
msgid "be verbose"
-msgstr "passer en mode verbeux"
+msgstr "passer en mode bavard"
#: lilypond-book.py:177 main.cc:183
msgid "show warranty and copyright"
-msgstr "afficher les notices de garantie et de droit d'auteur"
+msgstr "afficher les notices de garantie et du droit d'auteur"
#: lilypond-book.py:734
#, python-format
#: lilypond-book.py:1595
msgid "Output would overwrite input file; use --output."
-msgstr "La sortie écraserait le fichier d'entrée ; utiliser --output."
+msgstr "La sortie écraserait le fichier d'entrée ; utilisez --output"
#: lilypond-book.py:1599
#, python-format
msgid "Reading %s..."
-msgstr "Lecture de %s..."
+msgstr "Lecture en cours de %s..."
#: lilypond-book.py:1618
msgid "Dissecting..."
#: lilypond-book.py:1634
#, python-format
msgid "Compiling %s..."
-msgstr "Compilation de %s..."
+msgstr "Compilation en cours de %s..."
#: lilypond-book.py:1643
#, python-format
msgstr "Écriture des polices dans %s..."
#: lilypond-book.py:1729
+#, fuzzy
msgid "option --psfonts not used"
-msgstr "option --psfonts inutilisée"
+msgstr "option --psfonts=FICHIER inutilisée"
#: lilypond-book.py:1730
msgid "processing with dvips will have no fonts"
#: midi2ly.py:873
#, python-format
msgid "%s output to `%s'..."
-msgstr "%s reproduit dans « %s »..."
+msgstr "%s produites dans « %s »..."
#: midi2ly.py:887
msgid "Convert MIDI to LilyPond source."
-msgstr "Convertir du format MIDI au format source LilyPond."
+msgstr "Convertir du format MIDI au format source LilyPond"
#: midi2ly.py:891
msgid "print absolute pitches"
#: midi2ly.py:897
msgid "print explicit durations"
-msgstr "écrire les durées explicites"
+msgstr "afficher les durées explicites"
#: midi2ly.py:898
msgid "set key: ALT=+sharps|-flats; MINOR=1"
#: midi2ly.py:910
msgid "allow tuplet durations DUR*NUM/DEN"
-msgstr "permettre des n-olets de durée DUR*NUM/DEN"
+msgstr "permettre des n-olets de durées DUR*NUM/DEN"
#: midi2ly.py:918
msgid "treat every text as a lyric"
msgstr "traiter chaque texte comme des paroles"
#: midi2ly.py:921
+#, fuzzy
msgid "example"
-msgstr "Exemple"
+msgstr "Exemples"
#: midi2ly.py:942
msgid "no files specified on command line."
-msgstr "aucun fichier spécifié en ligne de commande."
+msgstr "aucun fichier spécifié sur la ligne de commande."
#: getopt-long.cc:141
#, c-format
#: warn.cc:69
msgid "continuing, cross fingers"
-msgstr "poursuite ; croisons les doigts !"
+msgstr "poursuite ; croisons les doigts"
#: accidental-engraver.cc:238
#, c-format
msgid "accidental typesetting list must begin with context-name: %s"
msgstr ""
-"la saisie d'une liste d'altérations accidentelles doit débuter \n"
-"par un nom de contexte : %s"
+"la saisie d'une liste d'altérations accidentelles doit débuter par un nom de "
+"contexte : %s"
#: accidental-engraver.cc:266
#, c-format
msgid "ignoring unknown accidental: %s"
-msgstr "altération accidentelle inconnue, donc ignorée : %s"
+msgstr "altération accidentelle inconnue ignorée : %s"
#: accidental-engraver.cc:282
#, c-format
msgid "pair or context-name expected for accidental rule, found %s"
msgstr ""
-"paire ou nom de contexte attendu pour la règle d'altération accidentelle,\n"
-" %s trouvé"
+"paire ou nom de contexte attendu pour la règle d'altération accidentelle, %s "
+"trouvé"
#: accidental.cc:239 key-signature-interface.cc:124
#, c-format
msgid "accidental `%s' not found"
-msgstr "altération accidentelle « %s » non trouvée"
+msgstr "altération accidentelle `%s' non repérée"
#: align-interface.cc:160
msgid ""
"vertical alignment called before line-breaking.\n"
"Only do cross-staff spanners with PianoStaff."
msgstr ""
-"alignement vertical demandé avant un saut de ligne.\n"
-"N'utilisez les lignes inter-portées (cross-staff spanners) que dans une double portée (PianoStaff)."
#: all-font-metrics.cc:213
#, c-format
#: all-font-metrics.cc:224
#, c-format
msgid "can't find default font: `%s'"
-msgstr "impossible de trouver la police par défaut : « %s »"
+msgstr "impossible de repérer la police par défaut : « %s »"
#: all-font-metrics.cc:225 includable-lexer.cc:62 lily-parser-scheme.cc:97
#, c-format
#: auto-change-iterator.cc:62 change-iterator.cc:61
#, c-format
msgid "can't change, already in translator: %s"
-msgstr "impossible de faire un changement, c'est déjà dans le traducteur : %s"
+msgstr "impossible de faire un changement, il est déjà dans le traducteur : %s"
#: axis-group-engraver.cc:82
msgid "Axis_group_engraver: vertical group already has a parent"
msgstr "le lien a débuté ici"
#: beam-quanting.cc:306
+#, fuzzy
msgid "no feasible beam position"
-msgstr "nulle part où positionner le lien"
+msgstr "aucun saut de ligne faisable repéré"
#: beam.cc:126
msgid "removing beam with less than two stems"
#: beam.cc:981
msgid "no viable initial configuration found: may not find good beam slope"
-msgstr "pas de configuration initiale viable repérée : la pente du lien pourrait \n"
-"être mauvaise"
+msgstr ""
+"pas de configuration initiale viable repérée : possibilité de mauvaise pente "
+"de lien"
#: break-align-interface.cc:194
#, c-format
msgid "No spacing entry from %s to `%s'"
-msgstr "Pas d'entrée d'espacement entre %s et « %s »"
+msgstr "Pas d'entrée d'espacement de %s jusqu'à « %s »"
#: change-iterator.cc:23
#, c-format
#: change-iterator.cc:91
#, c-format
msgid "not changing to same context type: %s"
-msgstr "changement vers un autre type de contexte : %s"
+msgstr "pas de changement vers le même type de contexte : %s"
#. FIXME: uncomprehensable message
#: change-iterator.cc:95
#: chord-tremolo-iterator.cc:60
msgid "no one to print a tremolos"
-msgstr "nulle part où positionner un trémolo"
+msgstr "rien pour l'impression de trémolo"
#: clef.cc:55
#, c-format
#: cluster.cc:135
msgid "junking empty cluster"
-msgstr "rejet d'un cluster vide"
+msgstr "mise au rebut d'un cluster vide"
#: coherent-ligature-engraver.cc:86
#, c-format
#: coherent-ligature-engraver.cc:136
#, c-format
msgid "Coherent_ligature_engraver: setting `spacing-increment=0.01': ptr=%ul"
-msgstr "Coherent_ligature_engraver : initialise `spacing-increment=0.01': ptr=%ul"
+msgstr ""
+"Coherent_ligature_engraver : initialise `spacing-increment=0.01': ptr=%ul"
#: constrained-breaking.cc:124
msgid "no system number set in constrained-breaking"
-msgstr "nombre de systèmes non défini pour les contraintes de saut de ligne"
+msgstr ""
#. if we get to here, just put everything on one line
#: constrained-breaking.cc:225 constrained-breaking.cc:241
+#, fuzzy
msgid "couldn't find line breaking that satisfies constraints"
-msgstr "impossible de trouver un saut de ligne qui satisfasse aux contraintes"
+msgstr "impossible de trouver un saut de ligne qui satisfasse les contraintes"
#: context-def.cc:123
#, c-format
#: custos.cc:77
#, c-format
msgid "custos `%s' not found"
-msgstr "custode « %s » non trouvée"
+msgstr "custos « %s » non trouvé"
#: dynamic-engraver.cc:181 span-dynamic-performer.cc:84
msgid "can't find start of (de)crescendo"
-msgstr "impossible de trouver le début du (de)crescendo"
+msgstr "impossible de repérer le début du (de)crescendo"
#: dynamic-engraver.cc:190
msgid "already have a decrescendo"
#: folded-repeat-iterator.cc:63
msgid "no one to print a repeat brace"
-msgstr "nulle part où positionner une accolade de reprise"
+msgstr "rien pour l'impression d'accolades de reprise"
#: font-config.cc:28
msgid "Initializing FontConfig..."
#: font-config.cc:38
#, c-format
msgid "Rebuilding FontConfig cache %s. this may take a while..."
-msgstr "Reconstruction du cache FontConfig %s. Patientez..."
+msgstr ""
#: font-config.cc:49 font-config.cc:51
#, c-format
#: general-scheme.cc:161
msgid "infinity or NaN encountered while converting Real number"
-msgstr "infini ou valeur non numérique rencontré lors de la conversion d'un nombre réel"
+msgstr "infini ou NaN rencontré lors de la conversion d'un nombre réel"
#: general-scheme.cc:162
msgid "setting to zero"
#: gourlay-breaking.cc:207
msgid "no feasible line breaking found"
-msgstr "aucun saut de ligne réalisable repéré"
+msgstr "aucun saut de ligne faisable repéré"
#: gourlay-breaking.cc:215
msgid "can't find line breaking that satisfies constraints"
-msgstr "impossible de trouver un saut de ligne qui satisfasse aux contraintes"
+msgstr "impossible de trouver un saut de ligne qui satisfasse les contraintes"
#: gregorian-ligature-engraver.cc:61
#, c-format
#. ligature may not start with 2nd head of pes or flexa
#: gregorian-ligature-engraver.cc:214
+#, fuzzy
msgid "can't apply `\\~' on first head of ligature"
-msgstr "Impossible d'appliquer '\\~' à la première tête de ligature"
+msgstr ""
+"Impossible d'appliquer '\\~' à la première tête de ligature ; '\\~' ignoré"
#. (pitch == prev_pitch)
#: gregorian-ligature-engraver.cc:226
+#, fuzzy
msgid "can't apply `\\~' on heads with identical pitch"
-msgstr "impossible d'appliquer '\\~' à des têtes ayant la même hauteur"
+msgstr ""
+"impossible de appliquer '\\~' à des têtes ayant la même hauteur ; '\\~' "
+"ignoré"
#: grob-interface.cc:48
#, c-format
"L'objet graphique (Grob) « %s » n'a pas d'interface pour la propriété « %s »"
#: grob.cc:242
+#, fuzzy
msgid "Infinity or NaN encountered"
-msgstr "infini ou valeur non numérique rencontré lors de la conversion d'un nombre réel"
+msgstr "infini ou NaN rencontré lors de la conversion d'un nombre réel"
#: hairpin.cc:149
msgid "decrescendo too small"
#: hyphen-engraver.cc:93
msgid "removing unterminated hyphen"
-msgstr "retrait du trait d'union sans suite"
+msgstr "retrait du trait d'union non terminé"
#: hyphen-engraver.cc:107
msgid "unterminated hyphen; removing"
-msgstr "trait d'union sans suite ; escamoté"
+msgstr "retrait du trait d'union non terminé"
#: includable-lexer.cc:53
msgid "include files are not allowed in safe mode"
#: ligature-engraver.cc:209
msgid "ignoring rest: ligature may not contain rest"
-msgstr "le silence est ignoré : une ligature ne peut contenir de silence"
+msgstr "le silence est ignoré : une ligature ne peut contenir un silence"
#: ligature-engraver.cc:210
msgid "ligature was started here"
#: lily-guile.cc:444
msgid "perhaps a typing error?"
-msgstr "s'agit-il d'une faute de frappe ?"
+msgstr "peut-être avez-vous commis une faute de frappe ?"
#: lily-guile.cc:450
msgid "doing assignment anyway"
#: lily-guile.cc:462
#, c-format
msgid "type check for `%s' failed; value `%s' must be of type `%s'"
-msgstr "la vérification du type de « %s » a échoué ; \n"
-" la valeur « %s » doit être du type « %s »"
+msgstr ""
+"la vérification du type de « %s » a échoué ; la valeur « %s » doit être du "
+"type « %s »"
#: lily-lexer.cc:223
#, c-format
msgstr "appel à une fonction obsolète : %s"
#: lily-parser-scheme.cc:76
-#, c-format
+#, fuzzy, c-format
msgid "Changing working directory to `%s'"
-msgstr "impossible de changer le répertoire de travail pour : %s"
+msgstr "impossible de changer de répertoire de travail vers : %s : %s"
#: lily-parser-scheme.cc:96
#, c-format
#: lyric-combine-music-iterator.cc:256
#, c-format
msgid "cannot find Voice `%s'"
-msgstr "impossible de repérer la voix Voice « %s »"
+msgstr "impossible de repérer la Voix %s"
#: main.cc:116
#, c-format
"under certain conditions. Invoke as `%s --warranty' for more\n"
"information.\n"
msgstr ""
-"Ce programme est un logiciel libre. Il est couvert par la licence GNU General\n"
-"Public License, et vous êtes libre de le modifier et/ou d'en distribuer des \n"
-"copies sous certaines conditions. Appelez « %s --warranty » pour plus d'informations.\n"
+"Ce logiciel est libre. Il est couvert par la licence GNU General Public "
+"License,\n"
+"et vous êtes libre de le modifier et/ou d'en distribuer des copies sous "
+"certaines conditions\n"
+"Invoquez « %s --warranty » pour plus d'informations.\n"
#: main.cc:122
msgid ""
msgstr "BACK"
#: main.cc:153
+#, fuzzy
msgid ""
"use backend BACK (gnome, ps,eps,\n"
"scm, svg, tex, texstr)\n"
"default: PS"
msgstr ""
-"utiliser le support BACK (gnome, ps, eps,\n"
-"scm, svg, tex, texstr)\n"
-"par défaut : PS"
+"utiliser le support BACK (gnome, ps [par défaut],\n"
+" scm, svg, tex, texstr)"
#: main.cc:155
msgid "SYM=VAL"
-msgstr "SYM=VAL"
+msgstr ""
#: main.cc:156
msgid ""
"set a Scheme program option. Uses #t if VAL is not specified\n"
"Try -dhelp for help."
msgstr ""
-"définit une option en langage Scheme. Utilise #t si VAL n'est pas spécifiée.\n"
-"Tenter -dhelp pour obtenir de l'aide."
#: main.cc:159
msgid "EXPR"
#: main.cc:159
msgid "evaluate scheme code"
-msgstr "évalue du code Scheme"
+msgstr ""
#. Bug in option parser: --output =foe is taken as an abbreviation
#. for --output-format.
#: main.cc:164
msgid "relocate using directory of lilypond program"
-msgstr "redétermine le chemin d'exécution de LilyPond"
+msgstr ""
#: main.cc:165
msgid "generate PDF (default)"
msgstr "CHAMP"
#: main.cc:170
+#, fuzzy
msgid "dump a header field to file BASENAME.FIELD"
-msgstr "écrire un champ d'en-tête dans le fichier BASENAME.CHAMP"
+msgstr "écrire un champ d'en-tête dans BASENAME.CHAMP"
#: main.cc:171
msgid "DIR"
msgstr "UTILISATEUR,GROUPE,CAGE,RÉPERTOIRE"
#: main.cc:174
+#, fuzzy
msgid ""
"chroot to JAIL, become USER:GROUP\n"
"and cd into DIR"
msgstr ""
"chroot dans CAGE, devenir UTILISATEUR:GROUPE\n"
-"et cd dans RÉPERTOIRE"
+" et cd dans RÉPERTOIRE"
#: main.cc:177
msgid "do not generate printed output"
#: main.cc:180
msgid "disallow unsafe Scheme and PostScript operations"
-msgstr "rejette les opérations Scheme et PostScript non sûres"
+msgstr ""
#: main.cc:181
msgid "print version number"
-msgstr "affiche le numéro de version"
+msgstr "afficher le numéro de version"
#: main.cc:221
#, c-format
#: main.cc:254
#, c-format
msgid "For more information, see %s"
-msgstr "Pour plus d'information, voir %s"
+msgstr "Pour plus d'informations, voir %s"
#: main.cc:256
#, c-format
msgstr "Options :"
#: main.cc:260
-#, c-format
+#, fuzzy, c-format
msgid "Report bugs via %s"
-msgstr "Rapporter toute anomalie à %s"
+msgstr "Rapporter toute anomalie à %s."
#: main.cc:306
-#, c-format
+#, fuzzy, c-format
msgid "expected %d arguments with jail, found: %u"
-msgstr "attendait %d arguments avec la cage, %u trouvés"
+msgstr "attendait %d arguments avec la cage, %d trouvés"
#: main.cc:320
#, c-format
#: main.cc:322
#, c-format
msgid "can't get user id from user name: %s: %s"
-msgstr "impossible de repérer l'id d'utilisateur à partir du nom d'utilisateur : %"
+msgstr ""
+"impossible de repérer l'id d'utilisateur à partir du nom d'utilisateur : %"
"s : %s"
#: main.cc:337
#: main.cc:339
#, c-format
msgid "can't get group id from group name: %s: %s"
-msgstr "impossible de repérer l'id de groupe à partir du nom de groupe : %s : %s"
+msgstr ""
+"impossible de repérer l'id de groupe à partir du nom de groupe : %s : %s"
#: main.cc:347
#, c-format
msgid "can't chroot to: %s: %s"
-msgstr "impossible de chrooter vers : %s : %s"
+msgstr "impossible de chrooter dans : %s : %s"
#: main.cc:354
#, c-format
msgid "can't change group id to: %d: %s"
-msgstr "impossible de changer l'id de groupe vers : %d : %s"
+msgstr "impossible de changer d'id de groupe vers : %d : %s"
#: main.cc:360
#, c-format
msgid "can't change user id to: %d: %s"
-msgstr "impossible de changer l'id d'utilisateur vers : %d : %s"
+msgstr "impossible de changer l'id d'utilisateur vers : « %d » : « %s »"
#: main.cc:366
#, c-format
msgid "can't change working directory to: %s: %s"
-msgstr "impossible de changer le répertoire de travail vers : %s : %s"
+msgstr "impossible de changer de répertoire de travail vers : %s : %s"
#: main.cc:413
#, c-format
msgid "Evaluating %s"
-msgstr "Èvaluation de %s"
+msgstr ""
#: main.cc:627
#, c-format
msgid "exception caught: %s"
-msgstr "Exception capturée : %s"
+msgstr ""
#. FIXME: constant error message.
#: mark-engraver.cc:131
#: mark-engraver.cc:137
msgid "mark label must be a markup object"
-msgstr "les étiquettes de marque doivent être des objets de type \"markup\""
+msgstr "les étiquettes de marques doivent être des objets de type \"markup\""
#: mensural-ligature-engraver.cc:77
msgid "ligature with less than 2 heads -> skipping"
-msgstr "ligature ayant moins de 2 têtes -> escamotage"
+msgstr "ligature avec moins de 2 têtes -> escamotée"
#: mensural-ligature-engraver.cc:104
msgid "cannot determine pitch of ligature primitive -> skipping"
-msgstr "impossible de déterminer la hauteur de la primitive de ligature -> escamotage"
+msgstr ""
+"impossible de déterminer la hauteur de la primitive de la ligature -> "
+"escamotée"
#: mensural-ligature-engraver.cc:118
msgid "single note ligature - skipping"
-msgstr "ligature de note unique -> escamotage"
+msgstr "ligature de note unique -> escamotée"
#: mensural-ligature-engraver.cc:130
msgid "prime interval within ligature -> skipping"
-msgstr "premier intervalle dans la ligature -> escamotage"
+msgstr "premier intervalle dans la ligature -> escamoté"
#: mensural-ligature-engraver.cc:142
msgid "mensural ligature: duration none of Mx, L, B, S -> skipping"
-msgstr "ligature mensurale : aucune durée parmi Mx, L, B, S -> escamotage"
+msgstr "ligature mensurale : aucune durée parmi Mx, L, B, S -> escamotée"
#: mensural-ligature-engraver.cc:190
msgid "semibrevis must be followed by another one -> skipping"
-msgstr "une ronde doit être suivie d'une autre -> escamotage"
+msgstr "une ronde doit être suivie d'une autre -> escamotée"
#: mensural-ligature-engraver.cc:201
msgid ""
#: music.cc:140
#, c-format
msgid "octave check failed; expected %s, found: %s"
-msgstr "la vérification d'octave a échoué ; attendait %s, a obtenu : %s"
+msgstr "la vérification d'octave a échoué; attendait %s, a obtenu : %s"
#: music.cc:203
#, c-format
#: new-fingering-engraver.cc:84
msgid "can't add text scripts to individual note heads"
-msgstr "impossible d'ajouter du texte à des têtes de notes individuelles"
+msgstr ""
+"impossible d'ajouter du texte complexe à des têtes de notes individuelles"
#.
#. music for the softenon children?
#: new-fingering-engraver.cc:261
msgid "no placement found for fingerings"
-msgstr "aucun emplacement trouvé pour des doigtés"
+msgstr "aucun emplacement repéré pour des doigtés"
#: new-fingering-engraver.cc:262
msgid "placing below"
#: note-column.cc:123
msgid "can't have note heads and rests together on a stem"
-msgstr "impossible de superposer une note et un silence"
+msgstr "superposition d'une note et d'un silence impossible"
#: note-head.cc:67
#, c-format
#: note-heads-engraver.cc:84
msgid "NoteEvent without pitch"
-msgstr "NoteEvent sans hauteur"
+msgstr ""
#: open-type-font.cc:33
-#, c-format
+#, fuzzy, c-format
msgid "can't allocate %lu bytes"
-msgstr "impossible d'allouer %lu octets"
+msgstr "impossible d'allouer %d octets"
#: open-type-font.cc:37
#, c-format
#: pango-font.cc:157
#, c-format
msgid "no PostScript font name for font `%s'"
-msgstr "aucun nom de police PostScript correspondant à « %s »"
+msgstr "aucun nom de police PostScript correspondant à %s"
#: pango-font.cc:205
msgid "FreeType face has no PostScript font name"
#: paper-score.cc:104
#, c-format
msgid "Element count %d (spanners %d) "
-msgstr "%d éléments dénombrés (extensions %d) "
+msgstr "%d éléments dénombrés (extenseurs %d) "
#: paper-score.cc:108
msgid "Preprocessing graphical objects..."
#: percent-repeat-iterator.cc:52
msgid "no one to print a percent"
-msgstr "nulle part où imprimer le pourcent de répétition"
+msgstr "rien pour l'impression de pourcent"
#: performance.cc:46
msgid "Track..."
msgstr "liaison de phrasé non terminée"
#: piano-pedal-engraver.cc:223
-#, c-format
+#, fuzzy, c-format
msgid "expect 3 strings for piano pedals, found: %ld"
-msgstr "nécessite 3 cordes pour les pédales du piano, mais seulement %ld trouvées"
+msgstr ""
+"nécessite 3 cordes pour les pédales du piano, mais seulement %d trouvées"
#: piano-pedal-engraver.cc:238 piano-pedal-engraver.cc:249
#: piano-pedal-performer.cc:82
#: piano-pedal-engraver.cc:296
#, c-format
msgid "can't find start of piano pedal bracket: `%s'"
-msgstr "impossible de trouver le début du crochet de pédale de piano : « %s »"
+msgstr ""
+"impossible de repérer le début du crochet de la pédale de piano : « %s »"
#: program-option.cc:195
#, c-format
msgstr "Échec de la vérification de l'octave, a obtenu : "
#: relocate.cc:52
-#, c-format
+#, fuzzy, c-format
msgid "no such file: %s for %s"
-msgstr "fichier inexistant : %s pour %s"
+msgstr "symbole inexistant : %s : %s"
#: relocate.cc:62 relocate.cc:80
-#, c-format
+#, fuzzy, c-format
msgid "no such directory: %s for %s"
-msgstr "répertoire inexistant : %s pour %s"
+msgstr "symbole inexistant : %s : %s"
#: relocate.cc:72
#, c-format
#: relocate.cc:104
#, c-format
msgid "Relocation: compile prefix=%s, new prefix=%s"
-msgstr "Réaffectation : prefixe de compilation=%s, nouveau préfixe=%s"
+msgstr ""
#: relocate.cc:130
#, c-format
msgid "Relocation: framework_prefix=%s"
-msgstr "Réaffectation : framework_prefix=%s"
+msgstr ""
#: relocate.cc:212
#, c-format
msgid "Relocation: is absolute: argv0=%s"
-msgstr "Réaffectation : est absolu : argv0=%s"
+msgstr ""
#: relocate.cc:219
#, c-format
msgid "Relocation: from cwd: argv0=%s"
-msgstr "Réaffectation : à partir du répertoire courant : argv0=%s"
+msgstr ""
#: relocate.cc:228
#, c-format
"Relocation: from PATH=%s\n"
"argv0=%s"
msgstr ""
-"Réaffectation : à partir de PATH=%s\n"
-"argv0=%s"
#: rest-collision.cc:149
msgid "can't resolve rest collision: rest direction not set"
-msgstr "collision de silences insoluble : direction du silence non fixée"
+msgstr ""
#: rest-collision.cc:163 rest-collision.cc:208
msgid "too many colliding rests"
#: stem.cc:98
msgid "weird stem size, check for narrow beams"
-msgstr "taille de hampe bizarre ; vérifier la présence de liens étroits"
+msgstr "taille de hampe bizarre ; vérifiez la présence de liens étroits"
#: stem.cc:592
#, c-format
#: stem.cc:603
#, c-format
msgid "flag stroke `%s' not found"
-msgstr "type de crochet `%s' non repéré"
+msgstr "crochet `%s' non repéré"
#: system.cc:181
#, c-format
#: tfm-reader.cc:140
#, c-format
msgid "%s: TFM file has %u parameters, which is more than the %u I can handle"
-msgstr "%s : le fichier TFM a %u paramètres, soit plus que les %u pouvant être "
+msgstr ""
+"%s : le fichier TFM a %u paramètres, soit plus que les %u pouvant être "
"traités"
#: tfm.cc:72
#: time-signature-engraver.cc:63
#, c-format
msgid "strange time signature found: %d/%d"
-msgstr "chiffrage de mesure étrange : %d/%d"
+msgstr "chiffrage de mesure quelque peu étrange : %d/%d"
#. If there is no such symbol, we default to the numbered style.
#. (Here really with a warning!)
#: time-signature.cc:82
#, c-format
msgid "time signature symbol `%s' not found; reverting to numbered style"
-msgstr "symbole de chiffrage de mesure « %s » non trouvé ; retour à un style numérique"
+msgstr ""
+"symbole de chiffrage de mesure « %s » non trouvé ; retour à un style "
+"numérique"
#: translator-ctors.cc:52
#, c-format
#. no longer valid with dashes in \paper{} block.
#: parser.yy:535
msgid "identifier should have alphabetic characters only"
-msgstr "l'identificateur doit contenir uniquement des caractères alphabétiques"
+msgstr "l'identificateur doit contenir des caractères alphabétiques seulement"
#: parser.yy:705
msgid "\\paper cannot be used in \\score, use \\layout instead"
#: parser.yy:729
msgid "need \\paper for paper block"
-msgstr "\\paper est nécessaire pour définir les paramètres de la page"
+msgstr "\\paper est nécessaire pour définir les paramètres du papier"
#: parser.yy:879
msgid "more alternatives than repeats"
#: parser.yy:1822
msgid "expecting string as script definition"
-msgstr "chaîne attendue comme définition de script"
+msgstr "un script doit être défini par une chaîne ; ce n'est pas le cas"
#: parser.yy:1981 parser.yy:2031
#, c-format
#: lexer.ll:158
msgid "stray UTF-8 BOM encountered"
-msgstr "parasitage par UTF-8 BOM"
+msgstr ""
#: lexer.ll:162
msgid "Skipping UTF-8 BOM"
-msgstr "Escamotage d'UTF-8 BOM"
+msgstr ""
#: lexer.ll:206
#, c-format
#: lexer.ll:231
msgid "EOF found inside a comment"
-msgstr "Fin de fichier (EOF) au mileu d'un commentaire"
+msgstr "Fin de fichier (EOF) à l'intérieur d'un commentaire"
#: lexer.ll:246
msgid "\\maininput not allowed outside init files"
#: lexer.ll:441
msgid "Brace found at end of lyric. Did you forget a space?"
-msgstr "Accolade repérée à la fin d'une parole. Manquerait-il un espace ?"
+msgstr "Accolade repérée à la fin d'une parole. Avez-vous oublié un espace ?"
#: lexer.ll:540
msgid "Brace found at end of markup. Did you forget a space?"
-msgstr "Accolade repérée à la fin d'un \"markup\". Manquerait-il un espace ?"
+msgstr ""
+"Accolade repérée à la fin d'un \"markup\". Avez-vous oublié un espace ?"
#: lexer.ll:640
#, c-format
#: lexer.ll:825
msgid "Consider updating the input with the convert-ly script"
-msgstr "Envisagez la mise à jour de la source à l'aide du script convert-ly"
+msgstr "Envisager la mise à jour de la source à l'aide du script convert-ly"
#. TODO: print location
#: lexer.ll:945
#: define-markup-commands.scm:251
msgid "no systems found in \\score markup, does it have a \\layout block?"
-msgstr "pas de système trouvé dans le bloc \\score, contient-il un bloc \\layout ?"
+msgstr ""
+"pas de système trouvé dans le bloc \\score, contient-il un bloc \\layout ?"
#: define-markup-commands.scm:1205
#, lisp-format
#: define-music-types.scm:762
msgid "See music-types.scm for supported repeats"
-msgstr "Consulter music-types.scm pour les types de répétitions reconnus"
+msgstr "Consulter music-types.scm pour les répétitions admises"
#: document-backend.scm:91
#, lisp-format
msgstr "impossible de trouver l'interface pour la propriété ~S"
#: document-backend.scm:145
-#, lisp-format
+#, fuzzy, lisp-format
msgid "unknown Grob interface: ~S"
-msgstr "interface d'objet graphique (Grob) inconnue : ~S"
+msgstr "interface inconnue : « ~S »"
#: documentation-lib.scm:45
#, lisp-format
#: documentation-lib.scm:150
#, lisp-format
msgid "Writing ~S..."
-msgstr "Écriture de ~S..."
+msgstr "Écriture de « ~S »..."
#: documentation-lib.scm:172
-#, lisp-format
+#, fuzzy, lisp-format
msgid "can't find description for property ~S (~S)"
-msgstr "impossible de trouver une description pour la propriété ~S (~S)"
+msgstr "impossible de trouver une description pour la propriété ~S"
#: framework-eps.scm:71 framework-eps.scm:72
#, lisp-format
msgid "Writing ~a..."
-msgstr "Écriture de ~a..."
+msgstr "Écriture de « ~a »..."
#: framework-ps.scm:275
#, lisp-format
msgid "can't embed ~S=~S"
-msgstr "intégration impossible : ~S=~S"
+msgstr ""
#: framework-ps.scm:326
#, lisp-format
msgid "can't extract file matching ~a from ~a"
-msgstr "impossible d'extraire le fichier ~a à partir de ~a"
+msgstr ""
#: framework-ps.scm:343
#, lisp-format
msgid "don't know how to embed ~S=~S"
-msgstr "imposible de réaliser l'intégration ~S=~S"
+msgstr ""
#: framework-ps.scm:373
-#, lisp-format
+#, fuzzy, lisp-format
msgid "don't know how to embed font ~s ~s ~s"
-msgstr "impossible d'intégrer les polices ~s ~s ~s"
+msgstr "ne sait comment interpréter l'articulation : "
#: framework-ps.scm:579
#, lisp-format
"\n"
"or remove the lilypond-book specific settings from the input.\n"
msgstr ""
-"Le support PostScript ne prend pas en compte le cadre « classique ».\n"
-"Utilisez de préférence le support EPS\n"
-"\n"
-" lilypond -b eps <fichier>\n"
-"\n"
-"ou supprimez du fichier source les paramètres spécifiques à lilypond-book.\n"
#: framework-tex.scm:356
#, lisp-format
msgid "TeX file name must not contain whitespace: `~a'"
-msgstr "un nom de fichier Tex ne peut contenir d'espace : « ~a »"
+msgstr "un nom de fichier Tex ne peut contenir des espaces : « ~a »"
#: layout-beam.scm:29
#, lisp-format
#: lily-library.scm:491
#, lisp-format
msgid "no \\version statement found, add~afor future compatibility"
-msgstr "pas de déclaration \\version trouvée, ajoutez ~a pour une compatibilité "
+msgstr ""
+"pas de déclaration \\version trouvée, ajoutez ~a pour une compatibilité "
"future"
#: lily-library.scm:498
msgstr "erreur sur les fichiers : ~S"
#: lily.scm:419
-#, lisp-format
+#, fuzzy, lisp-format
msgid "Redirecting output to ~a..."
-msgstr "Redirection de la sortie vers ~a..."
+msgstr "Conversion en ~a..."
#: markup.scm:88
#, lisp-format
#: music-functions.scm:584
#, lisp-format
msgid "Bar check failed. Expect to be at ~a, instead at ~a"
-msgstr "Échec du contrôle de barre de mesure. \n"
-"Aurait dû se trouver à ~a au lieu de ~a"
+msgstr ""
+"Échec du contrôle de barre de mesure. Aurait dû se trouver à ~a au lieu de ~a"
#: music-functions.scm:739
#, lisp-format
msgid "can't find quoted music `~S'"
-msgstr "impossible de trouver la citation de musique « ~S »"
+msgstr "impossible de trouver la citation de musique '~S'"
#: music-functions.scm:947
#, lisp-format
msgstr "style d'altération inconnu : ~S"
#: output-ps.scm:282
+#, fuzzy
msgid "utf-8-string encountered in PS backend"
msgstr "le support PS a rencontré une chaîne utf8"
#: parser-clef.scm:124
#, lisp-format
msgid "unknown clef type `~a'"
-msgstr "type de clef inconnu : « ~a »"
+msgstr "type de clef inconnu : `~a'"
#: parser-clef.scm:125
msgid "see scm/clef.scm for supported clefs"
-msgstr "consultez scm/clef.scm pour les clefs reconnues"
+msgstr "consulter scm/clef.scm pour les clefs reconnues"
#: ps-to-png.scm:97
-#, lisp-format
+#, fuzzy, lisp-format
msgid "~a exited with status: ~S"
-msgstr "~a terminé avec l'état : ~S"
+msgstr "%s a terminé avec l'état : %d"
#: to-xml.scm:190
msgid "assertion failed"
msgstr "erreur d'assertion"
+#~ msgid "lilylib module"
+#~ msgstr "module lilylib"
+
+#~ msgid "Usage: %s [OPTIONS]... FILE"
+#~ msgstr "Utilisation : %s [OPTIONS]... FICHIER"
+
+#~ msgid "Binary %s has version %s, looking for version %s"
+#~ msgstr "Binaire %s de version %s, recherche de la version %s"
+
+#~ msgid "Opening pipe `%s'"
+#~ msgstr "Ouverture du tube « %s »"
+
+#~ msgid "`%s' failed (%s)"
+#~ msgstr "« %s » a échoué (%s)"
+
+#~ msgid "(ignored)"
+#~ msgstr "(ignoré)"
+
+#~ msgid "Cleaning %s..."
+#~ msgstr "Nettoyage de %s..."
+
+#~ msgid "Usage: %s [OPTION]... [FILE]..."
+#~ msgstr "Utilisation : %s [OPTIONS]... [FICHIER]..."
+
+#~ msgid ""
+#~ " -e, --edit edit in place\n"
+#~ " -f, --from=VERSION start from VERSION [default: \\version found in "
+#~ "file]\n"
+#~ " -h, --help print this help\n"
+#~ " -n, --no-version do not add \\version command if missing\n"
+#~ " -s, --show-rules print rules [default: --from=0, --"
+#~ "to=@TOPLEVEL_VERSION@]\n"
+#~ " -t, --to=VERSION convert to VERSION [default: "
+#~ "@TOPLEVEL_VERSION@]\n"
+#~ " -v, --version print program version"
+#~ msgstr ""
+#~ "-e, --edit éditer le fichier d'origine\n"
+#~ "-f, --from=VERSION à partir de la VERSION [défaut : \\version trouvée "
+#~ "dans le fichier]\n"
+#~ "-h, --help afficher cet aide-mémoire\n"
+#~ "-n, --no-version ne pas ajouter la commande \\version si absente\n"
+#~ "-s, --show-rules afficher les règles [défaut : --from=0, "
+#~ "to=@TOPLEVEL_VERSION@]\n"
+#~ "-t, --to=VERSION mettre au niveau de la VERSION [défaut : "
+#~ "@TOPLEVEL_VERSION@]\n"
+#~ "-v, --version afficher la version du programme"
+
+#~ msgid "%s: skipping: `%s'"
+#~ msgstr "%s : escamotage : « %s »"
+
+#~ msgid "FMT"
+#~ msgstr "FMT"
+
+#~ msgid "print version information"
+#~ msgstr "afficher les informations de version"
+
+#~ msgid "getopt says: `%s'"
+#~ msgstr "getopt() indique : « %s »"
+
+#~ msgid "Not in FILE:LINE:COL format: "
+#~ msgstr "N'est pas dans le format : FICHIER:LIGNE:COLONNE"
+
+#~ msgid "Command failed: `%s' (status %d)"
+#~ msgstr "Échec de la commande : %s (état d'exécution %d)."
+
+#~ msgid "command exited with value %d"
+#~ msgstr "fin de la commande avec l'état %d"
+
+#~ msgid "Example:"
+#~ msgstr "Exemple :"
+
+#~ msgid "Convert mup to LilyPond source."
+#~ msgstr "Convertir du format mup au format source LilyPond"
+
+#~ msgid "debug"
+#~ msgstr "débogue"
+
+#~ msgid "define macro NAME [optional expansion EXP]"
+#~ msgstr "définit la macro NOM [expansion optionnelle EXP]"
+
+#~ msgid "only pre-process"
+#~ msgstr "pré-traitement seulement"
+
+#~ msgid "no such context: %s"
+#~ msgstr "contexte inexistant : %s"
+
+#~ msgid "Processing `%s'..."
+#~ msgstr "Traitement de « %s »..."
+
+#~ msgid "Convert PostScript to PNG image."
+#~ msgstr "Convertir le PostScript en image PNG"
+
+#~ msgid "PAPER"
+#~ msgstr "PAPIER"
+
+#~ msgid "use papersize PAPER"
+#~ msgstr "utiliser le format PAPIER"
+
+#~ msgid "RES"
+#~ msgstr "RES"
+
+#~ msgid "set the resolution of the preview to RES"
+#~ msgstr "définir la résolution de la prévisualisation à RES"
+
+#~ msgid "Wrote `%s'"
+#~ msgstr "« %s » écrit"
+
+#~ msgid "can't dlopen: %s: %s"
+#~ msgstr "impossible d'ouvrir le fichier par dlopen : %s : %s"
+
+#~ msgid "install package: %s or %s"
+#~ msgstr "installer le paquetage : %s ou %s"
+
+#~ msgid "error opening kpathsea library"
+#~ msgstr "erreur d'ouverture de la bibliothèque kpathsea"
+
+#~ msgid "aborting"
+#~ msgstr "abandon"
+
+#~ msgid "parsing AFM file: `%s'"
+#~ msgstr "analyse syntaxique du fichier AFM : « %s »"
+
+#~ msgid "checksum mismatch for font file: `%s'"
+#~ msgstr ""
+#~ "la somme de contrôle ne concorde pas pour le fichier de police : « %s »"
+
+#~ msgid "does not match: `%s'"
+#~ msgstr "ne concorde pas : « %s »"
+
+#~ msgid "Rebuild all .afm files, and remove all .pk and .tfm files."
+#~ msgstr ""
+#~ "Reconstruire tous les fichiers .afm et enlever tous les fichiers .pk et ."
+#~ "tfm."
+
+#~ msgid "Rerun with -V to show font paths."
+#~ msgstr ""
+#~ "Ré-exécuter avec l'option -V pour afficher les chemins vers les polices."
+
+#~ msgid "A script for removing font-files is delivered with the source-code:"
+#~ msgstr ""
+#~ "Un script enlevant les fichiers de polices est livré avec le code source :"
+
+#~ msgid "beam has less than two visible stems"
+#~ msgstr "le lien a moins de deux hampes visibles"
+
+#~ msgid "initializing FontConfig"
+#~ msgstr "initialisation de FontConfig"
+
+#~ msgid "adding lilypond directory: %s"
+#~ msgstr "ajout du répertoire lilypond : %s"
+
+#~ msgid ""
+#~ "set scheme option, for help use\n"
+#~ " -e '(ly:option-usage)'"
+#~ msgstr ""
+#~ "définir l'option scheme ; pour de l'aide, utiliser\n"
+#~ " -e '(ly:option-usage)"
+
+#~ msgid "run in safe mode"
+#~ msgstr "exécuter en mode sécurisé"
+
+#~ msgid "can't handle a percent repeat of length: %s"
+#~ msgstr ""
+#~ "ne sait comment traiter la répétition en pourcent sur une longueur de %s"
+
+#~ msgid "rest direction not set. Cannot resolve collision."
+#~ msgstr ""
+#~ "direction du silence non déterminée. Impossible de résoudre la collision."
+
+#~ msgid "lilypond -e EXPR means:"
+#~ msgstr "lilypond -e EXPRESSION signifie :"
+
+#~ msgid " Evalute the Scheme EXPR before parsing any .ly files."
+#~ msgstr ""
+#~ " Évaluer l'expression Scheme EXPR avant d'analyser les fichiers .ly"
+
+#~ msgid ""
+#~ " Multiple -e options may be given, they will be evaluated sequentially."
+#~ msgstr ""
+#~ " De multiples options -e peuvent être fournies, elles seront évaluées "
+#~ "séquentiellement."
+
+#~ msgid ""
+#~ " The function ly:set-option allows for access to some internal variables."
+#~ msgstr ""
+#~ " La fonction ly:set-option permet l'accès à quelques variables internes."
+
+#~ msgid "Usage: lilypond -e \"(ly:set-option SYMBOL VAL)\""
+#~ msgstr "Utilisation : lilypond -e \"(ly-set-option SYMBOLE VALEUR)\""
+
+#~ msgid "Use help as SYMBOL to get online help."
+#~ msgstr "Utiliser help comme SYMBOLE pour obtenir de l'aide en ligne."
+
+#~ msgid "Separation_item: I've been drinking too much"
+#~ msgstr "Separation_item : J'ai dû trop boire..."
+
+#~ msgid "removing tuplet bracket across linebreak"
+#~ msgstr "effacement des accolades de n-olet pour saut de ligne"
+
+#~ msgid "tag must be symbol or list of symbols"
+#~ msgstr "l'étiquette doit être un symbole ou une liste de symboles"
+
+#~ msgid "need integer number arg"
+#~ msgstr "l'argument doit être un nombre entier"
+
+#~ msgid "suspect duration in beam: %s"
+#~ msgstr "durée suspecte à l'intérieur du lien : %s"
+
+#~ msgid "syntax error: cannot back up"
+#~ msgstr "erreur de syntaxe : impossible de revenir en arrière"
+
+#~ msgid "Stack now"
+#~ msgstr "Empilement"
+
+#~ msgid "Reducing stack by rule %d (line %u), "
+#~ msgstr "Réduction de la pile par la règle %d (ligne %u), "
+
+#~ msgid "parser stack overflow"
+#~ msgstr "saturation de la pile de l'analyseur syntaxique"
+
+#~ msgid "Stack size increased to %lu\n"
+#~ msgstr "La taille de la pile est passée à %lu\n"
+
+#~ msgid "Entering state %d\n"
+#~ msgstr "Passe à l'état %d\n"
+
+#~ msgid "Reading a token: "
+#~ msgstr "Lecture d'un jeton :"
+
+#~ msgid "Now at end of input.\n"
+#~ msgstr "Fin de la source atteinte.\n"
+
+#~ msgid "Next token is"
+#~ msgstr "Le jeton suivant est "
+
+#~ msgid "Shifting"
+#~ msgstr "Décalage en cours"
+
+#~ msgid "syntax error, unexpected %s"
+#~ msgstr "erreur de syntaxe : %s inattendu."
+
+#~ msgid "syntax error, unexpected %s, expecting %s"
+#~ msgstr "erreur de syntaxe : %s inattendu, au lieu de %s"
+
+#~ msgid "syntax error, unexpected %s, expecting %s or %s"
+#~ msgstr "erreur de syntaxe : %s inattendu, au lieu de %s ou %s"
+
+#~ msgid "syntax error, unexpected %s, expecting %s or %s or %s"
+#~ msgstr "erreur de syntaxe : %s inattendu, au lieu de %s ou %s ou %s"
+
+#~ msgid "syntax error, unexpected %s, expecting %s or %s or %s or %s"
+#~ msgstr "erreur de syntaxe : %s inattendu, au lieu de %s ou %s ou %s ou %s"
+
+#~ msgid "syntax error; also memory exhausted"
+#~ msgstr "erreur de syntaxe, et épuisement de la mémoire..."
+
+#~ msgid "syntax error"
+#~ msgstr "erreur de syntaxe"
+
+#~ msgid "Error: popping"
+#~ msgstr "Erreur : dépile"
+
+#~ msgid "Error: discarding"
+#~ msgstr "Erreur, mise au rebut"
+
+#~ msgid "Error: discarding lookahead"
+#~ msgstr "Erreur, abandon"
+
+#~ msgid "Could not find bounding box of `~a'"
+#~ msgstr "Conteneur pour '~a' non repéré"
+
+#~ msgid "can't find CFF/PFA/PFB font ~S=~S"
+#~ msgstr "impossible de trouver la police CFF/PFA/PFB ~S=~S"
+
+#~ msgid "unknown bar glyph: `~S'"
+#~ msgstr "forme de barre inconnue : '~S'"
% /setgray { 1 add } bind def
+% To let gs load fonts from builddir, do:
+% export GS_LIB=$(pwd)/mf/out:/usr/share/texmf/fonts/type1/bluesky/cm
+
+
/set-ps-scale-to-lily-scale {
lily-output-units output-scale mul dup scale
} bind def
% TODO: use dicts or prefixes to prevent namespace pollution.
+% Emulation code from Postscript Language Reference.
+
+/*SF
+{
+ exch findfont exch
+ dup type /arraytype eq
+ {makefont}
+ {scalefont}
+ ifelse
+ setfont
+} bind def
+
+/languagelevel where
+ {pop languagelevel}
+ {1}
+ifelse
+
+2 lt
+ { /selectfont /*SF load def }
+if
+
+% end emulation code
+
/pdfmark where
{pop} {userdict /pdfmark /cleartomark load put} ifelse
lastx = x
return s
- def regularize_dollar_reference (match):
- return regularize_id (match.group (1))
- def regularize_assignment (match):
- return '\n' + regularize_id (match.group (1)) + ' = '
- str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
- str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
- return str
+ def regularize_dollar_reference (match):
+ return regularize_id (match.group (1))
+ def regularize_assignment (match):
+ return '\n' + regularize_id (match.group (1)) + ' = '
+ str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
+ str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
+ return str
conversions.append (((1,3,117), conv, 'identifier names: $!foo_bar_123 -> xfooBarABC'))
def conv (str):
for a in ['beamed-lengths', 'beamed-minimum-free-lengths',
- 'lengths',
'beamed-extreme-minimum-free-lengths']:
str = re.sub (r"\\override\s+Stem\s+#'%s" % a,
r"\\override Stem #'details #'%s" % a,
"""override Stem #'beamed-* -> #'details #'beamed-*"""))
def conv (str):
- str = re.sub (r'\\epsfile *#"', r'\\epsfile #X #10 #"', str)
+ str = re.sub (r'\epsfile *#"', r'\epsfile #X #10 #"', str)
return str
conversions.append (((2, 7, 30), conv,
str = re.sub (r'\\context\s+\"?([a-zA-Z]+)\"?\s*\\applyOutput', r"\\applyOutput #'\1", str)
return str
-conversions.append (((2, 9, 6), conv, """\context Foo \\applyOutput #bla -> \\applyOutput #'Foo #bla """))
-
-
-def conv (str):
- str = re.sub ('annotatepage', 'annotate-page', str)
- str = re.sub ('annotateheaders', 'annotate-headers', str)
- str = re.sub ('annotatesystems', 'annotate-systems', str)
- return str
-
-conversions.append (((2, 9, 9), conv, """annotatefoo -> annotate-foo"""))
-
-
-def conv (str):
- str = re.sub (r"""(\\set\s)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#denominator-tuplet-formatter""",
- r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-denominator-text""", str)
-
- str = re.sub (r"""(\\set\s+)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#fraction-tuplet-formatter""",
- r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-fraction-text""", str)
-
- if re.search ('tupletNumberFormatFunction', str):
- error_file.write ("\n")
- error_file.write ("tupletNumberFormatFunction has been removed. Use #'text property on TupletNumber")
- error_file.write ("\n")
-
- return str
-
-conversions.append (((2, 9, 11), conv, """\\set tupletNumberFormatFunction -> \\override #'text = """))
-
-
-def conv (str):
- str = re.sub ('vocNam', 'shortVocalName', str)
- str = re.sub (r'\.instr\s*=', r'.shortInstrumentName =', str)
- str = re.sub (r'\.instrument\s*=', r'.instrumentName =', str)
- return str
-
-conversions.append (((2, 9, 13), conv, """instrument -> instrumentName, instr -> shortInstrumentName, vocNam -> shortVocalName"""))
-
-
-def conv (str):
-
- def sub_tempo (m):
- dur = int (m.group (1))
- dots = len (m.group (2))
- count = int (m.group (3))
-
- log2 = 0
- while dur > 1 :
- dur /= 2
- log2 += 1
-
- den = (1 << dots) * (1 << log2)
- num = ((1 << (dots+1)) - 1)
-
- return """
- \midi {
- \context {
- \Score
- tempoWholesPerMinute = #(ly:make-moment %d %d)
- }
- }
-
-""" % (num*count, den)
-
- str = re.sub (r'\\midi\s*{\s*\\tempo ([0-9]+)\s*([.]*)\s*=\s*([0-9]+)\s*}', sub_tempo, str)
- return str
-
-conversions.append (((2, 9, 16), conv, """deprecate \\tempo in \\midi"""))
-
-def conv (str):
- str = re.sub ('printfirst-page-number', 'print-first-page-number', str)
- return str
-
-conversions.append (((2, 9, 19), conv, """printfirst-page-number -> print-first-page-number"""))
-
+conversions.append (((2, 9, 6), conv, """\context Foo \applyOutput #bla -> \applyOutput #'Foo #bla """))
underscore = _
progress = sys.stderr.write
-# Modified version of the commands.mkarg(x), which always uses
-# double quotes (since Windows can't handle the single quotes:
-def mkarg(x):
- s = ' "'
- for c in x:
- if c in '\\$"`':
- s = s + '\\'
- s = s + c
- s = s + '"'
- return s
def command_name (cmd):
# Strip all stuf after command,
cmd = re.match ('([\(\)]*)([^\\\ ]*)', cmd).group (2)
return os.path.basename (cmd)
-def subprocess_system (cmd,
- ignore_error=False,
- progress_p=True,
- be_verbose=False,
- log_file=None):
+def system (cmd,
+ ignore_error=False,
+ progress_p=True,
+ be_verbose=False,
+ log_file=None):
+
import subprocess
show_progress= progress_p
return abs (retval)
-def ossystem_system (cmd,
- ignore_error=False,
- progress_p=True,
- be_verbose=False,
- log_file=None):
-
-
- name = command_name (cmd)
- if be_verbose:
- show_progress = 1
- progress (_ ("Invoking `%s\'") % cmd)
- else:
- progress ( _("Running %s...") % name)
-
- retval = os.system (cmd)
- if retval:
- print >>sys.stderr, 'command failed:', cmd
- if retval < 0:
- print >>sys.stderr, "Child was terminated by signal", -retval
- elif retval > 0:
- print >>sys.stderr, "Child returned", retval
-
- if ignore_error:
- print >>sys.stderr, "Error ignored"
- else:
- sys.exit (1)
-
- return abs (retval)
-
-
-system = subprocess_system
-if sys.platform == 'mingw32':
-
- ## subprocess x-compile doesn't work.
- system = ossystem_system
-
def strip_extension (f, ext):
(p, e) = os.path.splitext (f)
if e == ext:
long sum = 0;
int i = 0;
- for (; i < length &&
- ((*str) + i < end_str); i++)
+ for (; i < length; i++)
sum = (sum << 8) + (unsigned char) (*str)[i];
*str += length;
}
typedef PyObject* (*Read_midi_event)
- (unsigned char **track, unsigned char *end,
- unsigned char x);
+ (unsigned char **track, unsigned char *end,
+ unsigned char x);
static PyObject *
pytrack = PyList_New (0);
- if (*track + track_len < track_end)
- track_end = *track + track_len;
+ track_end = *track + track_len;
{
PyObject *pytime = PyInt_FromLong (0L);
/* Header */
header_len = get_number (midi, *midi + 4, 4);
+
if (header_len < 6)
return midi_error (__FUNCTION__, ": header too short");
return 0;
if (memcmp (midi, "MThd", 4))
- return midi_error (__FUNCTION__, ": MThd expected");
+ return midi_error (__FUNCTION__, ": MThd expected");
midi += 4;
"return (fifths, mode) tuple"
key = self.get_named_attribute ('key')
- mode_node = key.get_maybe_exist_named_child ('mode')
+ mode_node = self.get_maybe_exist_named_child ('mode')
mode = 'major'
if mode_node:
mode = mode_node.get_text ()
(evs (map car (cdar event-list)))
(now (car now-tun))
(notes (filter (lambda (x)
- (equal? (ly:event-property x 'class) 'note-event))
+ (equal? (ly:music-property x 'name) 'NoteEvent))
evs))
(pitch (if (pair? notes)
- (ly:event-property (car notes) 'pitch)
+ (ly:music-property (car notes) 'pitch)
#f)))
;; tail recursive.
(if (and pitch (not (= (ly:pitch-steps pitch) 0)))
(if pitch #f now)
(cdr event-list) acc)))))
+ (set! noticed '())
(let* ((m (make-music 'AutoChangeMusic))
- (m1 (make-non-relative-music (context-spec-music music 'Voice "one")))
- (context-list (recording-group-emulate music part-combine-listener))
- (evs (car context-list))
- (rev (reverse! (cdar context-list)))
+ (context (ly:run-translator (make-non-relative-music music) part-combine-listener))
+ (evs (last-pair noticed))
(split (reverse! (generate-split-list
#f
- rev
+ (if (pair? evs)
+ (reverse! (cdar evs) '()) '())
'())
'())))
(set! (ly:music-property m 'element) music)
(set! (ly:music-property m 'split-list) split)
+ (set! noticed '())
m))
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 2005--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; backend helpers.
;; must be sure that we don't catch stuff from old GUBs.
(search-executable '("gs")))
-
-(define-public (postscript->pdf paper-width paper-height name)
- (let* ((pdf-name (string-append
- (basename (basename name ".ps") ".eps")
- ".pdf"))
- (is-eps (string-match "\\.eps$" name))
- (paper-size-string (if is-eps
- " -dEPSCrop "
- (format "-dDEVICEWIDTHPOINTS=~,2f \
--dDEVICEHEIGHTPOINTS=~,2f "
- paper-width paper-height )))
+(define-public (postscript->pdf papersizename name)
+ (let* ((pdf-name (string-append (basename name ".ps") ".pdf"))
(cmd (format #f
"~a\
~a\
~a\
- ~a\
-dCompatibilityLevel=1.4 \
+ -sPAPERSIZE=~a\
-dNOPAUSE\
-dBATCH\
-r1200 \
"
(search-gs)
(if (ly:get-option 'verbose) "" "-q")
- (if (ly:get-option 'gs-load-fonts)
+ (if (ly:get-option 'gs-font-load)
" -dNOSAFER "
" -dSAFER ")
- paper-size-string
+ (sanitize-command-option papersizename)
pdf-name
name)))
;; The wrapper on windows cannot handle `=' signs,
(use-modules (scm ps-to-png))
-(define-public (postscript->png resolution paper-width paper-height name)
+(define-public (postscript->png resolution paper-size-name name)
;; Do not try to guess the name of the png file,
;; GS produces PNG files like BASE-page%d.png.
;;(ly:message (_ "Converting to `~a'...")
;; (string-append (basename name ".ps") "-page1.png" )))
- (let ((verbose (ly:get-option 'verbose))
+ (let ((paper-size (sanitize-command-option paper-size-name))
+ (verbose (ly:get-option 'verbose))
(rename-page-1 #f))
(ly:message (_ "Converting to ~a...") "PNG")
- (make-ps-images name resolution paper-width paper-height rename-page-1 verbose
+ (make-ps-images name resolution paper-size rename-page-1 verbose
(ly:get-option 'anti-alias-factor))
(ly:progress "\n")))
(lambda (x)
(member x formats))
completed)))
-
(for-each
(lambda (f)
- ((eval (string->symbol (format "convert-to-~a" f)) module)
+ ((eval (string->symbol (string-append "convert-to-" f)) module)
paper-book filename))
completed)
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;; Note: this file can't be used without LilyPond executable
;;;;
;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-(define-public (construct-chord-elements root duration modifications)
- " Build a chord on root using modifiers in MODIFICATIONS. NoteEvents
-have duration DURATION.
+(define-public (construct-chord root duration modifications)
+ " Build a chord on root using modifiers in MODIFICATIONS. NoteEvent
+have duration DURATION..
Notes: natural 11 is left from chord if not explicitly specified.
Entry point for the parser.
+
"
(let* ((flat-mods (flatten-list modifications))
(base-chord (stack-thirds (ly:make-pitch 0 4 0) the-canonical-chord))
(write-me "inversion: " inversion)
(write-me "bass: " bass)))
(if inversion
- (make-chord-elements (cdr complete-chord) bass duration (car complete-chord)
+ (make-chord (cdr complete-chord) bass duration (car complete-chord)
inversion)
- (make-chord-elements complete-chord bass duration #f #f))))
+ (make-chord complete-chord bass duration #f #f))))
-(define (make-chord-elements pitches bass duration inversion original-inv-pitch)
+(define (make-chord pitches bass duration inversion original-inv-pitch)
"Make EventChord with notes corresponding to PITCHES, BASS and
DURATION, and INVERSION."
(define (make-note-ev pitch)
(- (ly:pitch-octave inversion)
(ly:pitch-octave original-inv-pitch)))
(set! nots (cons inv-note nots))))
- nots))
+ (make-event-chord nots)))
;;;;;;;;;;;;;;;;
; chord modifiers change the pitch list.
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define (natural-chord-alteration p)
"Return the natural alteration for step P."
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define-public all-translation-properties '())
(define (translator-property-description symbol type? description)
- (if (not (and
- (symbol? symbol)
- (procedure? type?)
- (string? description)))
- (throw 'init-format-error))
-
-
- (if (not (equal? #f (object-property symbol 'translation-doc)))
- (ly:error (_ "symbol ~S redefined" symbol)))
+ (if (not (equal? #f (object-property symbol 'translation-doc)))
+ (ly:error (_ "symbol ~S redefined" symbol)))
(set-object-property! symbol 'translation-type? type?)
(set-object-property! symbol 'translation-doc description)
"If true, then the accidentals are aligned in bass figure context.")
(allowBeamBreak ,boolean? "If true allow line breaks for beams over bar lines.")
+ (allowPageTurn ,pair? "In the form (moment-start . penalty). Allow a page turn
+at the most recent breakpoint if it was after moment-start.")
(associatedVoice ,string? "Name of the
@code{Voice} that has the melody for this @code{Lyrics} line.")
(autoBeamSettings ,list? "Specifies
symbol @samp{hihat}) as key, and a list (@var{notehead-style}
@var{script} @var{vertical-position}) as values.
")
- (currentBarNumber ,integer? "Contains the current barnumber. This property is incremented at every bar line. ")
+ (currentBarNumber ,integer? "Contains the current barnumber. This property is incremented at
+every bar line.
+")
(defaultBarType ,string? "Sets the default type of bar line.
See @code{whichBar} for information on available bar types.
highest pitch on the instrument. This used by the automatic string
selector for tab notation.")
- (ignoreFiguredBassRest ,boolean? "Don't swallow rest events.")
(ignoreBarChecks ,boolean? "Ignore bar checks")
(ignoreMelismata ,boolean? "Ignore melismata for this @internalsref{Lyrics} line.")
(implicitBassFigures ,list? "List of bass figures that are not
printed as numbers, but only as extender lines.")
+ (instr ,markup? "See @code{instrument}")
- (instrumentCueName ,markup? "Name to print if another instrument is to be taken.")
- (instrumentName ,markup? "The name to print left of a staff. The
+ (instrument ,markup? "The name to print left of a staff. The
@code{instrument} property labels the staff in the first system, and
the @code{instr} property labels following lines.")
(instrumentEqualizer ,procedure? "
the instrument. Its value is the pitch that sounds like middle C. This
is used to transpose the MIDI output, and @code{\\quote}s.")
- (internalBarNumber ,integer? "Contains the current barnumber. This property is used for internal timekeeping, among others by the @code{Accidental_engraver}.")
-
(keepAliveInterfaces ,list? "List of symbols, signifying grob interfaces that
are worth keeping an staff with @code{remove-empty} set around for.")
(keyAlterationOrder ,list? " Alist that defines in what order
(midiMaximumVolume ,number? "Analogous to @code{midiMinimumVolume}.")
(minimumFret ,number? "The tablature auto string-selecting mechanism
selects the highest string with a fret at least @code{minimumFret}")
- (minimumPageTurnLength ,ly:moment? "Minimum length of a rest for a page turn to be allowed")
- (minimumRepeatLengthForPageTurn ,ly:moment? "Minimum length of a repeated section for a page
-turn to be allowed within that section")
(minimumVerticalExtent ,number-pair? "minimum vertical extent, same
format as @var{verticalExtent}")
- (output ,ly:music-output? "The output produced by a score-level translator during music interpretation")
(ottavation ,string? "If set, the text for an ottava spanner. Changing
this creates a new text spanner. ")
(pedalSustainStrings ,list? "List of string to print for
than this, a number is printed. ")
(shapeNoteStyles ,vector? "Vector of symbols, listing style for each note
head relative to the tonic (qv.) of the scale.")
- (shortInstrumentName ,markup? "See @code{instrument}")
- (shortVocalName ,markup? "Name of a vocal line, short version.")
(skipBars ,boolean? "If set to true, then
skip the empty bars that are produced by multimeasure notes and rests.
These bars will not appear on the printed output. If not set (the
(tupletFullLength ,boolean? "If set, the tuplet is printed up to
the start of the next note.")
- (tupletFullLengthNote ,boolean? "If set, end at the next note, otherwise end on the matter (time sigs, etc.) before the note.")
+ (tupletNumberFormatFunction
+ ,procedure?
+ "Function taking a music as input, producing a string. This function
+is called to determine the text to print on a tuplet bracket.")
+
(tupletSpannerDuration ,ly:moment? "
Normally a tuplet bracket is as wide as the
@code{\\times} expression that gave rise to it. By setting this
vertical spacing of systems.")
(vocalName ,markup? "Name of a vocal line.")
+ (vocNam ,markup? "Name of a vocal line, short version.")
(voltaOnThisStaff ,boolean?
"Normally, volta brackets are put only on the
This will create a start-repeat bar in this staff only.
Valid values are described in @internalsref{bar-line-interface}.
")
- (tempoWholesPerMinute ,ly:moment? "The tempo in whole notes per minute.")
- (tempoUnitDuration ,ly:duration? "Unit for specifying tempo.")
- (tempoUnitCount ,number? "Count for specifying tempo.")
-
)))
(define-public all-internal-translation-properties
(use-modules (srfi srfi-1))
-;; Event class hierarchy. Each line is on the form (Parent . (List of children))
+;; Event class hierarchy. Each line is on the form ((List of children) . Parent)
(define event-classes
- '((() . (StreamEvent))
- (StreamEvent .
- (RemoveContext ChangeParent Override Revert UnsetProperty
- SetProperty music-event OldMusicEvent CreateContext Prepare
- OneTimeStep Finish))
- (music-event . (arpeggio-event breathing-event extender-event span-event
- rhythmic-event dynamic-event break-event percent-event
- key-change-event string-number-event tie-event part-combine-event
- beam-forbid-event script-event
- tremolo-event bend-after-event fingering-event glissando-event
- harmonic-event hyphen-event laissez-vibrer-event mark-event
- multi-measure-text-event note-grouping-event
- pes-or-flexa-event repeat-tie-event spacing-section-event
- layout-instruction-event))
- (layout-instruction-event . (apply-output-event))
- (script-event . (articulation-event text-script-event))
- (part-combine-event . (solo-one-event solo-two-event unisono-event))
- (break-event . (line-break-event page-break-event page-turn-event))
- (dynamic-event . (absolute-dynamic-event))
- (span-event . (span-dynamic-event beam-event ligature-event
- pedal-event phrasing-slur-event slur-event staff-span-event
- text-span-event trill-span-event tremolo-span-event
- tuplet-span-event))
- (span-dynamic-event . (decrescendo-event crescendo-event))
- (pedal-event . (sostenuto-event sustain-event una-corda-event))
- (rhythmic-event . (lyric-event melodic-event multi-measure-rest-event
- rest-event skip-event bass-figure-event))
- (melodic-event . (cluster-note-event note-event))
- (() . (Announcement))
- (Announcement . (AnnounceNewContext))
+ '(((StreamEvent) . '())
+ ((RemoveContext ChangeParent Override Revert UnsetProperty SetProperty
+ MusicEvent CreateContext Prepare OneTimeStep Finish) . StreamEvent)
))
;; Maps event-class to a list of ancestors (inclusive)
-(define ancestor-lookup (make-hash-table 11))
+;; TODO: use resizable hash
+(define ancestor-lookup (make-hash-table 1))
;; Each class will be defined as
;; (class parent grandparent .. )
(lambda (rel)
(for-each
(lambda (type)
- (hashq-set! ancestor-lookup type
- (cons type (hashq-ref ancestor-lookup (car rel) '()))))
- (cdr rel)))
+ (hashq-set! ancestor-lookup type (cons type (hashq-ref ancestor-lookup (cdr rel) '())))) ;; `(define ,type (cons ',type ,(cdr rel)))))
+ (car rel)))
event-classes)
;; TODO: Allow entering more complex classes, by taking unions.
(define-public (ly:make-event-class leaf)
(hashq-ref ancestor-lookup leaf))
-
-(define-public (ly:in-event-class? ev cl)
- "Does event @var{ev} belong to event class @var{cl}?"
- (memq cl (ly:make-event-class (ly:event-property ev 'class))))
-
-;; does this exist in guile already?
-(define (map-tree f t)
- (cond
- ((list? t)
- (map (lambda (x) (map-tree f x)) t))
- ((pair? t)
- (cons (map-tree f (car t)) (map-tree f (cdr t))))
- (else (f t))))
-
-;; expand each non-leaf subtree to (root . children), recursively
-(define (expand-event-tree root)
- (let ((children (assq root event-classes)))
- (if children
- (cons root (map expand-event-tree (cdr children)))
- root)))
-
-;; All leaf event classes that no translator listens to
-;; directly. Avoids printing a warning.
-(define unlistened-music-event-classes
- '(harmonic-event line-break-event page-break-event page-turn-event
- solo-one-event solo-two-event skip-event unisono-event))
-
-;; produce neater representation of music event tree.
-;; TODO: switch to this representation for the event-classes list?
-(define music-event-tree (expand-event-tree 'music-event))
-(define (sort-tree t)
- (define (stringify el)
- (if (symbol? el)
- (symbol->string el)
- (symbol->string (first el))))
- (if (list? t)
- (sort (map (lambda (el)
- (if (list? el)
- (cons (car el) (sort-tree (cdr el)))
- el))
- t)
- (lambda (a b) (string<? (stringify a) (stringify b))))
- t))
-
-;;(use-modules (ice-9 pretty-print))
-;;(pretty-print (cons (car music-event-tree) (sort-tree (cdr music-event-tree))))
-
-;; check that the music event tree corresponds well with the set of
-;; available translators; print warnings otherwise.
-(map-tree (lambda (sym)
- (if (and (symbol? sym)
- (not (ly:is-listened-event-class sym))
- (not (assq sym event-classes))
- (not (memq sym unlistened-music-event-classes)))
- (ly:programming-error (_ "event class ~A seems to be unused") sym)))
- music-event-tree)
-
-(map (lambda (sym)
- (if (not (pair? (ly:make-event-class sym)))
- ;; should be programming-error
- (ly:error (_ "translator listens to nonexisting event class ~A") sym)))
- (ly:get-listened-event-classes))
+;; (primitive-eval leaf))
(defmacro-public make-stream-event (expr)
(Stream_event::undump (primitive-eval (list 'quasiquote expr))))
((pair? e) (cons (simplify (car e))
(simplify (cdr e))))
((ly:stream-event? e)
- (list 'unquote (list 'make-stream-event (simplify (Stream_event::dump e)))))
+ (list 'unquote `(make-stream-event ,(simplify (Stream_event::dump e)))))
((ly:music? e)
(list 'unquote (music->make-music e)))
((ly:moment? e)
(#t e)))
(define-public (ly:simplify-scheme e)
- (list 'quasiquote (simplify e)))
+ (list 'quasiquote (simplify e))
+)
+; used by lily/dispatcher.cc
+(define-public (car< a b) (< (car a) (car b)))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
"A bass figure text"
'(implicit))
-(ly:add-interface
- 'bend-after-interface
- "A doit or drop."
- '(thickness delta-position))
-
(ly:add-interface
'bass-figure-alignment-interface
""
"A fingering instruction"
'())
+(ly:add-interface
+ 'string-number-interface
+ "A string number instruction"
+ '())
+
(ly:add-interface
'fret-diagram-interface
"A fret diagram"
'(align-dir barre-type dot-color dot-radius finger-code fret-count
label-dir number-type size string-count thickness))
-(ly:add-interface
- 'grace-spacing-interface
- "Keep track of durations in a run of grace notes."
- '(columns common-shortest-duration))
-
(ly:add-interface
'ligature-interface
"A ligature"
are interesting enough to maintain a hara-kiri staff."
'())
-
-(ly:add-interface
- 'spacing-options-interface
- "Supports setting of spacing variables"
- '(spacing-increment shortest-duration-space))
-
(ly:add-interface
'stanza-number-interface
"A stanza number, to be put in from of a lyrics line"
'())
-(ly:add-interface
- 'string-number-interface
- "A string number instruction"
- '())
-
(ly:add-interface
'system-start-text-interface
"A text at the beginning of a system."
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (define-grob-property symbol type? description)
line).")
(default-direction ,ly:dir? "Direction determined by note head positions.")
- (direction ,ly:dir? "If side-position is 1 (#X), then this property determines if the object is placed #LEFT, #CENTER or #RIGHT with respect to the other object. Otherwise, it determines if the object is placed #UP #CENTER or #DOWN. Numerical values may also be used. #UP=1, #DOWN=-1, #LEFT=-1, #RIGHT=1, CENTER=0 but also other numerical values are permitted.")
+ (direction ,ly:dir? "#UP or #DOWN, #LEFT or #RIGHT? (or a numerical value, #UP=1, #DOWN=-1, #LEFT=-1, #RIGHT=1, CENTER=0)")
(dot-color ,symbol? "Color of dots. Options include
@code{black} and @code{white}.")
(font-shape ,symbol? "Select the shape of a font. Choices include @code{upright},
@code{italic}, @code{caps}.")
- (forced ,boolean? "manually forced accidental")
(forced-distance ,ly:dimension? "A fixed distance between object
reference points in an alignment.")
property.")
(gap ,ly:dimension? "Size of a gap in a variable symbol.")
(gap-count ,integer? "Number of gapped beams for tremolo.")
+ (grace-space-factor ,number? "Space grace notes at this fraction
+of the @code{spacing-increment}.")
+
(grow-direction ,ly:dir? "Crescendo or decrescendo?")
(hair-thickness ,number? "Thickness of the thin line in a bar line.")
(head-direction ,ly:dir? "Are the note heads left or right in a semitie?")
Choices are @code{around}, @code{inside}, @code{outside}. If unset, script
and slur ignore eachother.")
(inspect-quants ,number-pair? "If debugging is set,
-set beam/slur quant to this position, and print the respective scores.")
- (inspect-index ,integer? "If debugging is set,
-set beam/slur configuration to this index, and print the respective scores.")
+set beam quant to this position, and print the respective scores.")
(implicit ,boolean? "Is this an implicit bass figure?")
(keep-inside-line ,boolean? "If set, this column cannot have
things sticking into the margin.")
sum of 2 numbers. The first is the factor for line thickness, and the
second for staff space. Both contributions are added.")
(left-padding ,ly:dimension? "The amount of space that is put
-left to an object (eg. a group of accidentals).")
+left to a group of accidentals.")
+
(length ,ly:dimension? "User override for the stem length of
unbeamed stems.")
(length-fraction ,number? "Multiplier for lengths. Used for
(remove-empty ,boolean? "If set, remove group if it contains no
@code{interesting-items}")
(remove-first ,boolean? "Remove the first staff of a orchestral score?")
- (right-padding ,ly:dimension? "Space to insert on the right side of an object (eg. between note and its accidentals.)")
+ (right-padding ,ly:dimension? "Space to insert between note and
+accidentals.")
(rotation ,list? "Number of degrees to rotate this object, and what point
to rotate around. #'(45 0 0) means rotate 45 degrees around the center of this object.")
(same-direction-correction ,number? "Optical correction amount
Y axis.")
(shorten-pair ,number-pair? "The lengths to shorten a
-text-spanner on both sides, for example a pedal bracket. Positive values
-shorten the text-spanner, while negative values lengthen it.")
+text-spanner on both sides, for example a pedal bracket")
(clip-edges ,boolean? "Allow outward pointing beamlets at the edges of beams?")
(common-shortest-duration ,ly:moment?
"The most common shortest note length.
"Multiply direction of
@code{direction-source} with this to get the direction of this
object.")
- (side-axis ,number? "If the value is #X (or equivalently 1), the object is placed horizontally next to the other object. If the value is #Y or 0, it is placed vertically.")
+ (side-axis ,number? "Is this object horizontally or vertically next to another object?")
(size ,number? "Size of object, relative to standard size.")
(slope ,number? "The slope of this object.")
(slur-padding ,number? "Extra distance between slur and script.")
stems that are placed in tight configurations. For opposite
directions, this amount is the correction for two normal sized stems
that overlap completely.")
- (stencil ,ly:stencil? "The symbol to print.")
(strict-note-spacing ,boolean? "If set, unbroken columns
with non-musical material (clefs, barlines, etc.) are not spaced
separately, but put before musical columns.")
- (strict-grace-spacing ,boolean? "If set, grace notes
-are not spaced separately, but put before musical columns.")
(string-count ,integer? "The number of strings in a fret diagram.")
(stroke-style ,string? "set to \"grace\" to turn stroke through flag on.")
(apply define-internal-grob-property x))
`(
- (pure-relevant-elements ,ly:grob-array? "The subset of elements that are relevant for finding the pure-Y-extent.")
- (cached-pure-extents ,vector? "Used by a VerticalAxisGroup to cache the Y-extents of different column ranges.")
- (common-refpoint-of-elements ,ly:grob? "Caches the common_refpoint_of_array of the elements grob-set")
(axis-group-parent-X ,ly:grob? "Containing X axis group")
(axis-group-parent-Y ,ly:grob? "Containing Y axis group")
(accidental-grobs ,list? "Alist with (NOTENAME . GROBLIST) entries")
(dot ,ly:grob? "reference to Dots object.")
(dots ,ly:grob-array? "multiple Dots objects.")
(figures ,ly:grob-array? "Figured bass objects for continuation line.")
- (important-column-ranks ,vector? "Cache of columns that contain items-worth-living.")
(glyph-name ,string? "a name of character within font.")
(pedal-text ,ly:grob? "Pointer to the text of a mixed-style piano pedal.")
(stem ,ly:grob? "pointer to Stem object.")
in addition to notes and stems.")
(elements ,ly:grob-array? "list of grobs, type depending on the Grob
where this is set in.")
- (grace-spacing ,ly:grob? "a run of grace notes.")
- (spacing ,ly:grob? "the spacing spanner governing this section.")
(heads ,ly:grob-array? "List of note heads.")
(items-worth-living ,ly:grob-array? "A list of interesting items. If
empty in a particular staff, then that staff is erased.")
(positioning-done ,boolean?
"Used to signal that a positioning element
did its job. This ensures that a positioning is only done once.")
- (pure-Y-extent ,number-pair? "The estimated height of a system")
(script-stencil ,pair? "Pair (@code{type} . @code{arg}), which
;;; the next note could be seen
(join-right-amount ,number? "")
- (delta-position ,number? "vertical position difference")
+ (delta-pitch ,number? "the interval between this and the next note, or, more precisely, their vertical distance; this is used in ligatures for calculation of the height of vertical joins flexa shapes")
(head-width ,ly:dimension? "width of this ligature head")
;; [TODO: change this]
(primitive ,integer? "Pointer to a ligature primitive, i.e. an item similar to a note head that is part of a ligature. ")
+ (stencil ,ly:stencil? "The symbol to print.")
(ideal-distances ,list? "(@var{obj} . (@var{dist} . @var{strength})) pairs.")
(minimum-distances ,list? "list of rods, that have the format (@var{obj} . @var{dist}).")
;;;;;;; TODO:
;; there are too many properties for ancient notation
;; probably neume-types (a list of symbols) would also work.
-
- ;; However, such this list would consist of a couple of dozens of
- ;; entries, since head prefixes may be combined in many ways. If
- ;; the macros in gregorian-init.ly would directly set prefix-set,
- ;; all the head prefixes could be junked; however, such macros
- ;; would be quite numerous, I guess. --jr
-
- (auctum ,boolean? "is this neume liquescentically augmented?")
- (ascendens ,boolean? "is this neume of an ascending type?")
+
+ (auctum ,boolean? "is this neume augmented?")
+ (ascendens ,boolean? "is this neume of an ascending?")
(add-cauda ,boolean? "does this flexa require an additional cauda on the left side?")
(add-join ,boolean? "is this ligature head joined with the next one by a vertical line?")
(cavum ,boolean? "is this neume outlined?")
(flexa-width ,ly:dimension? "width of a flexa shape in a ligature grob in staff_space.")
(join-heads ,boolean? "Whether to join the note heads of an ambitus grob with a vertical line.")
(linea ,boolean? "attach vertical lines to this neume?")
+
+
(add-stem ,boolean? "is this ligature head a virga and therefore needs an additional stem on the right side?")
- (context-info ,integer? "Within a ligature, the final glyph or shape of a head may be affected by the left and/or right neighbour head. context-info holds for each head such information about the left and right neighbour, encoded as a bit mask.")
+ (context-info ,integer? "DOCME")
(inclinatum ,boolean? "is this neume an inclinatum?")
(oriscus ,boolean? "is this neume an oriscus?")
(quilisma ,boolean? "is this neume a quilisma?")
(pes-or-flexa ,boolean? "shall this neume be joined with the previous head?")
- (prefix-set ,number? "a bit mask that holds all Gregorian head prefixes, such as @code{\\virga} or @code{\\quilisma}")
+ ;; DOCME
+ (prefix-set ,number? "")
(stropha ,boolean? "Is this neume a stropha?")
(virga ,boolean? "Is this neume a virga?")
(x-offset ,ly:dimension? "Extra horizontal offset for ligature heads.")
-
+
;; end ancient notation
)))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
;;;; distances are given in line-thickness (thicknesses) and
. (
(axes . (0 1))
(X-extent . ,ly:axis-group-interface::width)
- (Y-extent . ,ly:axis-group-interface::height)
+ (X-extent . ,ly:axis-group-interface::height)
(space-alist . (
(clef . (extra-space . 0.5))
(key-signature . (extra-space . 0.0))
. (
(break-align-symbol . staff-bar)
(glyph . "|")
- (gap . 0.4)
(layer . 0)
(break-visibility . ,all-visible)
(non-musical . #t)
(list ly:self-alignment-interface::x-aligned-on-self)))))
(self-alignment-X . 1)
-
- ;; want the bar number before the clef at line start.
(break-align-symbol . left-edge)
(meta .
((class . Item)
(interfaces . (staff-symbol-referencer-interface
beam-interface))))))
- (BendAfter
- . (
- (stencil . ,fall::print)
- (thickness . 2.0)
- (meta . ((class . Spanner)
- (interfaces . (spanner-interface
- bend-after-interface))))))
-
(BreakAlignment
. (
(non-musical . #t)
(Dots
. (
(stencil . ,ly:dots::print)
- (dot-count . ,dots::calc-dot-count)
+ (dot-count . 1)
(meta . ((class . Item)
(interfaces . (font-interface
staff-symbol-referencer-interface
(meta . ((class . Spanner)
(interfaces . (font-interface
text-interface
- line-spanner-interface
dynamic-interface
dynamic-text-spanner-interface
spanner-interface))))))
-
(Fingering
. (
(stencil . ,ly:text-interface::print)
(direction . ,ly:script-interface::calc-direction)
- (text . ,fingering::calc-text)
+
(font-encoding . fetaNumber)
(font-size . -5) ; don't overlap when next to heads.
(meta . ((class . Item)
(interfaces . (line-interface
line-spanner-interface))))))
- (GraceSpacing
- . (
- (common-shortest-duration . ,grace-spacing::calc-shortest-duration)
- (spacing-increment . 0.8)
- (shortest-duration-space . 1.6)
- (meta . ((class . Spanner)
- (interfaces . (grace-spacing-interface
- spacing-interface
- spacing-options-interface
- spanner-interface))))))
(GridPoint
. (
(X-extent . (0 . 0))
(stencil . ,ly:hairpin::print)
(springs-and-rods . ,ly:spanner::set-spacing-rods)
(after-line-breaking . ,ly:hairpin::after-line-breaking)
- (grow-direction . ,hairpin::calc-grow-direction)
(circled-tip . #f)
(thickness . 1.0)
(height . 0.6666)
side-position-interface
font-interface))))))
- (InstrumentSwitch
- . (
- (padding . 0.3)
- (stencil . ,ly:text-interface::print)
- (Y-offset . ,ly:side-position-interface::y-aligned-side)
- (X-offset . ,ly:self-alignment-interface::x-aligned-on-self)
- (staff-padding . 2)
- (direction . ,UP)
- (self-alignment-X . ,CENTER)
- (meta . ((class . Item)
- (interfaces . (system-start-text-interface
- side-position-interface
- font-interface))))))
-
(KeyCancellation
. (
(stencil . ,ly:key-signature-interface::print)
(NoteHead
. (
(stencil . ,ly:note-head::print)
- (duration-log . ,note-head::calc-duration-log)
(stem-attachment . ,ly:note-head::calc-stem-attachment)
(glyph-name . ,note-head::calc-glyph-name)
(Y-offset . ,ly:staff-symbol-referencer::callback)
(non-musical . #t)
(line-break-permission . allow)
- (page-break-permission . allow)
;; debugging stuff: print column number.
;; (font-size . -6) (font-name . "sans") (Y-extent . #f)
(Rest
. (
(stencil . ,ly:rest::print)
- (duration-log . ,note-head::calc-duration-log)
(X-extent . ,ly:rest::width)
(Y-extent . ,ly:rest::height)
(Y-offset . ,ly:rest::y-offset-callback)
. (
;; don't set direction here: it breaks staccato.
- ;; padding set in script definitions.
+ ;; This value is sensitive: if too large, staccato dots will move a
+ ;; space a away.
+ (padding . 0.20)
(staff-padding . 0.25)
;; (script-priority . 0) priorities for scripts, see script.scm
(X-offset . , ly:self-alignment-interface::centered-on-x-parent)
+
(stencil . ,ly:script-interface::print)
(direction . ,ly:script-interface::calc-direction)
(meta . ((class . Spanner)
(interfaces . (slur-interface))))))
- (SostenutoPedal
+ (SostenutoPedal
. (
(stencil . ,ly:text-interface::print)
(direction . ,RIGHT)
(SpacingSpanner
. (
(springs-and-rods . ,ly:spacing-spanner::set-springs)
- (common-shortest-duration . ,ly:spacing-spanner::calc-common-shortest-duration)
(average-spacing-wishes . #t)
+ (grace-space-factor . 0.6)
(shortest-duration-space . 2.0)
(spacing-increment . 1.2)
-
(base-shortest-duration . ,(ly:make-moment 3 16))
(meta . ((class . Spanner)
(interfaces . (spacing-interface
- spacing-options-interface
spacing-spanner-interface))))))
(SpanBar
(Stem
. (
(direction . ,ly:stem::calc-direction)
- (duration-log . ,note-head::calc-duration-log)
(default-direction . ,ly:stem::calc-default-direction)
(stem-end-position . ,ly:stem::calc-stem-end-position)
(neutral-direction . ,DOWN)
(StringNumber
. (
(stencil . ,print-circled-text-callback)
- (text . ,string-number::calc-text)
(padding . 0.5)
(staff-padding . 0.5)
(self-alignment-X . 0)
(meta . ((class . Item)
(interfaces . (piano-pedal-interface
text-spanner-interface
- line-spanner-interface
text-interface
self-alignment-interface
font-interface))))))
. (
(stencil . ,ly:text-interface::print)
(Y-offset . ,ly:staff-symbol-referencer::callback)
- (duration-log . ,note-head::calc-duration-log)
(font-size . -2)
(stem-attachment . (0.0 . 1.35))
(font-series . bold)
(direction . ,UP)
(meta . ((class . Spanner)
(interfaces . (text-spanner-interface
- line-spanner-interface
side-position-interface
font-interface))))))
(Tie
. (
(control-points . ,ly:tie::calc-control-points)
- (springs-and-rods . ,ly:spanner::set-spacing-rods)
(avoid-slur . inside)
(direction . ,ly:tie::calc-direction)
(stencil . ,ly:tie::print)
(outer-tie-vertical-gap . 0.25)
(multi-tie-region-size . 1)
(between-length-limit . 1.0)))
-
(thickness . 1.2)
(line-thickness . 0.8)
(meta . ((class . Spanner)
(side-axis . ,Y)
(meta . ((class . Spanner)
(interfaces . (text-spanner-interface
- line-spanner-interface
side-position-interface
font-interface))))))
(stencil . ,ly:accidental-interface::print)
(meta . ((class . Item)
(interfaces . (item-interface
+ accidental-interface
side-position-interface
font-interface))))))
(edge-height . (0.7 . 0.7))
(shorten-pair . (-0.2 . -0.2))
(staff-padding . 0.25)
+
(direction . ,ly:tuplet-bracket::calc-direction)
(positions . ,ly:tuplet-bracket::calc-positions)
(connect-to-neighbor . ,ly:tuplet-bracket::calc-connect-to-neighbors)
(TupletNumber
. (
(stencil . ,ly:tuplet-number::print)
- (text . ,tuplet-number::calc-denominator-text)
(font-shape . italic)
(font-size . -2)
(avoid-slur . inside)
(Y-extent . ,ly:axis-group-interface::height)
(X-extent . ,ly:axis-group-interface::width)
(stacking-dir . -1)
- (padding . 0.1)
(meta . ((class . Spanner)
(interfaces . (align-interface
axis-group-interface))))))
(set! all-grob-descriptions (sort all-grob-descriptions alist<?))
-(define pure-print-callbacks
- (list
- `(,ly:note-head::print . '())
- `(,ly:clef::print . '())
- `(,ly:text-interface::print . '())
- `(,ly:script-interface::print . '())))
-
-;; ly:grob::stencil-extent is safe iff the print callback is safe too
-(define (pure-stencil-height grob start stop)
- (let ((sten (ly:grob-property-data grob 'stencil)))
- (if (or
- (ly:stencil? sten)
- (pair? (assq sten pure-print-callbacks)))
- (ly:grob::stencil-height grob)
- '(0 . 0))))
-
-(define pure-Y-extents
- (list
- `(,ly:staff-symbol::height . ())))
-
-(define Y-extent-conversions
- (list
- `(,ly:stem::height . ,ly:stem::pure-height)
- `(,ly:grob::stencil-height . ,pure-stencil-height)
- `(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)
- `(,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height)
- `(,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height)
- `(,ly:slur::height . ,ly:slur::pure-height)))
-
-(define pure-Y-offsets
- (list
- `(,ly:staff-symbol-referencer::callback . ())))
-
-(define Y-offset-conversions
- (list
- `(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side)))
-
-(define-public (pure-relevant grob)
- (let ((extent-callback (ly:grob-property-data grob 'Y-extent)))
- (or
- (pair? extent-callback)
- (pair? (assq extent-callback pure-Y-extents))
- (and
- (pair? (assq extent-callback Y-extent-conversions))
- (or
- (not (eq? extent-callback ly:grob::stencil-height))
- (pair? (assq (ly:grob-property-data grob 'stencil) pure-print-callbacks))
- (ly:stencil? (ly:grob-property-data grob 'stencil)))))))
-
-(define (pure-conversion pures conversions defsymbol defreturn rettype? grob start stop)
- (let* ((normal-callback (ly:grob-property-data grob defsymbol))
- )
-
- (if (rettype? normal-callback)
- normal-callback
- (if (pair? (assq normal-callback pures))
- (normal-callback grob)
- (let
- ((pure-callback (assq normal-callback conversions)))
-
- (if (pair? pure-callback)
- ((cdr pure-callback) grob start stop)
- defreturn))))))
-
-(define-public (pure-Y-extent grob start stop)
- (pure-conversion pure-Y-extents Y-extent-conversions
- 'Y-extent '(0 . 0) pair? grob start stop))
-
-(define-public (pure-Y-offset grob start stop)
- (pure-conversion pure-Y-offsets Y-offset-conversions
- 'Y-offset 0 number? grob start stop))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define-markup-command (whiteout layout props arg) (markup?)
"Provide a white underground for @var{arg}"
- (let* ((stil (interpret-markup layout props arg))
+ (let* ((stil (interpret-markup layout props
+ (make-with-color-markup black arg)))
(white
(interpret-markup layout props
(make-with-color-markup
(text-width (apply + text-widths))
(text-dir (chain-assoc-get 'text-direction props RIGHT))
(word-count (length stencils))
- (word-space (chain-assoc-get 'word-space props 1))
- (prop-line-width (chain-assoc-get 'line-width props #f))
- (line-width (if prop-line-width prop-line-width
- (ly:output-def-lookup layout 'line-width)))
+ (word-space (chain-assoc-get 'word-space props))
+ (line-width (chain-assoc-get 'line-width props))
(fill-space
(cond
((= word-count 1)
(define (wordwrap-markups layout props args justify)
(let*
((baseline-skip (chain-assoc-get 'baseline-skip props))
- (prop-line-width (chain-assoc-get 'line-width props #f))
- (line-width (if prop-line-width prop-line-width
- (ly:output-def-lookup layout 'line-width)))
+ (line-width (chain-assoc-get 'line-width props))
(word-space (chain-assoc-get 'word-space props))
(text-dir (chain-assoc-get 'text-direction props RIGHT))
(lines (wordwrap-stencils
(define-markup-command (char layout props num) (integer?)
"Produce a single character, e.g. @code{\\char #65} produces the
letter 'A'."
+ (ly:get-glyph (ly:paper-get-font layout props) num))
- (ly:text-interface::interpret-markup layout props (ly:wide-char->utf-8 num)))
(define number->mark-letter-vector (make-vector 25 #\A))
(define post-event? (make-music-type-predicate
'StringNumberEvent
'ArticulationEvent
- 'FingeringEvent
+ 'FingerEvent
'TextScriptEvent
'MultiMeasureTextEvent
'HyphenEvent
((portato) "_")
(else (format #f "\\~a" articulation)))))
-(define-post-event-display-method FingeringEvent (event) #t
+(define-post-event-display-method FingerEvent (event) #t
(ly:music-property event 'digit))
(define-post-event-display-method TextScriptEvent (event) #t
;; command_element
(format #f "~{~a ~}" (map-in-order music->lily-string elements))))))))
-(define-display-method MultiMeasureRestMusic (mmrest)
- (let* ((dur (ly:music-property mmrest 'duration))
- (ly (format #f "R~a~{~a ~}"
- (duration->lily-string dur)
- (map-in-order music->lily-string
- (ly:music-property mmrest 'articulations)))))
- (*previous-duration* dur)
- ly))
+(define-display-method MultiMeasureRestMusicGroup (mmrest)
+ (format #f "~{~a ~}"
+ (map-in-order music->lily-string
+ (remove (make-music-type-predicate 'BarCheck)
+ (ly:music-property mmrest 'elements)))))
(define-display-method SkipMusic (skip)
(format #f "\\skip ~a" (duration->lily-string (ly:music-property skip 'duration) #:force-duration #t)))
(define-display-method MetronomeChangeEvent (tempo)
(format #f "\\tempo ~a = ~a"
- (duration->lily-string (ly:music-property tempo 'tempo-unit) #:force-duration #t #:prev-duration #f)
+ (duration->lily-string (ly:music-property tempo 'tempo-unit) #:force-duration #f #:prev-duration #f)
(ly:music-property tempo 'metronome-count)))
(define-display-method KeyChangeEvent (key)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (music-property-description symbol type? description)
(map
(lambda (x) (apply music-property-description x))
`(
- (alteration ,number? "alteration for figured bass")
+ (iterator-ctor ,procedure? "Function to construct music-event-iterator object for this Music")
+ (duration ,ly:duration? "Duration of this note/lyric.")
+ (metronome-count ,number? "How many beats in a minute?")
+ (span-type ,string? "What kind of spanner should be created?
+TODO: consider making type into symbol")
(absolute-octave ,integer?
"The absolute octave for a octave check note.")
(articulations ,ly:music-list?
(augmented ,boolean? "This figure is for an augmented figured bass (with +) sign.")
(associated-context ,string? "Name of the Voice context associated with this \\newaddlyrics section")
(bass ,boolean? "Set if this note is a bass note in a chord")
- (bracket-start ,boolean? "start a bracket
-here. TODO: use SpanEvents?")
- (bracket-stop ,boolean? "stop a bracket here.")
(break-penalty ,number? "Penalty for line break hint.")
(break-permission ,symbol? "Whether to allow, forbid or force a line break.")
(cautionary ,boolean? "If set, this alteration needs cautionary accidental")
(compress-procedure ,procedure? "compress this music expression. Argument 1: the music, arg 2: factor")
(context-id ,string? "name of context")
(context-type ,symbol? "type of context")
- (create-new ,boolean? "Create a fresh context.")
- (delta-step ,number? "How much should a fall change pitch?")
+ (create-new ,boolean? "Create a fresh context.")
(descend-only ,boolean? "If set, this @code{\\context} will only descend in the context tree.")
(denominator ,integer? "denominator in a time signature")
(digit ,integer? "digit for fingering")
(diminished ,boolean? "This bass figure should be slashed.")
(direction ,ly:dir? "Print this up or down?")
(drum-type ,symbol? "Which percussion instrument to play this note on.")
- (duration ,ly:duration? "Duration of this note/lyric.")
(error-found ,boolean? "If true, a parsing error was found in this expression")
(element ,ly:music? "The single child of a Music_wrapper music object, or the body of a repeat.")
(elements ,ly:music-list? "A list of elements for sequential of simultaneous music, or the alternatives of repeated music. ")
- (elements-callback ,procedure? "Return a list of children, for use by a sequential iterator. Takes a single Music parameter")
(expected-beam-count ,integer? "Expected number of non-tremolo beams in a tremolo repeat")
- (figure ,integer? "a bass figure")
(force-accidental ,boolean? "If set, a cautionary accidental should always be printed on this note")
(grob-property ,symbol? "The symbol of the grob property to set. ")
(grob-property-path ,list? "A list of symbols, locating a nested grob property, e.g. (beamed-lengths details). ")
(grob-value ,scheme? "The value of the grob property to set")
(input-tag ,scheme? "Arbitrary marker to relate input and output")
(inversion ,boolean? "If set, this chord note is inverted.")
- (iterator-ctor ,procedure? "Function to construct music-event-iterator object for this Music")
-
(label ,markup? "label of a mark.")
(last-pitch ,ly:pitch? "The last pitch after relativization.")
(length ,ly:moment? "The duration of this music")
(length-callback ,procedure? "How to compute the duration of this music. This property can only be defined as initializer in @file{define-music-types.scm}.")
- (metronome-count ,number? "How many beats in a minute?")
(name ,symbol? "Name of this music object")
(no-continuation ,boolean? "If set, disallow continuation lines")
(numerator ,integer? "numerator of a time signature")
(once ,boolean? "Apply this operation only during one time step?")
(octavation ,integer? "This pitch was octavated by how many octaves? For chord inversions, this is negative.")
(origin ,ly:input-location? "where was this piece of music defined?")
- (part-combine-status ,symbol?
- "Change to what kind of state? Options are
-solo1, solo2 and unisono")
(parenthesize ,boolean? "Enclose resulting objects in parentheses?")
(pitch ,ly:pitch? "the pitch of this note")
(pitch-alist ,list? "list of pitches jointly forming the scale of a key signature")
(pop-first ,boolean? "Do a revert before we try to do a override on some grob property.")
- (prob-property ,symbol? "The symbol of the prob property to set. ")
(procedure ,procedure?
"The function to run with \\applycontext.
It must take a single argument, being the context.")
(repeat-count ,integer? "do a @code{\repeat} how ofen?")
(span-direction ,ly:dir? "Does this start or stop a spanner?")
- (span-type ,string? "What kind of spanner should be created?
-
-TODO: consider making type into symbol")
(split-list ,list? "splitting moments for part combiner.")
(start-callback ,procedure? "Function to compute the negative
length of starting grace notes. This property can only be defined as
(void ,boolean? "If this property is #t, then the music expression is to be
discarded by the toplevel music handler.")
(what ,symbol? "What to change for auto-change. FIXME, naming")
+ (part-combine-status ,symbol?
+ "Change to what kind of state? Options are
+solo1, solo2 and unisono")
+
+ (figure ,integer? "a bass figure")
+ (alteration ,number? "alteration for figured bass")
+ (bracket-start ,boolean? "start a bracket
+here. TODO: use SpanEvents?")
+ (bracket-stop ,boolean? "stop a bracket here.")
(untransposable ,boolean? "If set, this music is not transposed.")
)))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
;; TODO: should link back into user manual.
-(define (mm-rest-child-list music)
- "Generate events for multimeasure rests, to be used by the sequential-iterator"
- (let ((location (ly:music-property music 'origin))
- (duration (ly:music-property music 'duration)))
- (list (make-music 'BarCheck
- 'origin location)
- (make-event-chord (cons (make-music 'MultiMeasureRestEvent
- 'origin location
- 'duration duration)
- (ly:music-property music 'articulations)))
- (make-music 'BarCheck
- 'origin location))))
-
(define-public music-descriptions
`(
(AbsoluteDynamicEvent
3. context where FUNC is called.
")
- (types . (general-music event apply-output-event))
+ (types . (general-music event layout-instruction))
))
(ArpeggioEvent
. (
c8-[ c c-] c8")
(types . (general-music event beam-event span-event))
))
- (BendAfterEvent
- . ((description . "A drop/fall/doit jazz articulation")
- (types . (general-music bend-after-event event))))
-
- (BreathingEvent
+ (BreakEvent
+ . (
+ (description . "Create a line break, Syntax: \\break or page break, Syntax: \\pagebreak.")
+
+ (types . (general-music break-event event))
+ ))
+ (BreathingSignEvent
. (
(description . "Creates a `breath mark' or `comma'.
(types . (general-music event breathing-event))
))
+ (BusyPlayingEvent
+ . (
+ (description . "Used internally to signal beginning and ending of notes.")
+
+ (types . (general-music event busy-playing-event))
+ ))
(ContextChange
. (
(description . "Change staffs in Piano staff.
... @var{note}\\rc (you can also use \\<, \\!, \\cresc, and
\\endcresc. See the user manual for details.).")
- (types . (general-music span-event span-dynamic-event crescendo-event event))
+ (types . (general-music dynamic-event crescendo-event event))
))
(DecrescendoEvent
. (
(description . "See @ref{CrescendoEvent}.")
- (types . (general-music span-event span-dynamic-event decrescendo-event event))
+ (types . (general-music dynamic-event decrescendo-event event))
))
(ExtenderEvent
(types . (general-music extender-event event))
))
- (Event
- . (
- (description . "Atomic music event.")
- (types . (general-music event))
- ))
-
+
(EventChord
. (
(description . "Internally used to group a set of events.")
(types . (general-music event-chord simultaneous-music))
))
-
- (FingeringEvent
+ (FingerEvent
. (
(description . "Specify what finger to use for this note.")
(types . (general-music fingering-event event))
(LineBreakEvent
. (
(description . "Allow, forbid or force a line break.")
- (types . (general-music line-break-event break-event event))
+ (types . (general-music break-event event))
))
(LyricCombineMusic
(types . (general-music mark-event event))
))
+ (MelismaPlayingEvent
+ . (
+ (description . "Used internally to signal melismas.")
+ (types . (general-music melisma-playing-event event))
+ ))
(ManualMelismaEvent
. (
(description . "Start or stop a melisma.
Syntax: @code{c4\\melisma d\\melismaEnd}.")
(types . (general-music melisma-span-event event))
))
-
- (MultiMeasureRestMusic
+
+ (MultiMeasureRestEvent
. (
(description . "Rests that may be compressed into Multi rests.
Syntax
-@code{R2.*4} for 4 measures in 3/4 time.")
- (iterator-ctor . ,ly:sequential-iterator::constructor)
- (elements-callback . ,mm-rest-child-list)
- (types . (general-music multi-measure-rest))
+@code{R2.*4} for 4 measures in 3/4 time. Note the capital R.")
+ (types . (general-music event rhythmic-event multi-measure-rest-event))
))
-
- (MultiMeasureRestEvent
+
+ (MultiMeasureRestMusicGroup
. (
- (description . "Used internally by MultiMeasureRestMusic to signal rests")
- (types . (general-music event rhythmic-event multi-measure-rest-event))
+ (description . "Like sequential-music, but specifically intended
+to group start-mmrest, skip, stop-mmrest sequence.
+
+Syntax @code{R2.*5} for 5 measures in 3/4 time.")
+ (length-callback . ,ly:music-sequence::cumulative-length-callback)
+ (start-callback . ,ly:music-sequence::first-start-callback)
+ (iterator-ctor . ,ly:sequential-music-iterator::constructor)
+ (types . (general-music sequential-music))
))
(MultiMeasureTextEvent
@code{\\override [ @var{Ctxt} . ] @var{Obj} @var{prop} = @var{val}}
")
- (types . (general-music layout-instruction-event override-property-event))
+ (types . (general-music layout-instruction))
(iterator-ctor . ,ly:push-property-iterator::constructor)
))
(PageBreakEvent
. (
(description . "Allow, forbid or force a page break.")
- (types . (general-music break-event page-break-event event))
+ (types . (general-music break-event event))
))
(PageTurnEvent
. (
(description . "Allow, forbid or force a page turn.")
- (types . (general-music break-event page-turn-event event))
+ (types . (general-music break-event event))
))
(PartCombineMusic
. (
(description . "Set a context property.
Syntax: @code{\\property @var{context}.@var{prop} = @var{scheme-val}}.")
- (types . (layout-instruction-event general-music))
+ (types . (layout-instruction general-music))
(iterator-ctor . ,ly:property-iterator::constructor)
))
. (
(description . "Remove the definition of a context @code{\\property}.")
- (types . (layout-instruction-event general-music))
+ (types . (layout-instruction general-music))
(iterator-ctor . ,ly:property-unset-iterator::constructor)
))
(description . "Ties for starting a second volta bracket.")
(types . (general-music event repeat-tie-event))
))
+ (Event
+ . (
+ (description . "Atomic music event.")
+ (types . (general-music event))
+ ))
+
(RestEvent
. (
(description . "A Rest.
previously added property from a graphical object definition
")
- (types . (general-music layout-instruction-event))
+ (types . (general-music layout-instruction))
(iterator-ctor . , ly:pop-property-iterator::constructor)
))
(length-callback . ,ly:music-sequence::cumulative-length-callback)
(start-callback . ,ly:music-sequence::first-start-callback)
- (elements-callback . ,(lambda (m) (ly:music-property m 'elements)))
- (iterator-ctor . ,ly:sequential-iterator::constructor)
+ (iterator-ctor . ,ly:sequential-music-iterator::constructor)
(types . (general-music sequential-music))
))
. (
(description . "Print Solo.1")
(part-combine-status . solo1)
- (types . (general-music event part-combine-event solo-one-event))
+ (types . (general-music event part-combine-event))
))
(SoloTwoEvent
. (
(description . "Print Solo.2")
(part-combine-status . solo2)
- (types . (general-music event part-combine-event solo-two-event))
+ (types . (general-music event part-combine-event))
))
(UnisonoEvent
. ((description . "Print a2")
(part-combine-status . unisono)
- (types . (general-music event part-combine-event unisono-event))))
+ (types . (general-music event part-combine-event))))
(SimultaneousMusic
. (
(types . (general-music event span-event staff-span-event))
))
+ (StartPlayingEvent
+ . (
+ (description . "Used internally to signal beginning of notes.")
+
+ (types . (general-music event start-playing-event))
+ ))
+
(TextSpanEvent
. (
(description . "Start a text spanner like 8va.....|")
(types . (time-scaled-music music-wrapper-music general-music))
))
- (TupletSpanEvent
+ (TupletEvent
. (
(description . "Used internally to signal where tuplet brackets start and stop.")
- (types . (tuplet-span-event span-event event general-music))
+ (types . (tuplet-spanner-event span-event event general-music))
))
(UnrelativableMusic
(types . (general-music event rhythmic-event skip-event))
))
-
- (SpacingSectionEvent
- . ((description . "Start a new spacing section")
- (types . (general-music event spacing-section-event))))
-
(SpanEvent
. (
(description . "Event for anything that is started at a different time than stopped.")
(SustainEvent
. (
(description . "Depress or release sustain pedal. ")
- (types . (general-music event pedal-event sustain-event))
+ (types . (general-music event pedal-event sustain-pedal-event))
))
(SostenutoEvent
. (
(description . "Depress or release sostenuto pedal. ")
- (types . (general-music event pedal-event sostenuto-event))
+ (types . (general-music event pedal-event sostenuto-pedal-event))
))
(UnaCordaEvent
. (
(description . "Depress or release una-corda pedal.")
- (types . (general-music event pedal-event una-corda-event))
+ (types . (general-music event pedal-event una-corda-pedal-event))
))
(StringNumberEvent
(types . (general-music string-number-event event))
))
+ (MetronomeChangeEvent
+ . (
+ (description . "Change tempo setting (in beats per minute).")
+ (types . (general-music metronome-change-event tempo-event event))
+ ))
+
(TextScriptEvent
. (
(description . "")
dashed-slur
dot
draw-line
- embedded-ps
glyph-string
named-glyph
- path
polygon
repeat-slash
- resetcolor
round-filled-box
- setcolor
text
url-link
utf-8-string
white-dot
white-text
+ embedded-ps
zigzag-line
+ setcolor
+ resetcolor
grob-cause
no-origin
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (interface-doc-string interface grob-description)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(use-modules
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (doc-markup-function func)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (music-props-doc)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(define (engraver-makes-grob? name-symbol grav)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
;;; File entry point for generated documentation
(display
(string-append
(texi-file-head "LilyPond program-reference" file-name
- "(lilypond/lilypond-internals.info)")
+ "(lilypond-internals.info)")
"
@c NOTE: This is documentation-generate.scm, not macros.itexi
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(use-modules (oop goops)
"\\input texinfo @c -*-texinfo-*-"
"\n@setfilename " file-name ".info"
"\n@settitle " name
- "\n@dircategory LilyPond"
+ "\n@dircategory GNU music project"
"\n@direntry"
;; prepend GNU for dir, must be unique
"\n* GNU " name ": (" file-name "). " name "."
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2005--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define cache-hash-tab (make-hash-table 11))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-module (scm framework-eps))
))
stencils))
-
(define (dump-stencils-as-EPSes stencils book basename)
- (define do-pdf (member "pdf" (ly:output-formats)))
(define paper (ly:paper-book-paper book))
(define (dump-infinite-stack-EPS stencils)
(let* ((dump-me (stack-stencils Y DOWN 2.0 stencils)))
(dump-stencil-as-EPS paper dump-me basename #t)))
- (define (dump-stencils-as-separate-EPS stencils count )
+ (define (dump-stencils-as-separate-EPS stencils count)
(if (pair? stencils)
(let* ((line (car stencils))
- (rest (cdr stencils))
- (system-base-name (format "~a-~a" basename count))
- )
+ (rest (cdr stencils)))
(dump-stencil-as-EPS
- paper line system-base-name
- (ly:get-option 'include-eps-fonts))
-
- (if do-pdf
- (postscript->pdf 0 0 (string-append system-base-name ".eps")))
+ paper line (format "~a-~a" basename count)
+ (ly:get-option 'eps-font-include))
+
(dump-stencils-as-separate-EPS rest (1+ count)))))
\\betweenLilyPondSystem{~a}
\\fi
" c) tex-system-port))
- (display (format "\\includegraphics{~a-~a}\n"
+ (display (format "\\includegraphics{~a-~a.eps}\n"
basename (1+ c)) tex-system-port)
(display (format "@image{~a-~a}\n"
basename (1+ c)) texi-system-port))
(display "@c eof - 'eof' is a Makefile marker; do not remove. " texi-system-port)
(display "% eof - 'eof' is Makefile marker; do not remove. " tex-system-port)
- (dump-infinite-stack-EPS stencils)
+ (dump-infinite-stack-EPS stencils))
(postprocess-output book framework-eps-module
- (format "~a.eps" basename) (ly:output-formats))))
+ (format "~a.eps" basename) (ly:output-formats)))
(output-scopes scopes fields basename)
(if (ly:get-option 'dump-signatures)
- (write-system-signatures basename (ly:paper-book-systems book) 1))
+ (write-system-signatures basename (ly:paper-book-systems book) 0))
(dump-stencils-as-EPSes
(map paper-system-stencil (ly:paper-book-systems book))
(define convert-to-tex convert-to-tex)
(define convert-to-dvi convert-to-dvi)
-
(define location-callback spawn-editor)
(define (get-location grob)
- (and-let* ((p (procedure? point-and-click))
+ (and-let* ((p? (procedure? point-and-click))
(g grob)
(cause (ly:grob-property grob 'cause))
- (music-origin (if (ly:event? cause)
- (ly:event-property cause 'origin)
- ;; How come #<unspecified> [and '()]
+ (music-origin (if (ly:music? cause)
+ (ly:music-property cause 'origin)
+ ;; How come #<unspecied> [and '()]
;; are #t? :-(
#f)))
(if (ly:input-location? music-origin)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-module (scm framework-ps))
"page-width output-scale lily-output-units mul mul 0 translate 90 rotate\n"
"")
"%%EndPageSetup\n"
-
- "true setstrokeadjust\n"
+
"gsave 0 paper-height translate "
"set-ps-scale-to-lily-scale "
"\n"))
(lambda (x y) (string<? (cadr x) (cadr y))))))
- (font-loader (if (ly:get-option 'gs-load-fonts)
+ (font-loader (if (ly:get-option 'gs-font-load)
load-font-via-GS
load-font))
(port (ly:outputter-port outputter)))
(if (ly:get-option 'dump-signatures)
- (write-system-signatures basename (ly:paper-book-systems book) 1))
+ (write-system-signatures basename (ly:paper-book-systems book) 0))
(output-scopes scopes fields basename)
(display (file-header paper page-count #t) port)
;; the left-overshoot is to make sure that
;; bar numbers stick out of margin uniformly.
;;
- (list
-
- (if (ly:get-option 'pad-eps-boxes)
- (min left-overshoot (car xext))
- (car xext))
- (car yext) (cdr xext) (cdr yext))))
-
+ (list (min left-overshoot (car xext))
+ (car yext) (cdr xext) (cdr yext))))
(rounded-bbox (to-bp-box bbox))
(port (ly:outputter-port outputter))
(header (eps-header paper rounded-bbox load-fonts?)))
;; skip booktitles.
(if (and
- (not (ly:get-option 'include-book-title-preview))
+ (not (ly:get-option 'preview-include-book-title))
(pair? systems)
(ly:prob-property (car systems) 'is-book-title #f))
(define-public (convert-to-pdf book name)
(let* ((defs (ly:paper-book-paper book))
- (landscape (ly:output-def-lookup defs 'landscape))
- (output-scale (ly:output-def-lookup defs 'output-scale))
- (convert (lambda (x) (* x output-scale (/ (ly:bp 1)))))
-
- (paper-width (convert (ly:output-def-lookup defs 'paper-width)))
- (paper-height (convert (ly:output-def-lookup defs 'paper-height)))
-
- (w (if landscape paper-height paper-width))
- (h (if landscape paper-width paper-height))
- )
+ (papersizename (ly:output-def-lookup defs 'papersizename)))
(if (equal? (basename name ".ps") "-")
(ly:warning (_ "can't convert <stdout> to ~S" "PDF"))
- (postscript->pdf w h name))))
+ (postscript->pdf (if (string? papersizename) papersizename "a4")
+ name))))
(define-public (convert-to-png book name)
(let* ((defs (ly:paper-book-paper book))
(resolution (if (number? defs-resolution)
defs-resolution
(ly:get-option 'resolution)))
- (paper-width (ly:output-def-lookup defs 'paper-width))
- (paper-height (ly:output-def-lookup defs 'paper-height))
- (output-scale (ly:output-def-lookup defs 'output-scale)))
+ (papersizename (ly:output-def-lookup defs 'papersizename)))
(postscript->png resolution
- (* paper-width output-scale (/ (ly:bp 1)))
- (* paper-height output-scale (/ (ly:bp 1)))
+ (if (string? papersizename) papersizename "a4")
name)))
(define-public (convert-to-dvi book name)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-module (scm framework-tex)
#:export (output-framework-tex
(define-public (convert-to-pdf book name)
(let* ((defs (ly:paper-book-paper book))
- (paper-width (ly:output-def-lookup defs 'paper-width))
- (paper-height (ly:output-def-lookup defs 'paper-height))
- (output-scale (ly:output-def-lookup defs 'output-scale)))
- (postscript->pdf (* paper-width output-scale (/ (ly:bp 1)))
- (* paper-height output-scale (/ (ly:bp 1)))
+ (papersizename (ly:output-def-lookup defs 'papersizename)))
+ (postscript->pdf (if (string? papersizename) papersizename "a4")
(string-append (basename name ".tex") ".ps"))))
(define-public (convert-to-png book name)
(let* ((defs (ly:paper-book-paper book))
(resolution (ly:output-def-lookup defs 'pngresolution))
- (paper-width (ly:output-def-lookup defs 'paper-width))
- (paper-height (ly:output-def-lookup defs 'paper-height))
- (output-scale (ly:output-def-lookup defs 'output-scale)))
+ (papersizename (ly:output-def-lookup defs 'papersizename)))
(postscript->png
(if (number? resolution)
resolution
(ly:get-option 'resolution))
- (* paper-width output-scale (/ (ly:bp 1)))
- (* paper-height output-scale (/ (ly:bp 1)))
-
+ (if (string? papersizename)
+ papersizename
+ "a4")
+
(string-append (basename name ".tex") ".ps"))))
(define-public (convert-to-ps book name)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-module (scm framework-texstr)
#:export (output-framework-tex
+++ /dev/null
-;;;; layout-page-tweaks.scm -- page breaking and page layout
-;;;;
-;;;; source file of the GNU LilyPond music typesetter
-;;;;
-;;;; (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-;;;; 2006 Nicolas Sceaux <nicolas.sceaux@free.fr>
-
-(define-module (scm layout-page-dump)
- #:use-module (srfi srfi-1)
- #:use-module (ice-9 pretty-print)
- #:use-module (scm paper-system)
- #:use-module (scm page)
- #:use-module (scm layout-page-layout)
- #:use-module (lily)
- #:export (write-page-breaks
- ;; utilisties for writing other page dump functions
- record-tweaks dump-all-tweaks))
-
-(define (record-tweaks what property-pairs tweaks)
- (let ((key (ly:output-def-lookup (ly:grob-layout what)
- 'tweak-key
- "tweaks"))
- (when (ly:grob-property what 'when)))
- (if (not (hash-ref tweaks key))
- (hash-set! tweaks key '()))
- (hash-set! tweaks key
- (acons when property-pairs
- (hash-ref tweaks key)))))
-
-(define (graceless-moment mom)
- (ly:make-moment (ly:moment-main-numerator mom)
- (ly:moment-main-denominator mom)
- 0 0))
-
-(define (moment->skip mom)
- (let ((main (if (> (ly:moment-main-numerator mom) 0)
- (format "\\skip 1*~a/~a"
- (ly:moment-main-numerator mom)
- (ly:moment-main-denominator mom))
- ""))
- (grace (if (< (ly:moment-grace-numerator mom) 0)
- (format "\\grace { \\skip 1*~a/~a }"
- (- (ly:moment-grace-numerator mom))
- (ly:moment-grace-denominator mom))
- "")))
- (format "~a~a" main grace)))
-
-(define (dump-tweaks out-port tweak-list last-moment)
- (if (not (null? tweak-list))
- (let* ((now (caar tweak-list))
- (diff (ly:moment-sub now last-moment))
- (these-tweaks (cdar tweak-list))
- (skip (moment->skip diff))
- (line-break-str (if (assoc-get 'line-break these-tweaks #f)
- "\\break\n"
- ""))
- (page-break-str (if (assoc-get 'page-break these-tweaks #f)
- "\\pageBreak\n"
- ""))
- (space-tweaks (format "\\spacingTweaks #'~a\n"
- (with-output-to-string
- (lambda ()
- (pretty-print
- (assoc-get 'spacing-parameters
- these-tweaks '()))))))
- (base (format "~a~a~a"
- line-break-str
- page-break-str
- space-tweaks)))
- (format out-port "~a\n~a\n" skip base)
- (dump-tweaks out-port (cdr tweak-list) (graceless-moment now)))))
-
-(define (dump-all-tweaks pages tweaks)
- (let* ((paper (ly:paper-book-paper (page-property (car pages) 'paper-book)))
- (parser (ly:output-def-parser paper))
- (name (format "~a-page-layout.ly"
- (ly:parser-output-name parser)))
- (out-port (open-output-file name)))
- (ly:message "Writing page layout to ~a" name)
- (hash-for-each
- (lambda (key val)
- (format out-port "~a = {" key)
- (dump-tweaks out-port (reverse val) (ly:make-moment 0 1))
- (display "}" out-port))
- tweaks)
- (close-port out-port)))
-
-(define (write-page-breaks pages)
- "Dump page breaks and tweaks"
- (let ((tweaks (make-hash-table 60)))
- (define (handle-page page)
- "Computes vertical stretch for each music line of `page' (starting by
- the smallest lines), then record the tweak parameters of each line to
- the `tweaks' hash-table."
- (let* ((lines (page-property page 'lines))
- (line-count (length lines))
- (compute-max-stretch (ly:output-def-lookup
- (ly:paper-book-paper (page-property page
- 'paper-book))
- 'system-maximum-stretch-procedure))
- (page-number (page-property page 'page-number)))
- (let set-line-stretch! ((sorted-lines (sort lines
- (lambda (l1 l2)
- (< (line-height l1)
- (line-height l2)))))
- (rest-height ;; sum of stretchable line heights
- (reduce + 0.0
- (map line-height
- (filter stretchable-line? lines))))
- (space-left (page-maximum-space-left page)))
- (if (not (null? sorted-lines))
- (let* ((line (first sorted-lines))
- (height (line-height line))
- (stretch (min (compute-max-stretch line)
- (if (and (stretchable-line? line)
- (positive? rest-height))
- (/ (* height space-left) rest-height)
- 0.0))))
- (set! (ly:prob-property line 'stretch) stretch)
- (set-line-stretch! (cdr sorted-lines)
- (if (stretchable-line? line)
- (- rest-height height)
- rest-height)
- (- space-left stretch)))))
- (let record-line-tweak ((lines lines)
- (is-first-line #t)
- (index 0))
- (if (not (null? lines))
- (let ((line (first lines)))
- (if (not (ly:prob-property? line 'is-title))
- (record-tweaks
- (ly:spanner-bound (ly:prob-property line 'system-grob) LEFT)
- `((line-break . #t)
- (page-break . ,is-first-line)
- (spacing-parameters
- . ((page-number . ,page-number)
- (system-index . ,index)
- (system-stretch . ,(ly:prob-property line 'stretch))
- (system-Y-extent . ,(paper-system-extent line Y))
- (system-refpoint-Y-extent . ,(paper-system-staff-extents line))
- (page-system-count . ,line-count)
- (page-printable-height . ,(page-printable-height page))
- (page-space-left . ,(page-property page 'space-left)))))
- tweaks))
- (record-line-tweak (cdr lines) #f (1+ index)))))))
- ;; Compute tweaks for each page, then dump them to the page-layout file
- (for-each handle-page pages)
- (dump-all-tweaks pages tweaks)))
-;;;; layout-page-layout.scm -- page breaking and page layout
+;;;; page-layout.scm -- page breaking and page layout
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 2004--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
-
-(define-module (scm layout-page-layout)
- #:use-module (srfi srfi-1)
- #:use-module (oop goops describe)
- #:use-module (oop goops)
- #:use-module (scm paper-system)
- #:use-module (scm page)
- #:use-module (scm layout-page-dump)
- #:use-module (lily)
- #:export (post-process-pages optimal-page-breaks make-page-from-systems
- page-breaking-wrapper
- ;; utilities for writing custom page breaking functions
- line-height line-next-space line-next-padding
- line-minimum-distance line-ideal-distance
- first-line-position
- line-ideal-relative-position line-minimum-relative-position
- line-minimum-position-on-page stretchable-line?
- page-maximum-space-to-fill page-maximum-space-left space-systems))
-
-(define (page-breaking-wrapper paper-book)
- "Compute line and page breaks by calling the page-breaking paper variable,
- then performs the post process function using the page-post-process paper
- variable. Finally, return the pages."
- (let* ((paper (ly:paper-book-paper paper-book))
- (pages ((ly:output-def-lookup paper 'page-breaking) paper-book)))
- ((ly:output-def-lookup paper 'page-post-process) paper pages)
- pages))
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+(use-modules (oop goops describe)
+ (oop goops)
+ (scm paper-system)
+ (scm page)
+ )
+
+
+(define (write-page-breaks pages)
+ "Dump page breaks"
+
+ (define tweaks (make-hash-table 23))
+
+ (define (record what property-pairs)
+ (let*
+ ((key (ly:output-def-lookup (ly:grob-layout what)
+ 'tweak-key
+ "tweaks"
+ ))
+ (when (ly:grob-property what 'when))
+ )
+
+ (if (not (hash-ref tweaks key))
+ (hash-set! tweaks key '()))
+
+ (hash-set! tweaks key
+ (acons when property-pairs
+ (hash-ref tweaks key)))
+
+ ))
+
+ (define (graceless-moment mom)
+ (ly:make-moment
+ (ly:moment-main-numerator mom)
+ (ly:moment-main-denominator mom)
+ 0 0))
+
+ (define (moment->skip mom)
+ (let*
+ ((main (if (> (ly:moment-main-numerator mom) 0)
+ (format "\\skip 1*~a/~a"
+ (ly:moment-main-numerator mom)
+ (ly:moment-main-denominator mom))
+ ""))
+ (grace (if (< (ly:moment-grace-numerator mom) 0)
+ (format "\\grace { \\skip 1*~a/~a }"
+ (- (ly:moment-grace-numerator mom))
+ (ly:moment-grace-denominator mom))
+ "")))
+
+ (format "~a~a" main grace)))
+
+ (define (dump-tweaks out-port tweak-list last-moment)
+ (if (not (null? tweak-list))
+ (let*
+ ((now (caar tweak-list))
+ (diff (ly:moment-sub now last-moment))
+ (these-tweaks (cdar tweak-list))
+ (skip (moment->skip diff))
+ (line-break-str (if (assoc-get 'line-break these-tweaks #f)
+ "\\break\n"
+ ""))
+ (page-break-str (if (assoc-get 'page-break these-tweaks #f)
+ "\\pageBreak\n"
+ ""))
+ (space-tweaks (format "\\spacingTweaks #'~a\n"
+ (with-output-to-string
+ (lambda ()
+ (pretty-print
+
+ (assoc-get 'spacing-parameters these-tweaks '()))))
+ ))
+ (base (format "~a~a~a"
+ line-break-str
+ page-break-str
+ space-tweaks))
+ )
+
+ (format out-port "~a\n~a\n" skip base)
+ (dump-tweaks out-port (cdr tweak-list) (graceless-moment now))
+ )))
+
+ (define (dump-all-tweaks)
+ (let*
+ ((paper (ly:paper-book-paper (page-property (car pages) 'paper-book)))
+ (parser (ly:output-def-parser paper))
+ (name (format "~a-page-layout.ly"
+ (ly:parser-output-name parser)))
+ (out-port (open-output-file name)))
+
+ (ly:progress "Writing page layout to ~a" name)
+ (hash-for-each
+ (lambda (key val)
+ (format out-port "~a = {" key)
+ (dump-tweaks out-port (reverse val) (ly:make-moment 0 1))
+ (display "}" out-port))
+ tweaks)
+ (close-port out-port)
+ ))
+
+ (define (handle-page page)
+ (define index 0)
+ (define music-system-heights
+ (map-in-order (lambda (sys)
+ (* -1 (car (paper-system-extent sys Y))))
+ (remove (lambda (sys)
+ (ly:prob-property? sys 'is-title))
+ (page-lines page))))
+ (define (handle-system sys)
+ (let*
+ ((props `((line-break . #t)
+ (spacing-parameters
+ . ((system-Y-extent . ,(paper-system-extent sys Y))
+ (system-refpoint-Y-extent . ,(paper-system-staff-extents sys))
+ (system-index . ,index)
+ (music-system-heights . ,music-system-heights)
+ (page-system-count . ,(length (page-lines page)))
+ (page-printable-height . ,(page-printable-height page))
+ (page-space-left . ,(page-property page 'space-left))))
+ )))
+
+ (if (equal? (car (page-lines page)) sys)
+ (set! props (cons '(page-break . #t)
+ props)))
+ (if (not (ly:prob-property? sys 'is-title))
+ (record (ly:spanner-bound (ly:prob-property sys 'system-grob) LEFT)
+ props))
+
+ (set! index (1+ index))
+ ))
+ (for-each handle-system (page-lines page)))
+
+ (for-each handle-page pages)
+ (dump-all-tweaks))
(define (post-process-pages layout pages)
- "If the write-page-layout paper variable is true, dumps page breaks
- and tweaks."
(if (ly:output-def-lookup layout 'write-page-layout #f)
(write-page-breaks pages)))
-;;;
-;;; Utilities for computing line distances and positions
-;;;
-(define (line-height line)
- "Return the system height, that is the length of its vertical extent."
- (interval-length (paper-system-extent line Y)))
-
-(define (line-next-space line next-line layout)
- "Return space to use between `line' and `next-line'.
- `next-line' can be #f, meaning that `line' is the last line."
- (let* ((title (paper-system-title? line))
- (next-title (and next-line (paper-system-title? next-line))))
- (cond ((and title next-title)
- (ly:output-def-lookup layout 'between-title-space))
- (title
- (ly:output-def-lookup layout 'after-title-space))
- (next-title
- (ly:output-def-lookup layout 'before-title-space))
- (else
- (ly:prob-property
- line 'next-space
- (ly:output-def-lookup layout 'between-system-space))))))
-
-(define (line-next-padding line next-line layout)
- "Return padding to use between `line' and `next-line'.
- `next-line' can be #f, meaning that `line' is the last line."
- (ly:prob-property
- line 'next-padding
- (ly:output-def-lookup layout 'between-system-padding)))
-
-
-(define (line-minimum-distance line next-line layout ignore-padding)
- "Minimum distance between `line' reference position and `next-line'
- reference position. If next-line is #f, return #f."
- (and next-line
- (max 0 (- (+ (interval-end (paper-system-extent next-line Y))
- (if ignore-padding 0 (line-next-padding line next-line layout)))
- (interval-start (paper-system-extent line Y))))))
-
-(define (line-ideal-distance line next-line layout ignore-padding)
- "Ideal distance between `line' reference position and `next-line'
- reference position. If next-line is #f, return #f."
- (and next-line
- (+ (max 0 (- (+ (interval-end (paper-system-staff-extents next-line))
- (if ignore-padding 0 (line-next-padding line next-line layout)))
- (interval-start (paper-system-staff-extents line))))
- (line-next-space line next-line layout))))
-
-(define (first-line-position line layout)
- "Position of the first line on page"
- (max (+ (ly:output-def-lookup layout 'page-top-space)
- (interval-end (paper-system-staff-extents line)))
- (interval-end (paper-system-extent line Y))))
-
-(define (line-ideal-relative-position line prev-line layout ignore-padding)
- "Return ideal position of `line', relative to `prev-line' position.
- `prev-line' can be #f, meaning that `line' is the first line."
- (if (not prev-line)
- ;; first line on page
- (first-line-position line layout)
- ;; not the first line on page
- (max (line-minimum-distance prev-line line layout ignore-padding)
- (line-ideal-distance prev-line line layout ignore-padding))))
-
-(define (line-minimum-relative-position line prev-line layout ignore-padding)
- "Return position of `line', relative to `prev-line' position.
- `prev-line' can be #f, meaning that `line' is the first line."
- (if (not prev-line)
- ;; first line on page
- (first-line-position line layout)
- ;; not the first line on page
- (line-minimum-distance prev-line line layout ignore-padding)))
-
-(define (line-minimum-position-on-page line prev-line prev-position page)
- "If `line' fits on `page' after `prev-line', which position on page is
- `prev-position', then return the line's postion on page, otherwise #f.
- `prev-line' can be #f, meaning that `line' is the first line."
- (let* ((layout (ly:paper-book-paper (page-property page 'paper-book)))
- (position (+ (line-minimum-relative-position line prev-line layout #f)
- (if prev-line prev-position 0.0)))
- (bottom-position (- position
- (interval-start (paper-system-extent line Y)))))
- (and (or (not prev-line)
- (< bottom-position (page-printable-height page)))
- position)))
-
-(define (stretchable-line? line)
- "Say whether a system can be stretched."
- (not (or (ly:prob-property? line 'is-title)
- (let ((system-extent (paper-system-staff-extents line)))
- (= (interval-start system-extent)
- (interval-end system-extent))))))
-
-(define (page-maximum-space-to-fill page lines paper)
- "Return the space between the first line top position and the last line
- bottom position. This constitutes the maximum space to fill on `page'
- with `lines'."
- (let ((last-line (car (last-pair lines))))
- (- (page-printable-height page)
- (first-line-position (first lines) paper)
- (ly:prob-property last-line
- 'bottom-space 0.0)
- (- (interval-start (paper-system-extent last-line Y))))))
-
-(define (page-maximum-space-left page)
- (let ((paper (ly:paper-book-paper (page-property page 'paper-book))))
- (let bottom-position ((lines (page-property page 'lines))
- (prev-line #f)
- (prev-position #f))
- (if (null? lines)
- (page-printable-height page)
- (let* ((line (first lines))
- (position (line-minimum-position-on-page
- line prev-line prev-position page)))
- (if (null? (cdr lines))
- (and position
- (- (page-printable-height page)
- (- position
- (interval-start (paper-system-extent line Y)))))
- (bottom-position (cdr lines) line position)))))))
-
-;;;
-;;; Utilities for distributing systems on a page
-;;;
-
-(define (space-systems space-to-fill lines ragged paper ignore-padding)
- "Compute lines positions on page: return force and line positions as a pair.
- force is #f if lines do not fit on page."
- (let* ((empty-stencil (ly:make-stencil '() '(0 . 0) '(0 . 0)))
- (empty-prob (ly:make-prob 'paper-system (list `(stencil . ,empty-stencil))))
- (cdr-lines (append (cdr lines)
- (if (<= (length lines) 1)
- (list empty-prob)
- '())))
- (springs (map (lambda (prev-line line)
- (list (line-ideal-distance prev-line line paper ignore-padding)
- (/ 1.0 (line-next-space prev-line line paper))))
- lines
- cdr-lines))
- (rods (map (let ((i -1))
- (lambda (prev-line line)
- (set! i (1+ i))
- (list i (1+ i)
- (line-minimum-distance prev-line line paper ignore-padding))))
- lines
- cdr-lines))
- (space-result
- (ly:solve-spring-rod-problem springs rods space-to-fill ragged)))
- (cons (car space-result)
- (map (let ((topskip (first-line-position (first lines) paper)))
- (lambda (y)
- (+ y topskip)))
- (cdr space-result)))))
-
-(define (make-page-from-systems paper-book lines page-number ragged last)
- "Return a new page, filled with `lines'."
- (let* ((page (make-page paper-book
- 'lines lines
- 'page-number page-number
- 'is-last last))
- (posns (if (null? lines)
- (list)
- (let* ((paper (ly:paper-book-paper paper-book))
- (space-to-fill (page-maximum-space-to-fill
- page lines paper))
- (spacing (space-systems space-to-fill lines ragged paper #f)))
- (if (or (not (car spacing)) (inf? (car spacing)))
- (cdr (space-systems space-to-fill lines ragged paper #t))
- (cdr spacing))))))
- (page-set-property! page 'configuration posns)
- page))
-
-;;;
-;;; Page breaking function
-;;;
-
;; Optimal distribution of
;; lines over pages; line breaks are a given.
;; - separate function for word-wrap style breaking?
;; - ragged-bottom? ragged-last-bottom?
-(define (get-path node done)
- "Follow NODE.PREV, and return as an ascending list of pages. DONE
+(define-public (optimal-page-breaks lines paper-book)
+ "Return pages as a list starting with 1st page. Each page is a 'page Prob."
+
+ (define MAXPENALTY 1e9)
+ (define paper (ly:paper-book-paper paper-book))
+
+ ;; ugh.
+ (define page-alist (layout->page-init (ly:paper-book-paper paper-book)))
+ (define scopes (ly:paper-book-scopes paper-book))
+ (define force-equalization-factor #f)
+ (define (get-path node done)
+
+ "Follow NODE.PREV, and return as an ascending list of pages. DONE
is what have collected so far, and has ascending page numbers."
- (if (page? node)
- (get-path (page-prev node) (cons node done))
- done))
-
-(define (combine-penalties force user best-paths
- inter-system-space force-equalization-factor)
- (let* ((prev-force (if (null? best-paths)
- 0.0
- (page-force (car best-paths))))
- (prev-penalty (if (null? best-paths)
+
+ (if (page? node)
+ (get-path (page-prev node) (cons node done))
+ done))
+
+ (define (combine-penalties force user best-paths)
+ (let* ((prev-force (if (null? best-paths)
0.0
- (page-penalty (car best-paths))))
+ (page-force (car best-paths))))
+ (prev-penalty (if (null? best-paths)
+ 0.0
+ (page-penalty (car best-paths))))
+ (inter-system-space (ly:output-def-lookup paper 'between-system-space))
(relative-force (/ force inter-system-space))
(abs-relative-force (abs relative-force)))
- (+ (* abs-relative-force (+ abs-relative-force 1))
- prev-penalty
- (* force-equalization-factor (/ (abs (- prev-force force))
- inter-system-space))
- user)))
-
-(define (walk-paths done-lines best-paths current-lines last current-best
- paper-book page-alist)
- "Return the best optimal-page-break-node that contains
-CURRENT-LINES. DONE-LINES.reversed ++ CURRENT-LINES is a consecutive
+
+ (+ (* abs-relative-force (+ abs-relative-force 1))
+ prev-penalty
+ (* force-equalization-factor (/ (abs (- prev-force force))
+ inter-system-space))
+ user)))
+
+ (define (space-systems page-height lines ragged?)
+ (let* ((global-inter-system-space
+ (ly:output-def-lookup paper 'between-system-space))
+ (top-space
+ (ly:output-def-lookup paper 'page-top-space))
+ (global-fixed-dist (ly:output-def-lookup paper 'between-system-padding))
+
+ (system-vector (list->vector
+ (append lines
+ (if (= (length lines) 1)
+ '(#f)
+ '()))))
+ (staff-extents
+ (list->vector
+ (append (map paper-system-staff-extents lines)
+ (if (= (length lines) 1)
+ '((0 . 0))
+ '()))))
+
+ (real-extents
+ (list->vector
+ (append
+ (map
+ (lambda (sys) (paper-system-extent sys Y)) lines)
+ (if (= (length lines) 1)
+ '((0 . 0))
+ '()))))
+
+ (system-count (vector-length real-extents))
+ (topskip (max
+ (+
+ top-space
+ (interval-end (vector-ref staff-extents 0)))
+ (interval-end (vector-ref real-extents 0))
+ ))
+ (last-system (vector-ref system-vector (1- system-count)))
+ (bottom-space (if (ly:prob? last-system)
+ (ly:prob-property last-system 'bottom-space 0.0)
+ 0.0))
+ (space-left (- page-height
+ bottom-space
+ (apply + (map interval-length
+ (vector->list real-extents)))))
+
+ (space (- page-height
+ topskip
+ bottom-space
+ (- (interval-start
+ (vector-ref real-extents (1- system-count))))))
+
+ (calc-spring
+ (lambda (idx)
+ (let* (
+ (upper-system (vector-ref system-vector idx))
+ (between-space (ly:prob-property upper-system 'next-space
+ global-inter-system-space))
+ (fixed-dist (ly:prob-property upper-system 'next-padding
+ global-fixed-dist))
+
+ (this-system-ext (vector-ref staff-extents idx))
+ (next-system-ext (vector-ref staff-extents (1+ idx)))
+ (fixed (max 0 (- (+ (interval-end next-system-ext)
+ fixed-dist)
+ (interval-start this-system-ext))))
+ (title1? (and (vector-ref system-vector idx)
+ (paper-system-title? (vector-ref system-vector idx)
+ )))
+ (title2? (and
+ (vector-ref system-vector (1+ idx))
+ (paper-system-title? (vector-ref system-vector (1+ idx)))))
+ (ideal (+
+ (cond
+ ((and title2? title1?)
+ (ly:output-def-lookup paper 'between-title-space))
+ (title1?
+ (ly:output-def-lookup paper 'after-title-space))
+ (title2?
+ (ly:output-def-lookup paper 'before-title-space))
+ (else between-space))
+ fixed))
+ (hooke (/ 1 (- ideal fixed))))
+ (list ideal hooke))))
+
+ (springs (map calc-spring (iota (1- system-count))))
+ (calc-rod
+ (lambda (idx)
+ (let* (
+ (upper-system (vector-ref system-vector idx))
+ (fixed-dist (ly:prob-property upper-system 'next-padding
+ global-fixed-dist))
+ (this-system-ext (vector-ref real-extents idx))
+ (next-system-ext (vector-ref real-extents (1+ idx)))
+
+ (distance (max (- (+ (interval-end next-system-ext)
+ fixed-dist)
+ (interval-start this-system-ext)
+ ) 0))
+ (entry (list idx (1+ idx) distance)))
+ entry)))
+ (rods (map calc-rod (iota (1- system-count))))
+
+ ;; we don't set ragged based on amount space left.
+ ;; ragged-bottomlast = ##T is much more predictable
+ (result (ly:solve-spring-rod-problem
+ springs rods space
+ ragged?))
+
+ (force (car result))
+ (positions
+ (map (lambda (y)
+ (+ y topskip))
+ (cdr result))))
+
+ (if #f ;; debug.
+ (begin
+ (display (list "\n# systems: " system-count
+ "\nreal-ext" real-extents "\nstaff-ext" staff-extents
+ "\ninterscore" global-inter-system-space
+ "\nspace-left" space-left
+ "\nspring,rod" springs rods
+ "\ntopskip " topskip
+ " space " space
+ "\npage-height" page-height
+ "\nragged" ragged?
+ "\nforce" force
+ "\nres" (cdr result)
+ "\npositions" positions "\n"))))
+
+ (cons force positions)))
+
+ (define (walk-paths done-lines best-paths current-lines last? current-best)
+ "Return the best optimal-page-break-node that contains
+CURRENT-LINES. DONE-LINES.reversed ++ CURRENT-LINES is a consecutive
ascending range of lines, and BEST-PATHS contains the optimal breaks
corresponding to DONE-LINES.
CURRENT-BEST is the best result sofar, or #f."
- (let* ((paper (ly:paper-book-paper paper-book))
- (this-page (make-page
- paper-book
- 'is-last last
- 'page-number (if (null? best-paths)
- (ly:output-def-lookup paper 'first-page-number)
- (1+ (page-page-number (first best-paths))))))
- (ragged-all (eq? #t (ly:output-def-lookup paper 'ragged-bottom)))
- (ragged-last (eq? #t (ly:output-def-lookup paper 'ragged-last-bottom)))
- (ragged (or ragged-all (and ragged-last last)))
- (space-to-fill (page-maximum-space-to-fill this-page current-lines paper))
- (vertical-spacing (space-systems space-to-fill current-lines ragged paper #f))
- (satisfied-constraints (car vertical-spacing))
- (force (if satisfied-constraints
- (if (and last ragged-last)
- 0.0
- satisfied-constraints)
- 10000))
- (positions (cdr vertical-spacing))
- (get-break-penalty (lambda (sys)
- (ly:prob-property sys 'penalty 0.0)))
- (user-nobreak-penalties (- (apply + (filter negative?
- (map get-break-penalty
- (cdr current-lines))))))
- (user-penalty (+ (max (get-break-penalty (car current-lines)) 0.0)
- user-nobreak-penalties))
- (total-penalty (combine-penalties
- force user-penalty best-paths
- (ly:output-def-lookup paper 'between-system-space)
- (ly:output-def-lookup paper 'verticalequalizationfactor 0.3)))
- (new-best (if (or (not current-best)
- (and satisfied-constraints
- (< total-penalty (page-penalty current-best))))
- (begin
- (map (lambda (x)
- (page-set-property! this-page
- (car x)
- (cdr x)))
- (list (cons 'prev (if (null? best-paths)
- #f
- (car best-paths)))
- (cons 'lines current-lines)
- (cons 'force force)
- (cons 'configuration positions)
- (cons 'penalty total-penalty)))
- this-page)
- current-best)))
- (if #f ;; debug
- (display
- (list
- "\nuser pen " user-penalty
- "\nsatisfied-constraints" satisfied-constraints
- "\nlast? " last "ragged?" ragged
- "\nis-better " is-better " total-penalty " total-penalty "\n"
- "\nconfig " positions
- "\nforce " force
- "\nlines: " current-lines "\n")))
- (if #f ; debug
- (display (list "\nnew-best is " (page-lines new-best)
- "\ncontinuation of "
- (if (null? best-paths)
- "start"
- (page-lines (car best-paths))))))
- (if (and (pair? done-lines)
- ;; if this page is too full, adding another line won't help
- satisfied-constraints)
- (walk-paths (cdr done-lines) (cdr best-paths)
- (cons (car done-lines) current-lines)
- last new-best
- paper-book page-alist)
- new-best)))
-
-(define (walk-lines done best-paths todo paper-book page-alist)
- "Return the best page breaking as a single
+
+ (let* ((this-page-num (if (null? best-paths)
+ (ly:output-def-lookup paper 'first-page-number)
+ (1+ (page-page-number (car best-paths)))))
+
+ (this-page (make-page
+ page-alist
+ 'paper-book paper-book
+ 'is-last last?
+ 'page-number this-page-num))
+
+ (ragged-all? (eq? #t (ly:output-def-lookup paper 'ragged-bottom)))
+ (ragged-last? (eq? #t (ly:output-def-lookup paper 'ragged-last-bottom)))
+ (ragged? (or ragged-all?
+ (and ragged-last?
+ last?)))
+ (height (page-printable-height this-page))
+ (vertical-spacing (space-systems height current-lines ragged?))
+
+ (satisfied-constraints (car vertical-spacing))
+ (force (if satisfied-constraints
+ (if (and last? ragged-last?)
+ 0.0
+ satisfied-constraints)
+ 10000))
+ (positions (cdr vertical-spacing))
+ (get-break-penalty (lambda (sys)
+ (ly:prob-property sys 'penalty 0.0)))
+ (user-nobreak-penalties
+ (-
+ (apply + (filter negative?
+ (map get-break-penalty
+ (cdr current-lines))))))
+ (user-penalty
+ (+
+ (max (get-break-penalty (car current-lines)) 0.0)
+ user-nobreak-penalties))
+
+ (total-penalty (combine-penalties
+ force user-penalty
+ best-paths))
+
+ (is-better (or
+ (not current-best)
+ (and
+ satisfied-constraints
+ (< total-penalty (page-penalty current-best)))))
+ (new-best (if is-better
+ (begin
+ (map
+ (lambda (x)
+ (page-set-property! this-page
+ (car x)
+ (cdr x)))
+ (list
+ (cons 'prev (if (null? best-paths)
+ #f
+ (car best-paths)))
+ (cons 'lines current-lines)
+ (cons 'force force)
+ (cons 'configuration positions)
+ (cons 'penalty total-penalty)))
+ this-page)
+ current-best)))
+
+;; (display total-penalty) (newline)
+ (if #f ;; debug
+ (display
+ (list
+ "\nuser pen " user-penalty
+ "\nsatisfied-constraints" satisfied-constraints
+ "\nlast? " last? "ragged?" ragged?
+ "\nis-better " is-better " total-penalty " total-penalty "\n"
+ "\nconfig " positions
+ "\nforce " force
+ "\nlines: " current-lines "\n")))
+
+ (if #f ; debug
+ (display (list "\nnew-best is " (page-lines new-best)
+ "\ncontinuation of "
+ (if (null? best-paths)
+ "start"
+ (page-lines (car best-paths))))))
+
+ (if (and (pair? done-lines)
+ ;; if this page is too full, adding another line won't help
+ satisfied-constraints)
+ (walk-paths (cdr done-lines) (cdr best-paths)
+ (cons (car done-lines) current-lines)
+ last? new-best)
+ new-best)))
+
+ (define (walk-lines done best-paths todo)
+ "Return the best page breaking as a single
page node for optimally breaking TODO ++
DONE.reversed. BEST-PATHS is a list of break nodes corresponding to
DONE."
- (if (null? todo)
- (car best-paths)
- (let* ((this-line (car todo))
- (last (null? (cdr todo)))
- (next (walk-paths done best-paths (list this-line) last #f
- paper-book page-alist)))
- (walk-lines (cons this-line done)
- (cons next best-paths)
- (cdr todo)
- paper-book
- page-alist))))
-
-(define-public (optimal-page-breaks paper-book)
- "Return pages as a list starting with 1st page. Each page is a 'page Prob."
- (let* ((paper (ly:paper-book-paper paper-book))
- (lines (ly:paper-book-systems paper-book))
- (page-alist (layout->page-init paper))
- (force-equalization-factor (ly:output-def-lookup
- paper 'verticalequalizationfactor 0.3)))
- (ly:message (_ "Calculating page breaks..."))
- (let* ((best-break-node (walk-lines '() '() lines paper-book page-alist))
- (break-nodes (get-path best-break-node '())))
- (page-set-property! (car (last-pair break-nodes)) 'is-last #t)
- (if #f; (ly:get-option 'verbose)
- (begin
- (display (list
- "\nbreaks: " (map (lambda (node)
- (ly:prob-property (car (page-lines node))
- 'number))
- break-nodes)
- "\nsystems " (map page-lines break-nodes)
- "\npenalties " (map page-penalty break-nodes)
- "\nconfigs " (map page-configuration break-nodes)))))
- ;; construct page stencils.
- (for-each page-stencil break-nodes)
- break-nodes)))
+
+ (if (null? todo)
+ (car best-paths)
+ (let* ((this-line (car todo))
+ (last? (null? (cdr todo)))
+ (next (walk-paths done best-paths (list this-line) last? #f)))
+
+ ;; (display "\n***************")
+ (walk-lines (cons this-line done)
+ (cons next best-paths)
+ (cdr todo)))))
+
+ (define (line-number node)
+ (ly:prob-property (car (page-lines node)) 'number))
+
+ (ly:message (_ "Calculating page breaks..."))
+ (set! force-equalization-factor
+ (ly:output-def-lookup paper 'verticalequalizationfactor 0.3))
+
+ (let* ((best-break-node (walk-lines '() '() lines))
+ (break-nodes (get-path best-break-node '())))
+
+ (page-set-property! (car (last-pair break-nodes)) 'is-last #t)
+ (if #f; (ly:get-option 'verbose)
+ (begin
+ (display (list
+ "\nbreaks: " (map line-number break-nodes))
+ "\nsystems " (map page-lines break-nodes)
+ "\npenalties " (map page-penalty break-nodes)
+ "\nconfigs " (map page-configuration break-nodes))))
+
+ ;; construct page stencils.
+ (for-each page-stencil break-nodes)
+ (post-process-pages paper break-nodes)
+
+ break-nodes))
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-public X 0)
(not (or (nan? (car i))
(inf? (car i))
(nan? (cdr i))
- (inf? (cdr i))
- (> (car i) (cdr i)))))
+ (inf? (cdr i)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-(define-public (string-encode-integer i)
- (cond
- ((= i 0) "o")
- ((< i 0) (string-append "n" (string-encode-integer (- i))))
- (else (string-append
- (make-string 1 (integer->char (+ 65 (modulo i 26))))
- (string-encode-integer (quotient i 26))))))
-
-(define-public (ly:numbers->string lst)
- (string-join (map ly:number->string lst) " "))
-
-(define (number->octal-string x)
- (let* ((n (inexact->exact x))
- (n64 (quotient n 64))
- (n8 (quotient (- n (* n64 64)) 8)))
- (string-append
- (number->string n64)
- (number->string n8)
- (number->string (remainder (- n (+ (* n64 64) (* n8 8))) 8)))))
-
-(define-public (ly:inexact->string x radix)
- (let ((n (inexact->exact x)))
- (number->string n radix)))
-
-(define-public (ly:number-pair->string c)
- (string-append (ly:number->string (car c)) " "
- (ly:number->string (cdr c))))
-
-
(define-public (write-me message x)
"Return X. Display MESSAGE and write X. Handy for debugging,
possibly turned off."
0
(if (< x 0) -1 1)))
-(define-public (car< a b) (< (car a) (car b)))
-
-
(define-public (symbol<? lst r)
(string<? (symbol->string lst) (symbol->string r)))
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define (define-scheme-options)
(for-each (lambda (x)
(ly:add-option (car x) (cadr x) (caddr x)))
- `(
-
- ;; NAMING: either
-
- ;; - [subject-]object-object-verb +"ing"
- ;; - [subject-]-verb-object-object
-
- (anti-alias-factor 1 "render at higher resolution and scale down result\nto prevent jaggies in PNG")
- (check-internal-types #f "check every property assignment for types")
- (debug-gc #f
- "dump memory debugging statistics")
- (debug-midi #f "generate human readable MIDI")
- (delete-intermediate-files #f
- "delete unusable PostScript files")
- (dump-signatures #f "dump output signatures of each system")
- (dump-tweaks #f "dump page layout and tweaks for each score having the tweak-key layout property set.")
- (gs-load-fonts #f
- "load fonts via Ghostscript.")
- (include-book-title-preview #t "include book-titles in preview images.")
- (include-eps-fonts #f "Include fonts in separate-system EPS files.")
-
- (pad-eps-boxes #f "Pad EPS bounding boxes to guarantee alignment between systems")
-
- (gui #f "running from gui; redirect stderr to log file")
-
+ `((point-and-click #t "use point & click")
+ (paper-size "a4" "the default paper size")
+ (midi-debug #f "generate human readable MIDI")
+ (dump-signatures #f "dump output signatures of each system (EPS backend)")
+ (internal-type-checking #f "check every property assignment for types")
+ (parse-protect #t "continue when finding errors in inline
+scheme are caught in the parser. If off, halt
+on errors, and print a stack trace.")
+ (profile-property-accesses #f "keep statistics of get_property() calls.")
(old-relative #f
"relative for simultaneous music works
similar to chord syntax")
(object-keys #f
"experimental mechanism for remembering tweaks")
- (point-and-click #t "use point & click")
- (paper-size "a4" "the default paper size")
- (protected-scheme-parsing #t "continue when finding errors in inline
-scheme are caught in the parser. If off, halt
-on errors, and print a stack trace.")
- (profile-property-accesses #f "keep statistics of get_property() calls.")
-
(resolution 101 "resolution for generating bitmaps")
- (read-file-list #f "Read files to be processed from command line arguments")
-
+ (anti-alias-factor 1 "render at higher resolution and scale down result\nto prevent jaggies in PNG")
+ (book-title-preview #t "include book-titles in preview images.")
+ (eps-font-include #f "Include fonts in separate-system EPS files.")
+ (gs-font-load #f
+ "load fonts via Ghostscript.")
+ (gui #f "running from gui; redirect stderr to log file")
+ (delete-intermediate-files #f
+ "delete unusable PostScript files")
(safe #f "Run safely")
+ (verbose ,(ly:command-line-verbose?) "value for the --verbose flag")
(strict-infinity-checking #f "If yes, crash on encountering Inf/NaN")
-
(ttf-verbosity 0
"how much verbosity for TTF font embedding?")
-
+ (debug-gc #f
+ "dump GC protection info")
(show-available-fonts #f
"List font names available.")
-
- (verbose ,(ly:command-line-verbose?) "value for the --verbose flag")
)))
safe-objects))
,safe-symbol)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; init pitch system
-
-(ly:set-default-scale (ly:make-scale #(0 2 4 5 7 9 11)))
-
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; other files.
"define-grobs.scm"
"define-grob-interfaces.scm"
"define-stencil-commands.scm"
+ "layout-page-layout.scm"
"titling.scm"
"paper.scm"
(exit 0)))))
(define-public (lilypond-all files)
- (if (ly:get-option 'read-file-list)
- (set! files
- (filter (lambda (s)
- (> (string-length s) 0))
- (apply append
- (map (lambda (f) (string-split (ly:gulp-file f) #\nl))
- files)))
- ))
(if (ly:get-option 'show-available-fonts)
(begin
;;;;
;;;; (c) 2006 Erik Sandberg <mandolaerik@gmail.com>
-;; TODO: use separate module for syntax
-;; constructors. Also create wrapper around the constructor?
+;; TODO: use separate module for parser.
(define define-ly-syntax define-public)
-;; A ly-syntax constructor takes two extra parameters, parser and
-;; location. These are mainly used for reporting errors and
-;; warnings. This function is a syntactic sugar which uses the
-;; location arg to set the origin of the returned music object; this
-;; behaviour is usually desired
+;; This shorthand adds a location parameter, and uses it to set the
+;; origin. It can be used for most music functions.
(defmacro define-ly-syntax-loc (args . body)
- (primitive-eval `(define-ly-syntax ,args
- (let ((m ,(cons 'begin body)))
- (set! (ly:music-property m 'origin) ,(third args))
- m))))
-
-;; Like define-ly-syntax-loc, but adds parser and location
-;; parameters. Useful for simple constructors that don't need to
-;; report errors.
-(defmacro define-ly-syntax-simple (args . body)
- (primitive-eval `(define-ly-syntax ,(cons* (car args)
- 'parser
- 'location
- (cdr args))
- (let ((m ,(cons 'begin body)))
+ (primitive-eval `(define-ly-syntax ,(cons* (car args) 'location (cdr args))
+ (let ((m ((lambda ,(cdr args) . ,body) . ,(cdr args))))
(set! (ly:music-property m 'origin) location)
m))))
-;; Music function: Apply function and check return value.
-(define-ly-syntax-loc (music-function parser loc fun args)
- (let ((m (apply fun (cons* parser loc args))))
- (if (ly:music? m)
- m
- (begin
- (ly:parser-error parser (_ "Music head function must return Music object") loc)
- (make-music 'Music)))))
-
-(define-ly-syntax-simple (void-music)
- (make-music 'Music))
-
-(define-ly-syntax-simple (sequential-music mlist)
+(define-ly-syntax-loc (sequential-music mlist)
(make-sequential-music mlist))
-(define-ly-syntax-simple (simultaneous-music mlist)
+(define-ly-syntax-loc (simultaneous-music mlist)
(make-simultaneous-music mlist))
-(define-ly-syntax-simple (event-chord mlist)
- (make-music 'EventChord
- 'elements mlist))
-
-(define-ly-syntax-simple (unrelativable-music mus)
- (make-music 'UnrelativableMusic
- 'element mus))
-
-(define-ly-syntax-simple (context-change type id)
- (make-music 'ContextChange
- 'change-to-type type
- 'change-to-id id))
-
-(define-ly-syntax-simple (voice-separator)
- (make-music 'VoiceSeparator))
-
-(define-ly-syntax-simple (bar-check)
- (make-music 'BarCheck))
-
-(define-ly-syntax-simple (time-scaled-music fraction music)
- (make-music 'TimeScaledMusic
- 'element (ly:music-compress music (ly:make-moment (car fraction) (cdr fraction)))
- 'numerator (car fraction)
- 'denominator (cdr fraction)))
-
-(define-ly-syntax-simple (transpose-music pitch music)
- (make-music 'TransposedMusic
- 'element (ly:music-transpose music pitch)))
-
-(define-ly-syntax-simple (tempo duration tempo)
- (context-spec-music
- (make-sequential-music
- (list
- (make-property-set 'tempoWholesPerMinute
- (ly:moment-mul (ly:make-moment tempo 1)
- (ly:duration-length duration)))
- (make-property-set 'tempoUnitDuration duration)
- (make-property-set 'tempoUnitCount tempo)))
- 'Score))
-
-(define-ly-syntax-simple (skip-music dur)
- (make-music 'SkipMusic
- 'duration dur))
-
-(define-ly-syntax-simple (repeat type num body alts)
+(define-ly-syntax-loc (repeat type num body alts)
(make-repeat type num body alts))
-
-(define (script-to-mmrest-text music)
- "Extract 'direction and 'text from SCRIPT-MUSIC, and transform MultiMeasureTextEvent"
- (if (memq 'script-event (ly:music-property music 'types))
-
- (let ((dir (ly:music-property music 'direction))
- (p (make-music 'MultiMeasureTextEvent
- 'text (ly:music-property music 'text))))
- (if (ly:dir? dir)
- (set! (ly:music-property p 'direction) dir))
- p)
- music))
-
-(define-ly-syntax (multi-measure-rest parser location duration articulations)
- (make-music 'MultiMeasureRestMusic
- 'articulations (map script-to-mmrest-text articulations)
- 'duration duration
- 'origin location))
-
-(define-ly-syntax-simple (context-specification type id mus ops create-new)
- (let* ((type-sym (if (symbol? type) type (string->symbol type)))
- (csm (context-spec-music mus type-sym id)))
- (set! (ly:music-property csm 'property-operations) ops)
- (if create-new (set! (ly:music-property csm 'create-new) #t))
- csm))
-
-(define-ly-syntax (property-operation parser location once ctx music-type symbol . args)
- (let* ((props (case music-type
- ((PropertySet) (list 'value (car args)))
- ((PropertyUnset) '())
- ((OverrideProperty) (list 'grob-value (car args)
- 'grob-property-path (cdr args)
- 'pop-first #t))
- ((RevertProperty) (list 'grob-property-path args))
- (else (ly:error (_ "Invalid property operation ~a") music-type))))
- (oprops (if once (cons* 'once once props) props))
- (m (apply make-music music-type
- 'symbol symbol
- 'origin location
- oprops)))
- (make-music 'ContextSpeccedMusic
- 'element m
- 'context-type ctx
- 'origin location)))
-
-;; TODO: It seems that this function rarely returns anything useful.
-(define (get-first-context-id type mus)
- "Find the name of a ContextSpeccedMusic with given type"
- (let ((id (ly:music-property mus 'context-id)))
- (if (and (eq? (ly:music-property mus 'type) 'ContextSpeccedMusic)
- (eq? (ly:music-property mus 'context-type) type)
- (string? id)
- (not (string-null? id)))
- id
- '())))
-
-(define unique-counter -1)
-(define (get-next-unique-voice-name)
- (set! unique-counter (1+ unique-counter))
- (call-with-output-string (lambda (p) (format p "uniqueContext~s" unique-counter))))
-
-(define (lyric-combine-music sync music loc)
- (make-music 'LyricCombineMusic
- 'element music
- 'associated-context sync
- 'origin loc))
-
-(define-ly-syntax (lyric-combine parser location voice music)
- (lyric-combine-music voice music location))
-
-(define-ly-syntax (add-lyrics parser location music addlyrics-list)
- (let* ((existing-voice-name (get-first-context-id 'Voice music))
- (voice-name (if (string? existing-voice-name)
- existing-voice-name
- (get-next-unique-voice-name)))
- (voice (if (string? existing-voice-name)
- (music)
- (make-music 'ContextSpeccedMusic
- 'element music
- 'context-type 'Voice
- 'context-id voice-name
- 'origin (ly:music-property music 'origin))))
- (lyricstos (map (lambda (mus)
- (let* ((loc (ly:music-property mus 'origin))
- (lyr (lyric-combine-music voice-name mus loc)))
- (make-music 'ContextSpeccedMusic
- 'create-new #t
- 'context-type 'Lyrics
- 'element lyr
- 'origin loc)))
- addlyrics-list)))
- (make-simultaneous-music (cons voice lyricstos))))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
"
Internally markup is stored as lists, whose head is a function.
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;; (use-modules (ice-9 optargs))
(make-procedure-with-setter ly:music-property
ly:music-set-property!))
-(define-safe-public (music-is-of-type? mus type)
- "Does @code{mus} belong to the music class @code{type}?"
- (memq type (ly:music-property mus 'types)))
;; TODO move this
(define-public ly:grob-property
(set! (ly:music-property music 'duration) nd)))
music))
+
+
(define-public (shift-duration-log music shift dot)
(music-map (lambda (x) (shift-one-duration-log x shift dot))
music))
;; mmrest
(define-public (make-multi-measure-rest duration location)
- (make-music 'MultiMeasureRestMusic
+ (make-music 'MultiMeasureRestMusicGroup
'origin location
- 'duration duration))
+ 'elements (list (make-music 'BarCheck
+ 'origin location)
+ (make-event-chord (list (make-music 'MultiMeasureRestEvent
+ 'origin location
+ 'duration duration)))
+ (make-music 'BarCheck
+ 'origin location))))
+
+(define-public (glue-mm-rest-texts music)
+ "Check if we have R1*4-\\markup { .. }, and if applicable convert to
+a property set for MultiMeasureRestNumber."
+ (define (script-to-mmrest-text script-music)
+ "Extract 'direction and 'text from SCRIPT-MUSIC, and transform MultiMeasureTextEvent"
+ (let ((dir (ly:music-property script-music 'direction))
+ (p (make-music 'MultiMeasureTextEvent
+ 'text (ly:music-property script-music 'text))))
+ (if (ly:dir? dir)
+ (set! (ly:music-property p 'direction) dir))
+ p))
+
+ (if (eq? (ly:music-property music 'name) 'MultiMeasureRestMusicGroup)
+ (let* ((text? (lambda (x) (memq 'script-event (ly:music-property x 'types))))
+ (event? (lambda (x) (memq 'event (ly:music-property x 'types))))
+ (group-elts (ly:music-property music 'elements))
+ (texts '())
+ (events '())
+ (others '()))
+
+ (set! texts
+ (map script-to-mmrest-text (filter text? group-elts)))
+ (set! group-elts
+ (remove text? group-elts))
+
+ (set! events (filter event? group-elts))
+ (set! others (remove event? group-elts))
+
+ (if (or (pair? texts) (pair? events))
+ (set! (ly:music-property music 'elements)
+ (cons (make-event-chord
+ (append texts events))
+ others)))
+
+ ))
+
+ music)
+
(define-public (make-property-set sym val)
(make-music 'PropertySet
'symbol sym
'value val))
-(define-public (make-property-unset sym)
- (make-music 'PropertyUnset
- 'symbol sym))
-
(define-public (make-ottava-set octavation)
(let ((m (make-music 'ApplyContext)))
(define (ottava-modify context)
(define-public (make-time-signature-set num den . rest)
"Set properties for time signature NUM/DEN. Rest can contain a list
of beat groupings "
-
- (define (standard-beat-grouping num den)
-
- "Some standard subdivisions for time signatures."
- (let*
- ((key (cons num den))
- (entry (assoc key '(((6 . 8) . (3 3))
- ((5 . 8) . (3 2))
- ((9 . 8) . (3 3 3))
- ((12 . 8) . (3 3 3 3))
- ((8 . 8) . (3 3 2))
- ))))
-
- (if entry
- (cdr entry)
- '())))
-
(let* ((set1 (make-property-set 'timeSignatureFraction (cons num den)))
(beat (ly:make-moment 1 den))
(len (ly:make-moment num den))
(set3 (make-property-set 'measureLength len))
(set4 (make-property-set 'beatGrouping (if (pair? rest)
(car rest)
- (standard-beat-grouping num den))))
+ '())))
(basic (list set1 set2 set3 set4)))
(descend-to-context
(context-spec-music (make-sequential-music basic) 'Timing) 'Score)))
(define-public toplevel-music-functions
(list
(lambda (music parser) (voicify-music music))
+ (lambda (x parser) (music-map glue-mm-rest-texts x))
(lambda (x parser) (music-map music-check-error x))
(lambda (x parser) (music-map precompute-music-length x))
(lambda (music parser)
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
+;;; Tablature functions, by Jiba (jiba@tuxfamily.org)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; general
-
-(define-public (make-stencil-boxer thickness padding callback)
-
- "Return function that adds a box around the grob passed as argument."
- (lambda (grob)
-
- (box-stencil (callback grob) thickness padding)))
-
-(define-public (make-stencil-circler thickness padding callback)
- "Return function that adds a circle around the grob passed as argument."
-
- (lambda (grob) (circle-stencil (callback grob) thickness padding)))
-
-(define-public (print-circled-text-callback grob)
- (let* ((text (ly:grob-property grob 'text))
-
- (layout (ly:grob-layout grob))
- (defs (ly:output-def-lookup layout 'text-font-defaults))
- (props (ly:grob-alist-chain grob defs))
- (circle (ly:text-interface::interpret-markup
- layout props (make-circle-markup text))))
- circle))
-
-
-(define-public (event-cause grob)
- (let*
- ((cause (ly:grob-property grob 'cause)))
-
- (cond
- ((ly:stream-event? cause) cause)
- ((ly:grob? cause) (event-cause cause))
- (else #f))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; tablature
+;; The TabNoteHead stem attachment function.
+(define (note-head::calc-tablature-stem-attachment grob)
+ (cons 0.0 1.35))
;; The TabNoteHead tablatureFormat callback.
;; Compute the text grob-property
(define-public (four-string-banjo tuning)
(reverse (cdr (reverse tuning))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; note heads
+;;; end of tablature functions
-(define-public (note-head::calc-duration-log grob)
- (ly:duration-log
- (ly:event-property (event-cause grob) 'duration)))
+(define-public (make-stencil-boxer thickness padding callback)
-(define-public (dots::calc-dot-count grob)
- (ly:duration-dot-count
- (ly:event-property (event-cause grob) 'duration)))
+ "Return function that adds a box around the grob passed as argument."
+ (lambda (grob)
+
+ (box-stencil (callback grob) thickness padding)))
-(define (note-head::calc-tablature-stem-attachment grob)
- (cons 0.0 1.35))
+(define-public (make-stencil-circler thickness padding callback)
+ "Return function that adds a circle around the grob passed as argument."
+ (lambda (grob) (circle-stencil (callback grob) thickness padding)))
+
+(define-public (arg->string arg)
+ (cond ((number? arg) (ly:inexact->string arg 10))
+ ((string? arg) (string-append "\"" arg "\""))
+ ((symbol? arg) (string-append "\"" (symbol->string arg) "\""))))
+
+(define-public (print-circled-text-callback grob)
+ (let* ((text (ly:grob-property grob 'text))
+
+ (layout (ly:grob-layout grob))
+ (defs (ly:output-def-lookup layout 'text-font-defaults))
+ (props (ly:grob-alist-chain grob defs))
+ (circle (ly:text-interface::interpret-markup
+ layout props (make-circle-markup text))))
+ circle))
+
+
+;;(define (mm-to-pt x)
+;; (* (/ 72.27 25.40) x))
+
+;; do nothing in .scm output
+
+(define-public (ly:numbers->string lst)
+ (string-join (map ly:number->string lst) " "))
+
+(define (number->octal-string x)
+ (let* ((n (inexact->exact x))
+ (n64 (quotient n 64))
+ (n8 (quotient (- n (* n64 64)) 8)))
+ (string-append
+ (number->string n64)
+ (number->string n8)
+ (number->string (remainder (- n (+ (* n64 64) (* n8 8))) 8)))))
+
+(define-public (ly:inexact->string x radix)
+ (let ((n (inexact->exact x)))
+ (number->string n radix)))
+(define-public (ly:number-pair->string c)
+ (string-append (ly:number->string (car c)) " "
+ (ly:number->string (cdr c))))
;; silly, use alist?
'(1.0 . 0.0))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; bar numbers
+(define-public (string-encode-integer i)
+ (cond
+ ((= i 0) "o")
+ ((< i 0) (string-append "n" (string-encode-integer (- i))))
+ (else (string-append
+ (make-string 1 (integer->char (+ 65 (modulo i 26))))
+ (string-encode-integer (quotient i 26))))))
(define-public ((every-nth-bar-number-visible n) barnum) (= 0 (modulo barnum n)))
(define-public (first-bar-number-invisible barnum) (> barnum 1))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; break visibility
-
+;; See documentation of ly:item::visibility-lambda-
(define-public begin-of-line-visible
#(#f #f #t))
(define-public end-of-line-visible
(result (assoc glyph
'((":|:" . (":|" . "|:"))
("||:" . ("||" . "|:"))
- ("dashed" . ("dashed" . '()))
("|" . ("|" . ()))
("||:" . ("||" . "|:"))
("|s" . (() . "|"))
(ly:grob-translate-axis! g 3.5 X)))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Tuplets
-
-(define-public (tuplet-number::calc-denominator-text grob)
- (number->string (ly:event-property (event-cause grob) 'denominator)))
-
-(define-public (tuplet-number::calc-fraction-text grob)
- (let*
- ((ev (event-cause grob)))
-
- (format "~a:~a"
- (ly:event-property ev 'denominator)
- (ly:event-property ev 'numerator))))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Color
(define (parenthesize-elements grob . rest)
(let*
- ((refp (if (null? rest)
+ (
+ (refp (if (null? rest)
grob
(car rest)))
(elts (ly:grob-object grob 'elements))
(lp (ly:font-get-glyph font "accidentals.leftparen"))
(rp (ly:font-get-glyph font "accidentals.rightparen"))
(padding (ly:grob-property grob 'padding 0.1)))
-
+
(ly:stencil-add
(ly:stencil-translate-axis lp (- (car x-ext) padding) X)
(ly:stencil-translate-axis rp (+ (cdr x-ext) padding) X))
value)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; falls
-
-(define-public (fall::print spanner)
- (let*
- ((delta-y (* 0.5 (ly:grob-property spanner 'delta-position)))
- (left-span (ly:spanner-bound spanner LEFT))
- (right-span (ly:spanner-bound spanner RIGHT))
- (thickness (* (ly:grob-property spanner 'thickness)
- (ly:output-def-lookup (ly:grob-layout spanner)
- 'line-thickness)))
- (padding (ly:grob-property spanner 'padding 0.5))
- (common (ly:grob-common-refpoint right-span
- (ly:grob-common-refpoint spanner
- left-span X)
- X))
- (left-x (+ padding (interval-end (ly:grob-robust-relative-extent left-span common X))))
- (right-x (- (interval-start (ly:grob-robust-relative-extent right-span common X)) padding))
- (self-x (ly:grob-relative-coordinate spanner common X))
- (dx (- right-x left-x))
- (exp (list 'path thickness
- `(quote
- (rmoveto
- ,(- left-x self-x) 0
-
- rcurveto
- ,(/ dx 3)
- 0
- ,dx ,(* 0.66 delta-y)
- ,dx ,delta-y
- ))))
- )
-
- (ly:make-stencil
- exp
- (cons 0 dx)
- (cons (min 0 delta-y)
- (max 0 delta-y)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; grace spacing
-
-
-(define-public (grace-spacing::calc-shortest-duration grob)
- (let*
- ((cols (ly:grob-object grob 'columns))
- (get-difference
- (lambda (idx)
- (ly:moment-sub (ly:grob-property (ly:grob-array-ref cols (1+ idx)) 'when)
- (ly:grob-property (ly:grob-array-ref cols idx) 'when))))
-
- (moment-min (lambda (x y)
- (cond
- ((and x y)
- (if (ly:moment<? x y)
- x
- y))
- (x x)
- (y y)))))
-
- (fold moment-min #f (map get-difference
- (iota (1- (ly:grob-array-length cols)))))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; fingering
-
-(define-public (fingering::calc-text grob)
- (let*
- ((event (event-cause grob))
- (digit (ly:event-property event 'digit)))
-
- (if (> digit 5)
- (ly:input-message (ly:music-property event 'origin)
- "Music for the martians"))
-
- (number->string digit 10)
- ))
-
-(define-public (string-number::calc-text grob)
- (let*
- ((digit (ly:event-property (event-cause grob) 'string-number)))
-
- (number->string digit 10)
- ))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; dynamics
-(define-public (hairpin::calc-grow-direction grob)
- (if (eq? (ly:event-property (event-cause grob) 'class) 'decrescendo-event)
- START
- STOP
- ))
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Note: currently misused as testbed for titles with markup, see
;;;; input/test/title-markup.ly
polygon
repeat-slash
resetcolor
- resetrotation
+ resetrotatino
round-filled-box
setcolor
- setrotation
+ setrotation
text
zigzag-line))
"false")
(round4 radius) (round4 thick)))
-(define (dashed-line thick on off dx dy phase)
- (format #f "~a ~a ~a [ ~a ~a ] ~a draw_dashed_line"
+(define (dashed-line thick on off dx dy)
+ (format #f "~a ~a ~a [ ~a ~a ] 0 draw_dashed_line"
(str4 dx)
(str4 dy)
(str4 thick)
(str4 on)
- (str4 off)
- (str4 phase)
-
- ))
+ (str4 off)))
;; what the heck is this interface ?
(define (dashed-slur thick on off l)
(define (grob-cause offset grob)
(let* ((cause (ly:grob-property grob 'cause))
- (music-origin (if (ly:stream-event? cause)
- (ly:event-property cause 'origin))))
+ (music-origin (if (ly:music? cause)
+ (ly:music-property cause 'origin))))
(if (not (ly:input-location? music-origin))
""
(let* ((location (ly:input-file-line-char-column music-origin))
(format #f "~a draw_repeat_slash"
(numbers->string4 (list x-width width height)))))
+;; restore color from stack
+(define (resetcolor) "setrgbcolor\n")
+
+;; reset rotation
+(define (resetrotation ang x y)
+ (format "~a translate ~a rotate ~a translate\n"
+ (numbers->string4 (list x y))
+ (number->string (* -1 ang))
+ (numbers->string4 (list (* -1 x) (* -1 y)))))
(define (round-filled-box left right bottom top blotdiam)
(let* ((halfblot (/ blotdiam 2))
;; save current color on stack and set new color
(define (setcolor r g b)
- (format #f "gsave ~a setrgbcolor\n"
+ (format #f "currentrgbcolor ~a setrgbcolor\n"
(numbers->string4 (list r g b))))
-;; restore color from stack
-(define (resetcolor) "grestore \n")
-
;; rotation around given point
(define (setrotation ang x y)
- (format "gsave ~a translate ~a rotate ~a translate\n"
+ (format "~a translate ~a rotate ~a translate\n"
(numbers->string4 (list x y))
(number->string ang)
(numbers->string4 (list (* -1 x) (* -1 y)))))
-(define (resetrotation ang x y)
- "grestore ")
-
-
(define (text font s)
;; (ly:warning (_ "TEXT backend-command encountered in Pango backend"))
;; (ly:warning (_ "Arguments: ~a ~a"" font str))
(str4 thick)
(str4 dx)
(str4 dy)))
-
-
-(define (path thickness exps)
- (define (convert-path-exps exps)
- (if (pair? exps)
- (let*
- ((head (car exps))
- (rest (cdr exps))
- (arity
- (cond
- ((memq head '(rmoveto rlineto lineto moveto)) 2)
- ((memq head '(rcurveto curveto)) 6)
- (else 1)))
- (args (take rest arity))
- )
-
- ;; WARNING: this is a vulnerability: a user can output arbitrary PS code here.
- (cons (format "~a ~a "
- (string-join (map (lambda (x) (format "~a " x)) args) " ")
- head)
- (convert-path-exps (drop rest arity))))
- '()))
-
-
- (format
- "1 setlinecap ~a setlinewidth\n~a stroke"
- thickness
- (string-join (convert-path-exps exps) " ")))
-
breapth width depth height blot-diameter
))
-(define (event-cause grob)
+(define (music-cause grob)
(let*
((cause (ly:grob-property grob 'cause)))
(cond
- ((ly:stream-event? cause) cause)
+ ((ly:music? cause) cause)
; ((ly:grob? cause) (music-cause cause))
(else
#f))))
(define-public (grob-cause offset grob)
(let*
- ((cause (event-cause grob))
- (tag (if (and cause (integer? (ly:event-property cause 'input-tag)))
- (ly:event-property cause 'input-tag)
+ ((cause (music-cause grob))
+ (tag (if (and cause (integer? (ly:music-property cause 'input-tag)))
+ (ly:music-property cause 'input-tag)
-1))
(name (cdr (assoc 'name (ly:grob-property grob 'meta))))
)
(guile)
(ice-9 regex)
(lily)
- (srfi srfi-1)
(srfi srfi-13))
(define (offset->point o)
(format #f " ~S,~S" (car o) (- (cdr o))))
-(define (number-list->point lst)
- (define (helper lst)
- (if (null? lst)
- '()
- (cons (format "~S,~S" (car lst) (cadr lst))
- (helper (cddr lst)))))
-
- (string-join (helper lst) " "))
-
-
(define (svg-bezier lst close)
(let* ((c0 (car (list-tail lst 3)))
(c123 (list-head lst 3)))
(entity 'path ""
'(stroke-linejoin . "round")
'(stroke-linecap . "round")
+ `(stroke-width . ,thick)
'(stroke . "currentColor")
'(fill . "currentColor")
- `(stroke-width . ,thick)
`(d . ,(string-append (svg-bezier first #f)
(svg-bezier second first-c0)))
)))
-(define (path thick commands)
- (define (convert-path-exps exps)
- (if (pair? exps)
- (let*
- ((head (car exps))
- (rest (cdr exps))
- (arity
- (cond
- ((memq head '(rmoveto rlineto lineto moveto)) 2)
- ((memq head '(rcurveto curveto)) 6)
- (else 1)))
- (args (take rest arity))
- (svg-head (assoc-get head '((rmoveto . m)
- (rcurveto . c)
- (curveto . C)
- (moveto . M)
- (lineto . L)
- (rlineto . l))
- ""))
- )
-
- (cons (format "~a~a "
- svg-head (number-list->point args)
- )
- (convert-path-exps (drop rest arity))))
- '()))
-
- (entity 'path ""
- `(stroke-width . ,thick)
- '(stroke-linejoin . "round")
- '(stroke-linecap . "round")
- '(stroke . "currentColor")
- '(fill . "none")
- `(d . ,(string-join (convert-path-exps commands) " "))))
-
(define (char font i)
(dispatch
`(fontify ,font ,(entity 'tspan (char->entity (integer->char i))))))
(y2 . ,(- y2)))
alist)))
-(define (dashed-line thick on off dx dy phase)
+(define (dashed-line thick on off dx dy)
(draw-line thick 0 0 dx dy `(style . ,(format "stroke-dasharray:~a,~a;" on off))))
(define (named-glyph font name)
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
;; The public interface is tight.
(ly:warning (_ "can't find ~a in ~a" name font))
""))))
-(define (dashed-line thick on off dx dy phase)
- (embedded-ps (list 'dashed-line thick on off dx dy phase)))
+(define (dashed-line thick on off dx dy)
+ (embedded-ps (list 'dashed-line thick on off dx dy)))
(define (zigzag-line centre? zzw zzh thick dx dy)
(embedded-ps (list 'zigzag-line centre? zzw zzh thick dx dy)))
(if (procedure? point-and-click)
(let* ((cause (ly:grob-property grob 'cause))
- (music-origin (if (ly:stream-event? cause)
- (ly:event-property cause 'origin)))
+ (music-origin (if (ly:music? cause)
+ (ly:music-property cause 'origin)))
(location (if (ly:input-location? music-origin)
(ly:input-file-line-column music-origin))))
(if (pair? location)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-module (scm output-texstr))
(define this-module (current-module))
(define page-module (current-module))
-(define (make-page paper-book . args)
+(define (make-page init . args)
(let*
((p (apply ly:make-prob (append
- (list 'page (layout->page-init (ly:paper-book-paper paper-book))
- 'paper-book paper-book)
+ (list 'page init)
args))))
(page-set-property! p 'head-stencil (page-header p))
(page-property page 'configuration))))
(define (annotate-page layout stencil)
- (let ((top-margin (ly:output-def-lookup layout 'top-margin))
- (paper-height (ly:output-def-lookup layout 'paper-height))
- (bottom-margin (ly:output-def-lookup layout 'bottom-margin))
- (add-stencil (lambda (y)
- (set! stencil
- (ly:stencil-add stencil
- (ly:stencil-translate-axis y 6 X))))))
+ (let*
+ ((top-margin (ly:output-def-lookup layout 'top-margin))
+ (paper-height (ly:output-def-lookup layout 'paper-height))
+ (bottom-margin (ly:output-def-lookup layout 'bottom-margin))
+ (add-stencil (lambda (y)
+ (set! stencil
+ (ly:stencil-add stencil y))
+ )))
+
(add-stencil
(ly:stencil-translate-axis
(annotate-y-interval layout "paper-height"
(cons (- paper-height) 0)
#t)
1 X))
+
+
(add-stencil
(ly:stencil-translate-axis
(annotate-y-interval layout "top-margin"
(cons (- top-margin) 0)
#t)
2 X))
+
(add-stencil
(ly:stencil-translate-axis
(annotate-y-interval layout "bottom-margin"
(cons (- paper-height) (- bottom-margin paper-height))
#t)
2 X))
+
stencil))
(define (annotate-space-left page)
(let*
- ((paper-book (page-property page 'paper-book))
- (layout (ly:paper-book-paper paper-book))
+ ((p-book (page-property page 'paper-book))
+ (layout (ly:paper-book-paper p-book))
(arrow (annotate-y-interval layout
"space left"
(cons (- 0.0
;; add arrow markers
(if (or (annotate? layout)
- (ly:output-def-lookup layout 'annotate-headers #f))
+ (ly:output-def-lookup layout 'annotateheaders #f))
(set! head-stencil
(ly:stencil-add
(ly:stencil-translate-axis
(define (page-header-or-footer page dir)
(let*
- ((paper-book (page-property page 'paper-book))
- (layout (ly:paper-book-paper paper-book))
- (scopes (ly:paper-book-scopes paper-book))
+ ((p-book (page-property page 'paper-book))
+ (layout (ly:paper-book-paper p-book))
+ (scopes (ly:paper-book-scopes p-book))
+ (lines (page-lines page))
(number (page-page-number page))
(last? (page-property page 'is-last))
)
)))
(define (make-page-stencil page)
- "Construct a stencil representing the page from PAGE."
+ "Construct a stencil representing the page from LINES.
+
+ Offsets is a list of increasing numbers. They must be negated to
+create offsets.
+"
+
(page-translate-systems page)
(let*
- ((paper-book (page-property page 'paper-book))
+ ((p-book (page-property page 'paper-book))
(prop (lambda (sym) (page-property page sym)))
- (layout (ly:paper-book-paper paper-book))
- (scopes (ly:paper-book-scopes paper-book))
+ (layout (ly:paper-book-paper p-book))
+ (scopes (ly:paper-book-scopes p-book))
(lines (page-lines page))
(number (page-page-number page))
;; TODO: naming paper-height/paper-width not analogous to TeX.
+
(system-xoffset (ly:output-def-lookup layout 'horizontal-shift 0.0))
(system-separator-markup (ly:output-def-lookup layout 'systemSeparatorMarkup))
(interval-length (ly:stencil-extent (prop 'head-stencil) Y))
0.0))
- (page-stencil (ly:make-stencil '()))
+ (page-stencil (ly:make-stencil
+ '()
+ (cons (prop 'left-margin) (prop 'paper-width))
+ (cons (- (prop 'top-margin)) 0)))
(last-system #f)
(last-y 0.0)
(cons
(+ system-xoffset x)
(- 0 head-height y (prop 'top-margin)))
-
+
)))))
(add-system
(lambda (system)
(foot (prop 'foot-stencil))
)
- (if (and
- (or (annotate? layout)
- (ly:output-def-lookup layout 'annotate-systems #f))
- (pair? lines))
+ (if (or (annotate? layout)
+ (ly:output-def-lookup layout 'annotatesystems #f))
(begin
- (for-each (lambda (sys next-sys)
- (paper-system-annotate sys next-sys layout))
- lines
- (append (cdr lines) (list #f)))
+ (for-each (lambda (sys) (paper-system-annotate sys layout))
+ lines)
(paper-system-annotate-last (car (last-pair lines)) layout)))
+
+ (set! page-stencil (ly:stencil-combine-at-edge
+ page-stencil Y DOWN
+ (if (and
+ (ly:stencil? head)
+ (not (ly:stencil-empty? head)))
+ head
+ (ly:make-stencil "" (cons 0 0) (cons 0 0)))
+ 0. 0.))
- (if (and
- (ly:stencil? head)
- (not (ly:stencil-empty? head)))
-
- (set! page-stencil (ly:stencil-add page-stencil
- (ly:stencil-translate-axis head
- (- 0 head-height (prop 'top-margin)) Y))))
-
(map add-system lines)
-
(ly:prob-set-property! page 'bottom-system-edge
(car (ly:stencil-extent page-stencil Y)))
(ly:prob-set-property! page 'space-left
;; annotation.
(if (or (annotate? layout)
- (ly:output-def-lookup layout 'annotate-page #f))
+ (ly:output-def-lookup layout 'annotatepage #f))
(set! page-stencil (annotate-page layout page-stencil)))
-
page-stencil))
(define (calc-printable-height page)
"Printable area for music and titles; matches default-page-make-stencil."
(let*
- ((paper-book (page-property page 'paper-book))
- (layout (ly:paper-book-paper paper-book))
+ ((p-book (page-property page 'paper-book))
+ (layout (ly:paper-book-paper p-book))
+ (scopes (ly:paper-book-scopes p-book))
+ (number (page-page-number page))
+ (last? (page-property page 'is-last))
(h (- (ly:output-def-lookup layout 'paper-height)
(ly:output-def-lookup layout 'top-margin)
(ly:output-def-lookup layout 'bottom-margin)))
stencil)
))
-(define-public (paper-system-annotate system next-system layout)
+(define-public (paper-system-annotate system layout)
"Add arrows and texts to indicate which lengths are set."
- (let* ((annotations (list))
- (annotate-extent-and-space
- (lambda (extent-accessor next-space
- extent-name next-space-name after-space-name)
- (let* ((extent-annotations (list))
- (this-extent (extent-accessor system))
- (next-extent (and next-system (extent-accessor next-system)))
- (push-annotation (lambda (stil)
- (set! extent-annotations
- (cons stil extent-annotations))))
- (color (if (paper-system-title? system) darkblue blue))
- (space-color (if (paper-system-title? system) darkred red)))
- (if (and (number-pair? this-extent)
- (not (= (interval-start this-extent)
- (interval-end this-extent))))
- (push-annotation (annotate-y-interval
- layout extent-name this-extent #f
- #:color color)))
- (if next-system
- (push-annotation (annotate-y-interval
- layout next-space-name
- (interval-translate (cons (- next-space) 0)
- (if (number-pair? this-extent)
- (interval-start this-extent)
- 0))
- #t
- #:color color)))
- (if (and next-system
- (number-pair? this-extent)
- (number-pair? next-extent))
- (let ((space-after
- (- (+ (ly:prob-property next-system 'Y-offset)
- (interval-start this-extent))
- (ly:prob-property system 'Y-offset)
- (interval-end next-extent)
- next-space)))
- (if (> space-after 0.01)
- (push-annotation (annotate-y-interval
- layout
- after-space-name
- (interval-translate
- (cons (- space-after) 0)
- (- (interval-start this-extent)
- next-space))
- #t
- #:color space-color)))))
- (if (not (null? extent-annotations))
- (set! annotations
- (stack-stencils X RIGHT 0.5
- (list annotations
- (ly:make-stencil '() (cons 0 1) (cons 0 0))
- (apply ly:stencil-add
- extent-annotations))))))))
+
+ (let*
+ ((annotations (ly:make-stencil '() (cons 0 2) (cons 0 0)))
+ (append-stencil
+ (lambda (a b)
+ (ly:stencil-combine-at-edge a X RIGHT b 0.5 0)))
+
+ (annotate-property
+ (lambda (name extent is-length?)
+ (set! annotations
+ (append-stencil annotations
+ (annotate-y-interval layout
+ name extent is-length?)))))
+
+ (bbox-extent (paper-system-extent system Y))
+ (refp-extent (ly:prob-property system 'refpoint-Y-extent))
+ (next-space (ly:prob-property system 'next-space
+ (ly:output-def-lookup layout 'between-system-space)
+ ))
+ (next-padding (ly:prob-property system 'next-padding
+ (ly:output-def-lookup layout 'between-system-padding)
+ ))
+ )
- (grob (ly:prob-property system 'system-grob))
- (estimate-extent (if (ly:grob? grob)
- (annotate-y-interval layout
- "extent-estimate"
- (ly:grob-property grob 'pure-Y-extent)
- #f)
- #f)))
- (let ((next-space (ly:prob-property
- system 'next-space
- (cond ((and next-system
- (paper-system-title? system)
- (paper-system-title? next-system))
- (ly:output-def-lookup layout 'between-title-space))
- ((paper-system-title? system)
- (ly:output-def-lookup layout 'after-title-space))
- ((and next-system
- (paper-system-title? next-system))
- (ly:output-def-lookup layout 'before-title-space))
- (else
- (ly:output-def-lookup layout 'between-system-space)))))
- (next-padding (ly:prob-property
- system 'next-padding
- (ly:output-def-lookup layout 'between-system-padding))))
- (annotate-extent-and-space (lambda (sys)
- (paper-system-extent sys Y))
- next-padding
- "Y-extent" "next-padding" "space after next-padding")
- (annotate-extent-and-space paper-system-staff-extents
- (+ next-space next-padding)
- "refpoint-Y-extent" "next-space+padding"
- "space after next-space+padding"))
- (if estimate-extent
- (set! annotations
- (stack-stencils X RIGHT 0.5
- (list annotations
- estimate-extent))))
-
- (if (not (null? annotations))
- (set! (ly:prob-property system 'stencil)
- (ly:stencil-add
- (ly:prob-property system 'stencil)
- (ly:make-stencil
- (ly:stencil-expr annotations)
- (ly:stencil-extent empty-stencil X)
- (ly:stencil-extent empty-stencil Y)))))
- (ly:prob-property system 'stencil)))
\ No newline at end of file
+ (if (number-pair? bbox-extent)
+ (begin
+ (annotate-property "Y-extent"
+ bbox-extent #f)
+ (annotate-property "next-padding"
+ (interval-translate (cons (- next-padding) 0) (car bbox-extent))
+ #t)))
+
+ ;; titles don't have a refpoint-Y-extent.
+ (if (number-pair? refp-extent)
+ (begin
+ (annotate-property "refpoint-Y-extent"
+ refp-extent #f)
+
+ (annotate-property "next-space"
+ (interval-translate (cons (- next-space) 0) (car refp-extent))
+ #t)))
+
+ (set! (ly:prob-property system 'stencil)
+ (ly:stencil-add
+ (ly:prob-property system 'stencil)
+ (ly:make-stencil
+ (ly:stencil-expr annotations)
+ (ly:stencil-extent empty-stencil X)
+ (ly:stencil-extent empty-stencil Y)
+ )))
+
+ ))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-public (set-paper-dimension-variables mod)
(module-define! mod 'dimension-variables
(set-paper-dimensions module (car entry) (cdr entry))
(module-define! module 'papersizename name)
- (module-define! module 'landscape
- (if landscape? #t #f)))
+
+ (if landscape?
+ (module-define! module 'landscape #t)))
(else
- (ly:warning (_ "Unknown papersize: ~a" name))))))
+ (ly:warning (_ ("Unknown papersize: ~a" name)))))))
(define-safe-public (set-default-paper-size name . rest)
(internal-set-paper-size
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;; (name . (glyph clef-position octavation))
("petrucci-c3" . ("clefs.petrucci.c3" 0 0))
("petrucci-c4" . ("clefs.petrucci.c4" 2 0))
("petrucci-c5" . ("clefs.petrucci.c5" 4 0))
- ("petrucci-f3" . ("clefs.petrucci.f" 0 0))
- ("petrucci-f4" . ("clefs.petrucci.f" 2 0))
("petrucci-f" . ("clefs.petrucci.f" 2 0))
("petrucci-g" . ("clefs.petrucci.g" -2 0))))
(char->integer #\0)))))
(string->list (number->string var-idx)))))))))
-(define-public (parse-string-result str parser)
+(define-public (ly:parse-string-result str parser)
"Parse `str', which is supposed to contain a music expression."
-
(ly:parser-parse-string
parser
(format #f "parseStringResult = \\notemode { ~a }" str))
,@(map (lambda (binding)
`(ly:parser-define! parser-clone ',(car binding) ,(cdr binding)))
(reverse bindings))
- (parse-string-result ,lily-string parser-clone)))))
+ (ly:parse-string-result ,lily-string parser-clone)))))
(read-hash-extend #\{ read-lily-expression)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;; todo: figure out how to make module,
;; without breaking nested ly scopes
(define-method (note-events (vs <Voice-state>))
(define (f? x)
- (equal? (ly:event-property x 'class) 'note-event))
+ (equal? (ly:music-property x 'name) 'NoteEvent))
(filter f? (events vs)))
(define-method (previous-voice-state (vs <Voice-state>))
"Analyse EVS at INDEX, given state ACTIVE."
(define (analyse-tie-start active ev)
- (if (equal? (ly:event-property ev 'class) 'tie-event)
+ (if (equal? (ly:music-property ev 'name) 'TieEvent)
(acons 'tie (split-index (vector-ref voice-state-vec index))
active)
active))
(define (analyse-tie-end active ev)
- (if (equal? (ly:event-property ev 'class) 'note-event)
+ (if (equal? (ly:music-property ev 'name) 'NoteEvent)
(assoc-remove! active 'tie)
active))
(define (analyse-absdyn-end active ev)
- (if (or (equal? (ly:event-property ev 'class) 'absolute-dynamic-event)
- (and (equal? (ly:event-property ev 'class) 'crescendo-event)
- (equal? STOP (ly:event-property ev 'span-direction))))
+ (if (or (equal? (ly:music-property ev 'name) 'AbsoluteDynamicEvent)
+ (and (equal? (ly:music-property ev 'name) 'CrescendoEvent)
+ (equal? STOP (ly:music-property ev 'span-direction))))
(assoc-remove! (assoc-remove! active 'cresc) 'decr)
active))
(else (< (cdr a) (cdr b)))))
(define (analyse-span-event active ev)
- (let* ((name (ly:event-property ev 'class))
- (key (cond ((equal? name 'slur-event) 'slur)
- ((equal? name 'phrasing-slur-event) 'tie)
- ((equal? name 'beam-event) 'beam)
- ((equal? name 'crescendo-event) 'cresc)
- ((equal? name 'decrescendo-event) 'decr)
+ (let* ((name (ly:music-property ev 'name))
+ (key (cond ((equal? name 'SlurEvent) 'slur)
+ ((equal? name 'PhrasingSlurEvent) 'tie)
+ ((equal? name 'BeamEvent) 'beam)
+ ((equal? name 'CrescendoEvent) 'cresc)
+ ((equal? name 'DecrescendoEvent) 'decr)
(else #f)))
- (sp (ly:event-property ev 'span-direction)))
+ (sp (ly:music-property ev 'span-direction)))
(if (and (symbol? key) (ly:dir? sp))
(if (= sp STOP)
(assoc-remove! active key)
(helper 0 '()))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define-public (recording-group-emulate music odef)
- "Interprets music according to odef, but stores all events in a chronological list, similar to the Recording_group_engraver in 2.8 and earlier"
- (let*
- ((context-list '())
- (now-mom (ly:make-moment 0 0))
- (global (ly:make-global-context odef))
- (mom-listener (ly:make-listener
- (lambda (tev)
- (set! now-mom (ly:event-property tev 'moment)))))
- (new-context-listener
- (ly:make-listener
- (lambda (sev)
- (let*
- ((child (ly:event-property sev 'context))
- (this-moment-list
- (cons (ly:context-id child) '()))
- (dummy
- (set! context-list (cons this-moment-list context-list)))
- (acc '())
- (accumulate-event-listener
- (ly:make-listener (lambda (ev)
- (set! acc (cons (cons ev #t) acc)))))
- (save-acc-listener (ly:make-listener (lambda (tev)
- (if (pair? acc)
- (let ((this-moment (cons (cons now-mom (ly:context-property child 'instrumentTransposition))
- acc)))
- (set-cdr! this-moment-list (cons this-moment (cdr this-moment-list)))
- (set! acc '())))))))
- (ly:add-listener accumulate-event-listener (ly:context-event-source child) 'music-event)
- (ly:add-listener save-acc-listener (ly:context-event-source global) 'OneTimeStep))))))
- (ly:add-listener new-context-listener (ly:context-events-below global) 'AnnounceNewContext)
- (ly:add-listener mom-listener (ly:context-event-source global) 'Prepare)
- (ly:interpret-music-expression (make-non-relative-music music) global)
- context-list))
-
(define noticed '())
-;; todo: junk this, extract $defaultlayout from parser instead
(define part-combine-listener '())
; UGH - should pass noticed setter to part-combine-listener
(set! noticed (acons (ly:context-id context) lst noticed)))
(define-public (make-part-combine-music music-list)
- (let* ((m (make-music 'PartCombineMusic))
- (m1 (make-non-relative-music (context-spec-music (first music-list) 'Voice "one")))
- (m2 (make-non-relative-music (context-spec-music (second music-list) 'Voice "two")))
- (evs2 (recording-group-emulate m2 part-combine-listener))
- (evs1 (recording-group-emulate m1 part-combine-listener)))
+ (let ((m (make-music 'PartCombineMusic))
+ (m1 (make-non-relative-music (context-spec-music (car music-list) 'Voice "one")))
+ (m2 (make-non-relative-music (context-spec-music (cadr music-list) 'Voice "two"))))
(set! (ly:music-property m 'elements) (list m1 m2))
+ (ly:run-translator m2 part-combine-listener)
+ (ly:run-translator m1 part-combine-listener)
(set! (ly:music-property m 'split-list)
- (determine-split-list (reverse! (cdr (assoc "one" evs1)) '())
- (reverse! (cdr (assoc "two" evs2)) '())))
+ (determine-split-list (reverse! (cdr (assoc "one" noticed)) '())
+ (reverse! (cdr (assoc "two" noticed)) '())))
+ (set! noticed '())
m))
(define-public (determine-split-list evl1 evl2)
(let* ((vs1 (car (voice-states now-state)))
(vs2 (cdr (voice-states now-state)))
(notes1 (note-events vs1))
- (durs1 (sort (map (lambda (x) (ly:event-property x 'duration))
+ (durs1 (sort (map (lambda (x) (ly:music-property x 'duration))
notes1)
ly:duration<?))
- (pitches1 (sort (map (lambda (x) (ly:event-property x 'pitch))
+ (pitches1 (sort (map (lambda (x) (ly:music-property x 'pitch))
notes1)
ly:pitch<?))
(notes2 (note-events vs2))
- (durs2 (sort (map (lambda (x) (ly:event-property x 'duration))
+ (durs2 (sort (map (lambda (x) (ly:music-property x 'duration))
notes2)
ly:duration<?))
- (pitches2 (sort (map (lambda (x) (ly:event-property x 'pitch))
+ (pitches2 (sort (map (lambda (x) (ly:music-property x 'pitch))
notes2)
ly:pitch<?)))
(cond ((> (length notes1) 1) (put 'apart))
(notes2 (note-events vs2)))
(cond ((and (= 1 (length notes1))
(= 1 (length notes2))
- (equal? (ly:event-property (car notes1) 'pitch)
- (ly:event-property (car notes2) 'pitch)))
+ (equal? (ly:music-property (car notes1) 'pitch)
+ (ly:music-property (car notes2) 'pitch)))
(set! (configuration now-state) 'unisono))
((and (= 0 (length notes1))
(= 0 (length notes2)))
(define (try-solo type start-idx current-idx)
"Find a maximum stretch that can be marked as solo. Only set
-the mark when there are no spanners active.
-
- return next idx to analyse.
-"
+the mark when there are no spanners active."
(if (< current-idx (vector-length result))
(let* ((now-state (vector-ref result current-idx))
(solo-state (current-voice-state now-state (if (equal? type 'solo1) 1 2)))
current-idx)
((and
(null? (span-state solo-state)))
-
;;
;; This includes rests. This isn't a problem: long rests
;; will be shared with the silent voice, and be marked
(define-public (add-quotable name mus)
(set! noticed '())
(let* ((tab (eval 'musicQuotes (current-module)))
- (context-list (recording-group-emulate (context-spec-music mus 'Voice)
- part-combine-listener)))
- (if (pair? context-list)
+ (context (ly:run-translator (context-spec-music mus 'Voice)
+ part-combine-listener))
+ (first-voice-handle (last-pair noticed)))
+
+ (if (pair? first-voice-handle)
(hash-set! tab name
;; cdr : skip name string
- (list->vector (reverse! (cdar context-list)
+ (list->vector (reverse! (cdar first-voice-handle)
'()))))))
+
(define-public (make-ps-images ps-name . rest)
(let-optional
rest ((resolution 90)
- page-width
- page-height
+ (paper-size "a4")
(rename-page-1? #f)
(verbose? #f)
(aa-factor 1)
)
-
+
(let* ((base (basename (re-sub "[.]e?ps" "" ps-name)))
(png1 (string-append base ".png"))
(pngn (string-append base "-page%d.png"))
;;
(gs-variable-options
(if multi-page?
- (format #f "-dDEVICEWIDTHPOINTS=~,2f -dDEVICEHEIGHTPOINTS=~,2f" page-width page-height)
+ (format #f "-sPAPERSIZE=~a" paper-size)
"-dEPSCrop"))
(cmd (format #f "~a\
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2004--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(map
(lambda (sym)
ly:output-def-scope
ly:output-description
ly:paper-book?
- ly:prob-property
ly:layout-def?
ly:paper-get-font
ly:paper-get-number
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2000--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(set! default-script-alist
(append
'(("thumb" .
((script-stencil . (feta . ("thumb" . "thumb")))
- (avoid-slur . inside)
- (padding . 0.20)
(direction . 1)))
("accent" .
((avoid-slur . around)
- (padding . 0.20)
(quantize-position . #t)
(script-stencil . (feta . ("sforzato" . "sforzato")))
(side-relative-direction . -1)))
("espressivo" .
((avoid-slur . around)
- (padding . 0.20)
(quantize-position . #t)
(script-stencil . (feta . ("espr" . "espr")))
(side-relative-direction . -1)))
("marcato" .
((script-stencil . (feta . ("dmarcato" . "umarcato")))
- (padding . 0.20)
- (avoid-slur . inside)
; (staff-padding . ())
(quantize-position . #t)
(side-relative-direction . -1)))
("staccatissimo" .
((avoid-slur . inside)
(script-stencil . (feta . ("dstaccatissimo" . "ustaccatissimo")))
- (padding . 0.20)
(side-relative-direction . -1)))
("portato" .
((script-stencil . (feta . ("uportato" . "dportato")))
- (avoid-slur . around)
- (slur-padding . 0.3)
- (padding . 0.45)
(side-relative-direction . -1)))
("accentus" .
((script-stencil . (feta . ("uaccentus" . "uaccentus")))
(side-relative-direction . -1)
- (padding . 0.20)
(quantize-position . #t)
(script-priority . -100)
(direction . 1)))
((script-stencil . (feta . ("ictus" . "ictus")))
(side-relative-direction . -1)
(quantize-position . #t)
- (padding . 0.20)
(script-priority . -100)
(direction . -1)))
("semicirculus" .
((script-stencil . (feta . ("dsemicirculus" . "dsemicirculus")))
(side-relative-direction . -1)
(quantize-position . #t)
- (padding . 0.20)
(script-priority . -100)
(direction . 1)))
("circulus" .
((script-stencil . (feta . ("circulus" . "circulus")))
(side-relative-direction . -1)
- (padding . 0.20)
(quantize-position . #t)
(script-priority . -100)
(direction . 1)))
("signumcongruentiae" .
((script-stencil . (feta . ("dsignumcongruentiae" . "usignumcongruentiae")))
- (padding . 0.20)
(direction . 1)))
("fermata" .
((script-stencil . (feta . ("dfermata" . "ufermata")))
- (padding . 0.20)
(avoid-slur . around)
(script-priority . 4000)
(direction . 1)))
("shortfermata" .
((script-stencil . (feta . ("dshortfermata" . "ushortfermata")))
- (padding . 0.20)
(direction . 1)))
("longfermata" .
((script-stencil . (feta . ("dlongfermata" . "ulongfermata")))
- (padding . 0.20)
(direction . 1)))
("verylongfermata" .
((script-stencil . (feta . ("dverylongfermata" . "uverylongfermata")))
- (padding . 0.20)
(direction . 1)))
("stopped" .
((script-stencil . (feta . ("stopped" . "stopped")))
- (avoid-slur . inside)
- (padding . 0.20)
(direction . 1)))
("staccato" .
((script-stencil . (feta . ("staccato" . "staccato")))
(side-relative-direction . -1)
(quantize-position . #t)
(avoid-slur . inside)
- (padding . 0.20)
(script-priority . -100)))
("tenuto" .
((script-stencil . (feta . ("tenuto" . "tenuto")))
(quantize-position . #t)
(avoid-slur . inside)
- (padding . 0.20)
(side-relative-direction . -1)))
("comma" .
((script-stencil . (feta . ("lcomma" . "rcomma")))
(quantize-position . #t)
- (padding . 0.20)
(direction . 1)))
("varcomma" .
((script-stencil . (feta . ("lvarcomma" . "rvarcomma")))
(quantize-position . #t)
- (padding . 0.20)
(direction . 1)))
("upbow" .
((script-stencil . (feta . ("upbow" . "upbow")))
(avoid-slur . around)
- (padding . 0.20)
(direction . 1)))
("downbow" .
((script-stencil . (feta . ("downbow" . "downbow")))
- (padding . 0.20)
(avoid-slur . around)
(direction . 1)))
("lheel" .
((script-stencil . (feta . ("upedalheel" . "upedalheel")))
- (padding . 0.20)
(direction . -1))
)
("rheel" .
((script-stencil . (feta . ("dpedalheel" . "dpedalheel")))
- (padding . 0.20)
(direction . 1)))
("ltoe" .
((script-stencil . (feta . ("upedaltoe" . "upedaltoe")))
- (padding . 0.20)
(direction . -1)))
("rtoe" .
((script-stencil . (feta . ("dpedaltoe" . "dpedaltoe")))
- (padding . 0.20)
(direction . 1)))
("turn" .
((script-stencil . (feta . ("turn" . "turn")))
- (avoid-slur . inside)
- (padding . 0.20)
(direction . 1)))
("open" .
((avoid-slur . outside)
- (padding . 0.20)
- (script-stencil . (feta . ("open" . "open")))
+ (script-stencil . (feta . ("open" . "open")))
(direction . 1)))
("flageolet" .
((script-stencil . (feta . ("flageolet" . "flageolet")))
- (padding . 0.20)
(direction . 1)))
("reverseturn" .
((script-stencil . (feta . ("reverseturn" . "reverseturn")))
- (padding . 0.20)
(direction . 1)))
("trill" .
((script-stencil . (feta . ("trill" . "trill")))
(direction . 1)
- (padding . 0.20)
(avoid-slur . outside)
(script-priority . 2000)))
("prall" .
((script-stencil . (feta . ("prall" . "prall")))
- (padding . 0.20)
(direction . 1)))
("mordent" .
((script-stencil . (feta . ("mordent" . "mordent")))
- (padding . 0.20)
(direction . 1)))
("prallprall" .
((script-stencil . (feta . ("prallprall" . "prallprall")))
- (padding . 0.20)
(direction . 1)))
("prallmordent" .
((script-stencil . (feta . ("prallmordent" . "prallmordent")))
- (padding . 0.20)
(direction . 1)))
("upprall" .
((script-stencil . (feta . ("upprall" . "upprall")))
- (padding . 0.20)
(direction . 1)))
("downprall" .
((script-stencil . (feta . ("downprall" . "downprall")))
- (padding . 0.20)
(direction . 1)))
("upmordent" .
((script-stencil . (feta . ("upmordent" . "upmordent")))
- (padding . 0.20)
(direction . 1)))
("downmordent" .
((script-stencil . (feta . ("downmordent" . "downmordent")))
- (padding . 0.20)
(direction . 1)))
("lineprall" .
((script-stencil . (feta . ("lineprall" . "lineprall")))
- (padding . 0.20)
(direction . 1)))
("pralldown" .
((script-stencil . (feta . ("pralldown" . "pralldown")))
- (padding . 0.20)
(direction . 1)))
("prallup" .
((script-stencil . (feta . ("prallup" . "prallup")))
- (padding . 0.20)
(direction . 1)))
("segno" .
((script-stencil . (feta . ("segno" . "segno")))
- (padding . 0.20)
(direction . 1)))
("coda" .
((script-stencil . (feta . ("coda" . "coda")))
- (padding . 0.20)
(direction . 1)))
("varcoda" .
((script-stencil . (feta . ("varcoda" . "varcoda")))
- (padding . 0.20)
(direction . 1))))
default-script-alist)
)
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 1998--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define standalone (not (defined? 'ly:gulp-file)))
;;(write standalone (current-error-port))
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-public (stack-stencils axis dir padding stils)
"Stack stencils STILS in direction AXIS, DIR, using PADDING."
;; spacing variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define*-public (annotate-y-interval layout name extent is-length
- #:key (color darkblue))
- (let ((text-props (cons '((font-size . -3)
- (font-family . typewriter))
- (layout-extract-page-properties layout)))
- (annotation #f))
- (define (center-stencil-on-extent stil)
- (ly:stencil-translate (ly:stencil-aligned-to stil Y CENTER)
- (cons 0 (interval-center extent))))
+(define-public (annotate-y-interval layout name extent is-length)
+ (let*
+ ((text-props (cons
+ '((font-size . -3)
+ (font-family . typewriter))
+ (layout-extract-page-properties layout)))
+ (annotation #f)
+ )
+
;; do something sensible for 0,0 intervals.
(set! extent (interval-widen extent 0.001))
(if (not (interval-sane? extent))
- (set! annotation (interpret-markup
- layout text-props
- (make-simple-markup (format "~a: NaN/inf" name))))
- (let ((text-stencil (interpret-markup
- layout text-props
- (markup #:whiteout #:simple name)))
- (dim-stencil (interpret-markup
- layout text-props
- (markup #:whiteout
- #:simple (cond
- ((interval-empty? extent)
- (format "empty"))
- (is-length
- (format "~$" (interval-length extent)))
- (else
- (format "(~$,~$)"
- (car extent) (cdr extent)))))))
- (arrows (ly:stencil-translate-axis
- (dimension-arrows (cons 0 (interval-length extent)))
- (interval-start extent) Y)))
+ (set! annotation (interpret-markup layout text-props
+ (make-simple-markup (format "~a: NaN/inf" name))))
+ (let*
+ ((text-stencil (interpret-markup
+ layout text-props
+ (make-column-markup
+ (list
+ (make-whiteout-markup (make-simple-markup name))
+ (make-whiteout-markup
+ (make-simple-markup
+ (cond
+ ((interval-empty? extent) "empty")
+ (is-length (format "~$" (interval-length extent)))
+ (else
+ (format "(~$,~$)" (car extent)
+ (cdr extent))))))))))
+ (arrows
+ (ly:stencil-translate-axis
+ (dimension-arrows (cons 0 (interval-length extent)))
+ (interval-start extent) Y)))
+
(set! annotation
- (center-stencil-on-extent text-stencil))
+ (ly:stencil-aligned-to text-stencil Y CENTER))
+
+ (set! annotation (ly:stencil-translate
+ annotation
+ (cons 0 (interval-center extent))))
+
+
(set! annotation
(ly:stencil-combine-at-edge arrows X RIGHT annotation 0.5 0))
+
(set! annotation
- (ly:stencil-combine-at-edge annotation X LEFT
- (center-stencil-on-extent dim-stencil)
- 0.5 0))
- (set! annotation
- (ly:make-stencil (list 'color color (ly:stencil-expr annotation))
+ (ly:make-stencil (ly:stencil-expr annotation)
(ly:stencil-extent annotation X)
(cons 10000 -10000)))))
annotation))
(write-system-signatures basename (cdr paper-systems) (1+ count))))))
-(use-modules (scm paper-system))
(define-public (write-system-signature filename paper-system)
(define (float? x)
(and (number? x) (inexact? x)))
rest))
expr))
+ (define (music-cause grob)
+ (let*
+ ((cause (ly:grob-property grob 'cause)))
+
+ (cond
+ ((ly:music? cause) cause)
+ ((ly:grob? cause) (music-cause cause))
+ (else #f))))
(define (pythonic-string expr)
"escape quotes and slashes for python consumption"
- (regexp-substitute/global #f "([\n\\\\'\"])" (format "~a" expr) 'pre "\\" 1 'post))
+ (regexp-substitute/global #f "([\\\\'\"])" (format "~a" expr) 'pre "\\" 1 'post))
(define (pythonic-pair expr)
(format "(~a,~a)"
(car expr) (cdr expr)))
-
-
- (define (raw-string expr)
- "escape quotes and slashes for python consumption"
- (regexp-substitute/global #f "[@\n]" (format "~a" expr) 'pre " " 'post))
-
- (define (raw-pair expr)
- (format "~a ~a"
- (car expr) (cdr expr)))
-
+
(define (found-grob expr)
(let*
((grob (car expr))
(rest (cdr expr))
(collected '())
- (cause (event-cause grob))
- (input (if (ly:stream-event? cause) (ly:event-property cause 'origin) #f))
+ (cause (music-cause grob))
+ (input (if (ly:music? cause) (ly:music-property cause 'origin) #f))
(location (if (ly:input-location? input) (ly:input-file-line-char-column input) '()))
(x-ext (ly:grob-extent grob system-grob X))
rest)
(format output
- "~a@~a@~a@~a@~a\n"
+ "['~a', '~a', ~a, ~a, '~a'],\n"
(cdr (assq 'name (ly:grob-property grob 'meta) ))
- (raw-string location)
- (raw-pair (if (interval-empty? x-ext) '(1 . -1) x-ext))
- (raw-pair (if (interval-empty? y-ext) '(1 . -1) y-ext))
- (raw-string collected))
+ (pythonic-string location)
+ (pythonic-pair (if (interval-empty? x-ext) '(0 . 0) x-ext))
+ (pythonic-pair (if (interval-empty? y-ext) '(0 . 0) y-ext))
+ (pythonic-string collected))
))
(define (interpret-for-signature escape collect expr)
output)
(interpret-for-signature found-grob (lambda (x) #f)
(ly:stencil-expr
- (paper-system-stencil paper-system)))))
-
- ;; should be superfluous, but leaking "too many open files"?
- (close-port output))
+ (paper-system-stencil paper-system))))))
;;;; source file of the GNU LilyPond music typesetter
;;;;
;;;; (c) 2004--2006 Jan Nieuwenhuizen <janneke@gnu.org>
-;;;; Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Han-Wen Nienhuys <hanwen@cs.uu.nl>
(define-public (layout-extract-page-properties layout)
(list (append `((line-width . ,(ly:paper-get-number
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 2003--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
(use-modules (ice-9 regex)
;;;;
;;;; source file of the GNU LilyPond music typesetter
;;;;
-;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; (c) 1998--2006 Han-Wen Nienhuys <hanwen@cs.uu.nl>
;;;; Jan Nieuwenhuizen <janneke@gnu.org>
+(define-public (denominator-tuplet-formatter mus)
+ (number->string (ly:music-property mus 'denominator)))
+
+(define-public (fraction-tuplet-formatter mus)
+ (string-append
+ (number->string (ly:music-property mus 'denominator))
+ ":"
+ (number->string (ly:music-property mus 'numerator))))
+
;; metronome marks
-(define-public (format-metronome-markup dur count context)
- (let* ((note-mark (make-smaller-markup
- (make-note-by-number-markup (ly:duration-log dur)
- (ly:duration-dot-count dur)
- 1))))
+(define-public (format-metronome-markup event context)
+ (let* ((dur (ly:music-property event 'tempo-unit))
+ (count (ly:music-property event 'metronome-count))
+ (note-mark (make-smaller-markup
+ (make-note-by-number-markup (ly:duration-log dur)
+ (ly:duration-dot-count dur)
+ 1))))
(make-line-markup
(list
(make-general-align-markup Y DOWN note-mark)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-public (format-bass-figure figure event context)
- (let* ((fig (ly:event-property event 'figure))
+ (let* ((fig (ly:music-property event 'figure))
(fig-markup (if (number? figure)
;; this is not very elegant, but center-aligning all digits
(lambda (y) (make-translate-scaled-markup (cons -0.7 0) y))
identity)
- (if (eq? #t (ly:event-property event 'diminished))
+ (if (eq? #t (ly:music-property event 'diminished))
(markup #:slashed-digit figure)
(markup #:number (number->string figure 10))))
#f
))
- (alt (ly:event-property event 'alteration))
+ (alt (ly:music-property event 'alteration))
(alt-markup
(if (number? alt)
(markup
(alteration->text-accidental-markup alt))
#f))
- (plus-markup (if (eq? #t (ly:event-property event 'augmented))
+ (plus-markup (if (eq? #t (ly:music-property event 'augmented))
(markup #:number "+")
#f))
program_name = sys.argv[0]
-for d in ['@lilypond_datadir@',
- '@lilypond_libdir@']:
- sys.path.insert (0, os.path.join (d, 'python'))
+datadir = '@local_lilypond_datadir@'
+if not os.path.isdir (datadir):
+ datadir = '@lilypond_datadir@'
+
+sys.path.insert (0, os.path.join (datadir, 'python'))
+
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir= datadir[:-1]
+
+ datadir = os.path.join (datadir, "share/lilypond/current/")
+sys.path.insert (0, os.path.join (datadir, 'python'))
# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
+bindir = os.path.split (sys.argv[0])[0]
for p in ['share', 'lib']:
datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
- sys.path.insert (0, datadir)
-
+ sys.path.insert (0, os.path.join (datadir))
import lilylib as ly
global _;_=ly._
def slyrics_append(a):
a = re.sub ( '_', ' _ ', a) # _ to ' _ '
a = re.sub ( '-', '- ', a) # split words with -
- a = re.sub ( ' - - ', ' -- ', a) # unless was originally " -- "
a = re.sub ( '\\\\- ', '-', a) # unless \-
a = re.sub ( '~', '_', a) # ~ to space('_')
a = re.sub ( '\*', '_ ', a) # * to to space
'~' : '^"~" ',
'J' : '', # ignore slide
'R' : '', # ignore roll
- 'S' : '^\\segno',
- 'O' : '^\\coda',
'v' : '^\\downbow'
}
#convention, such as most music written before 1700, or ethnic music in
#non-western scales, it is necessary to be able to tell a translator that
#the barlines should not affect its interpretation of the pitch.
- if 'nobarlines' in str:
+ if (string.find(str,'nobarlines') > 0):
nobarlines = 1
elif str[0:3] == '%LY':
p = string.find(str, 'voices')
datadir = '@local_lilypond_datadir@'
if not os.path.isdir (datadir):
- datadir = '@lilypond_datadir@'
+ datadir = '@lilypond_datadir@'
sys.path.insert (0, os.path.join (datadir, 'python'))
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir= datadir[:-1]
+
+ datadir = os.path.join (datadir, "share/lilypond/current/")
+sys.path.insert (0, os.path.join (datadir, 'python'))
+
# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
+bindir = os.path.split (sys.argv[0])[0]
for p in ['share', 'lib']:
- datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
- sys.path.insert (0, datadir)
+ datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
+ sys.path.insert (0, datadir)
import lilylib as ly
global _;_=ly._
''')
copyright = ('Jan Nieuwenhuizen <janneke@gnu.org>',
- 'Han-Wen Nienhuys <hanwen@cs.uu.nl>')
+ 'Han-Wen Nienhuys <hanwen@cs.uu.nl>')
program_name = os.path.basename (sys.argv[0])
program_version = '@TOPLEVEL_VERSION@'
+add_version = 1
+
def warning (s):
- sys.stderr.write (program_name + ": " + _ ("warning: %s") % s + '\n')
+ sys.stderr.write (program_name + ": " + _ ("warning: %s") % s + '\n')
def error (s):
- sys.stderr.write (program_name + ": " + _ ("error: %s") % s + '\n')
+ sys.stderr.write (program_name + ": " + _ ("error: %s") % s + '\n')
def identify (port=sys.stderr):
- port.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version))
+ port.write ('%s (GNU LilyPond) %s\n' % (program_name, program_version))
def warranty ():
- identify ()
- sys.stdout.write ('''
+ identify ()
+ sys.stdout.write ('''
Copyright (c) %s by
Han-Wen Nienhuys
def get_option_parser ():
- p = ly.get_option_parser (usage='convert-ly [OPTIONS] FILE',
- version="@TOPLEVEL_VERSION@",
- description=help_summary)
-
- p.add_option ('-f', '--from',
- action="store",
- metavar=_ ("VERSION"),
- dest="from_version",
- help=_('start from VERSION [default: \\version found in file]'),
- default='')
-
- p.add_option ('-e', '--edit', help=_('edit in place'),
- action='store_true')
- p.add_option ('-n', '--no-version',
- help=_ ('do not add \\version command if missing'),
- action='store_true',
- dest='skip_version_add',
- default=False)
-
- p.add_option ("-s", '--show-rules',
- help=_('print rules [default: --from=0, --to=@TOPLEVEL_VERSION@]'),
- dest='show_rules',
- action='store_true', default=False)
-
- p.add_option ('-t', '--to',
- help=_('convert to VERSION [default: @TOPLEVEL_VERSION@]'),
- metavar=_('VERSION'),
- action='store',
- dest="to_version",
- default='')
-
- p.add_option_group ('bugs',
- description='''Report bugs via http://post.gmane.org/post.php'''
- '''?group=gmane.comp.gnu.lilypond.bugs\n''')
-
- return p
+ p = ly.get_option_parser (usage='convert-ly [OPTIONS] FILE',
+ version="@TOPLEVEL_VERSION@",
+ description=help_summary)
+
+ p.add_option ('-f', '--from',
+ action="store",
+ metavar=_ ("VERSION"),
+ dest="from_version",
+ help=_('start from VERSION [default: \\version found in file]'),
+ default='')
+
+ p.add_option ('-e', '--edit', help=_('edit in place'),
+ action='store_true')
+ p.add_option ('-n', '--no-version',
+ help=_ ('do not add \\version command if missing'),
+ action='store_true',
+ dest='skip_version_add',
+ default=False)
+
+ p.add_option ("-s", '--show-rules',
+ help=_('print rules [default: --from=0, --to=@TOPLEVEL_VERSION@]'),
+ dest='show_rules',
+ action='store_true', default=False)
+
+ p.add_option ('-t', '--to',
+ help=_('convert to VERSION [default: @TOPLEVEL_VERSION@]'),
+ metavar=_('VERSION'),
+ action='store',
+ dest="to_version",
+ default='')
+
+ p.add_option_group ('bugs',
+ description='''Report bugs via http://post.gmane.org/post.php'''
+ '''?group=gmane.comp.gnu.lilypond.bugs\n''')
+
+ return p
def str_to_tuple (s):
- return tuple (map (int, string.split (s, '.')))
+ return tuple (map (int, string.split (s, '.')))
def tup_to_str (t):
- return string.join (map (lambda x: '%s' % x, list (t)), '.')
+ return string.join (map (lambda x: '%s' % x, list (t)), '.')
def version_cmp (t1, t2):
- for x in [0, 1, 2]:
- if t1[x] - t2[x]:
- return t1[x] - t2[x]
- return 0
+ for x in [0, 1, 2]:
+ if t1[x] - t2[x]:
+ return t1[x] - t2[x]
+ return 0
def get_conversions (from_version, to_version):
- def is_applicable (v, f = from_version, t = to_version):
- return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
- return filter (is_applicable, conversions)
+ def is_applicable (v, f = from_version, t = to_version):
+ return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
+ return filter (is_applicable, conversions)
def latest_version ():
- return conversions[-1][0]
+ return conversions[-1][0]
def show_rules (file, from_version, to_version):
- for x in conversions:
- if (not from_version or x[0] > from_version) \
- and (not to_version or x[0] <= to_version):
- file.write ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
+ for x in conversions:
+ if (not from_version or x[0] > from_version) \
+ and (not to_version or x[0] <= to_version):
+ file.write ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
def do_conversion (str, from_version, to_version):
- """Apply conversions from FROM_VERSION to TO_VERSION. Return
+ """Apply conversions from FROM_VERSION to TO_VERSION. Return
tuple (LAST,STR), with the last succesful conversion and the resulting
string."""
- conv_list = get_conversions (from_version, to_version)
+ conv_list = get_conversions (from_version, to_version)
- if error_file:
- error_file.write (_ ("Applying conversion: "))
-
- last_conversion = ()
- try:
- for x in conv_list:
- error_file.write (tup_to_str (x[0]))
- if x != conv_list[-1]:
- error_file.write (', ')
- str = x[1] (str)
- last_conversion = x[0]
+ if error_file:
+ error_file.write (_ ("Applying conversion: "))
+
+ last_conversion = ()
+ try:
+ for x in conv_list:
+ error_file.write (tup_to_str (x[0]))
+ if x != conv_list[-1]:
+ error_file.write (', ')
+ str = x[1] (str)
+ last_conversion = x[0]
- except FatalConversionError:
- error_file.write (_ ("error while converting"))
- error_file.write ('\n')
- error_file.write (_ ("Aborting"))
- error_file.write ('\n')
+ except FatalConversionError:
+ error_file.write (_ ("error while converting"))
+ error_file.write ('\n')
+ error_file.write (_ ("Aborting"))
+ error_file.write ('\n')
- return (last_conversion, str)
+ return (last_conversion, str)
def guess_lilypond_version (filename):
- s = open (filename).read ()
- m = lilypond_version_re.search (s)
- if m:
- return m.group (1)
- else:
- return ''
+ s = open (filename).read ()
+ m = lilypond_version_re.search (s)
+ if m:
+ return m.group (1)
+ else:
+ return ''
class FatalConversionError:
- pass
+ pass
class UnknownVersion:
- pass
+ pass
def do_one_file (infile_name):
- sys.stderr.write (_ ("Processing `%s\'... ") % infile_name)
- sys.stderr.write ('\n')
-
- from_version = None
- to_version = None
- if global_options.from_version:
- from_version = global_options.from_version
- else:
- guess = guess_lilypond_version (infile_name)
- if not guess:
- raise UnknownVersion ()
- from_version = str_to_tuple (guess)
-
- if global_options.to_version:
- to_version = global_options.to_version
- else:
- to_version = latest_version ()
-
-
- if infile_name:
- infile = open (infile_name, 'r')
- else:
- infile = sys.stdin
-
-
- (last, result) = do_conversion (infile.read (), from_version, to_version)
- infile.close ()
-
- if last:
- newversion = r'\version "%s"' % tup_to_str (last)
- if lilypond_version_re.search (result):
- result = re.sub (lilypond_version_re_str,
- '\\' + newversion, result)
- elif not global_options.skip_version_add:
- result = newversion + '\n' + result
-
- error_file.write ('\n')
-
- if global_options.edit:
- try:
- os.remove(infile_name + '~')
- except:
- pass
- os.rename (infile_name, infile_name + '~')
- outfile = open (infile_name, 'w')
- else:
- outfile = sys.stdout
-
-
- outfile.write (result)
-
- sys.stderr.flush ()
+ sys.stderr.write (_ ("Processing `%s\'... ") % infile_name)
+ sys.stderr.write ('\n')
+
+ from_version = None
+ to_version = None
+ if global_options.from_version:
+ from_version = global_options.from_version
+ else:
+ guess = guess_lilypond_version (infile_name)
+ if not guess:
+ raise UnknownVersion ()
+ from_version = str_to_tuple (guess)
+
+ if global_options.to_version:
+ to_version = global_options.to_version
+ else:
+ to_version = latest_version ()
+
+
+ if infile_name:
+ infile = open (infile_name, 'r')
+ else:
+ infile = sys.stdin
+
+
+ (last, result) = do_conversion (infile.read (), from_version, to_version)
+ infile.close ()
+
+ if last:
+ newversion = r'\version "%s"' % tup_to_str (last)
+ if lilypond_version_re.search (result):
+ result = re.sub (lilypond_version_re_str,
+ '\\' + newversion, result)
+ elif add_version:
+ result = newversion + '\n' + result
+
+ error_file.write ('\n')
+
+ if global_options.edit:
+ try:
+ os.remove(infile_name + '~')
+ except:
+ pass
+ os.rename (infile_name, infile_name + '~')
+ outfile = open (infile_name, 'w')
+ else:
+ outfile = sys.stdout
+
+
+ outfile.write (result)
+
+ sys.stderr.flush ()
def do_options ():
- opt_parser = get_option_parser()
- (options, args) = opt_parser.parse_args ()
+ opt_parser = get_option_parser()
+ (options, args) = opt_parser.parse_args ()
- if options.from_version:
- options.from_version = str_to_tuple (options.from_version)
- if options.to_version:
- options.to_version = str_to_tuple (options.to_version)
+ if options.from_version:
+ options.from_version = str_to_tuple (options.from_version)
+ if options.to_version:
+ options.to_version = str_to_tuple (options.to_version)
- options.outfile_name = ''
- global global_options
- global_options = options
+ options.outfile_name = ''
+ global global_options
+ global_options = options
- if not args and not options.show_rules:
- opt_parser.print_help ()
- sys.exit (2)
+ if not args and not options.show_rules:
+ opt_parser.print_help ()
+ sys.exit (2)
- return args
+ return args
def main ():
- files = do_options ()
-
- # should parse files[] to read \version?
- if global_options.show_rules:
- show_rules (sys.stdout, global_options.from_version, global_options.to_version)
- sys.exit (0)
-
- identify (sys.stderr)
-
- for f in files:
- if f == '-':
- f = ''
- elif not os.path.isfile (f):
- error (_ ("can't open file: `%s'") % f)
- if len (files) == 1:
- sys.exit (1)
- continue
- try:
- do_one_file (f)
- except UnknownVersion:
- error (_ ("can't determine version for `%s'. Skipping") % f)
-
- sys.stderr.write ('\n')
+ files = do_options ()
+
+ # should parse files[] to read \version?
+ if global_options.show_rules:
+ show_rules (sys.stdout, global_options.from_version, global_options.to_version)
+ sys.exit (0)
+
+ identify (sys.stderr)
+
+ for f in files:
+ if f == '-':
+ f = ''
+ elif not os.path.isfile (f):
+ error (_ ("can't open file: `%s'") % f)
+ if len (files) == 1:
+ sys.exit (1)
+ continue
+ try:
+ do_one_file (f)
+ except UnknownVersion:
+ error (_ ("can't determine version for `%s'. Skipping") % f)
+
+ sys.stderr.write ('\n')
main ()
################################################################
# Users of python modules should include this snippet.
#
-
-
-
-
-for d in ['@lilypond_datadir@',
- '@lilypond_libdir@']:
- sys.path.insert (0, os.path.join (d, 'python'))
-
+libdir = '@local_lilypond_libdir@'
+if not os.path.isdir (libdir):
+ libdir = '@lilypond_libdir@'
+
+# ugh
+datadir = '@local_lilypond_datadir@'
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir= datadir[:-1]
+ libdir = datadir.replace ('/share/', '/lib/')
+
+if os.path.exists (os.path.join (datadir, 'lib/lilypond/@TOPLEVEL_VERSION@/')):
+ libdir = os.path.join (libdir, 'lib/lilypond/@TOPLEVEL_VERSION@/')
+
+if os.path.exists (os.path.join (datadir, 'lib/lilypond/current/')):
+ libdir = os.path.join (libdir, 'lib/lilypond/current/')
+
+sys.path.insert (0, os.path.join (libdir, 'python'))
# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
+bindir = os.path.split (sys.argv[0])[0]
for p in ['share', 'lib']:
datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
sys.path.insert (0, datadir)
-
################################################################
import lilylib as ly
import sys
import re
+# Users of python modules should include this snippet
+# and customize variables below.
+
+# We'll suffer this path initialization stuff as long as we don't install
+# our python packages in <prefix>/lib/pythonX.Y
+
+# If set, LILYPONDPREFIX must take prevalence.
+# if datadir is not set, we're doing a build and LILYPONDPREFIX.
+
################
# RELOCATION
################
+datadir = '@local_lilypond_datadir@'
+if not os.path.isdir (datadir):
+ datadir = '@lilypond_datadir@'
+
+sys.path.insert (0, os.path.join (datadir, 'python'))
+
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir = datadir[:-1]
-for d in ['@lilypond_datadir@',
- '@lilypond_libdir@']:
- sys.path.insert (0, os.path.join (d, 'python'))
+ if not os.path.exists (os.path.join (datadir, 'python/lilylib.py')):
+ datadir = os.path.join (datadir, 'share/lilypond/current/')
+sys.path.insert (0, os.path.join (datadir, 'python'))
# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
+bindir = os.path.split (sys.argv[0])[0]
-os.environ['PATH'] = bindir + os.pathsep + os.environ['PATH']
-for p in ['share', 'lib']:
- datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
+
+for prefix_component in ['share', 'lib']:
+ datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % prefix_component)
sys.path.insert (0, datadir)
p.add_option ('-f', '--format',
help=_('''use output format FORMAT (texi [default], texi-html, latex, html)'''),
action='store')
-
p.add_option ("-I", '--include', help=_('add DIR to include path'),
metavar="DIR",
action='append', dest='include_path',
help = _ ("process ly_files using COMMAND FILE..."),
action='store',
dest='process_cmd', default='lilypond -b eps')
-
- p.add_option ('--pdf',
- action="store_true",
- dest="create_pdf",
- help="Create PDF files for use with PDFTeX",
- default=False)
p.add_option ('', '--psfonts', action="store_true", dest="psfonts",
help=_ ('''extract all PostScript fonts into INPUT.psfonts for LaTeX'''
LATEX: {
OUTPUT: r'''{%%
\parindent 0pt%%
+\catcode`\@=12%%
\ifx\preLilyPondExample \undefined%%
\relax%%
\else%%
PREAMBLE_LY = '''%%%% Generated by %(program_name)s
%%%% Options: [%(option_string)s]
-\\include "lilypond-book-preamble.ly"
+
+#(set! toplevel-score-handler print-score-with-defaults)
+#(set! toplevel-music-handler
+ (lambda (p m)
+ (if (not (eq? (ly:music-property m \'void) #t))
+ (print-score-with-defaults
+ p (scorify-music m p)))))
+
+#(ly:set-option (quote no-point-and-click))
+#(define inside-lilypond-book #t)
+#(define version-seen? #t)
%(preamble_string)s
%% ****************************************************************
\paper {
- #(define dump-extents #t)
- %(font_dump_setting)s
- %(paper_string)s
+ #(define dump-extents #t)
+ %(font_dump_setting)s
+ %(paper_string)s
}
\layout {
- %(layout_string)s
+ %(layout_string)s
}
'''
self.do_options (os, self.type)
def ly (self):
- contents = self.substring ('code')
- return ('\\sourcefileline %d\n%s'
- % (self.line_number - 1, contents))
+ return self.substring ('code')
def full_ly (self):
s = self.ly ()
options = split_options (option_string)
for i in options:
- if '=' in i:
+ if string.find (i, '=') > 0:
(key, value) = re.split ('\s*=\s*', i)
self.option_dict[key] = value
else:
if VERBATIM in self.option_dict:
verb = self.substring ('code')
str += (output[LATEX][VERBATIM] % vars ())
-
+
str += (output[LATEX][OUTPUT] % vars ())
## todo: maintain breaks
## strip version string to make automated regtest comparisons
## across versions easier.
contents = re.sub (r'\\version *"[^"]*"', '', contents)
-
- return ('\\sourcefilename \"%s\"\n\\sourcefileline 0\n%s'
+
+ return ('\\sourcefilename \"%s\"\n%s'
% (name, contents))
snippet_type_to_class = {
snippets = []
index = 0
- found = dict ([(t, None) for t in types])
+ found = dict ((t, None) for t in types)
line_starts = find_linestarts (s)
line_start_idx = 0
status = 0
def my_system (cmd):
status = ly.system (cmd,
- be_verbose=global_options.verbose,
- progress_p=1)
+ be_verbose=global_options.verbose,
+ progress_p= 1)
if global_options.format in (HTML, TEXINFO):
- cmd += ' --formats=png '
+ cmd += ' --format png '
# UGH
# the --process=CMD switch is a bad idea
my_system ('latex %s.texstr' % l)
if ly_names:
- open ('snippet-names', 'wb').write ('\n'.join (['snippet-map.ly']
- + ly_names))
-
- my_system (string.join ([cmd, 'snippet-names']))
-
+ my_system (string.join ([cmd, 'snippet-map.ly'] + ly_names))
LATEX_INSPECTION_DOCUMENT = r'''
\nonstopmode
def write_file_map (lys, name):
snippet_map = open ('snippet-map.ly', 'w')
snippet_map.write ("""
-#(define version-seen #t)
+#(define version-seen? #t)
#(ly:add-file-name-alist '(
""")
for ly in lys:
- snippet_map.write ('("%s.ly" . "%s")\n'
+ snippet_map.write ('("%s.ly" . "%s:%d (%s.ly)")\n'
% (ly.basename (),
- name))
+ name,
+ ly.line_number,
+ ly.basename ()))
snippet_map.write ('))\n')
formats = 'ps'
if global_options.format in (TEXINFO, HTML):
formats += ',png'
-
-
if global_options.process_cmd == '':
- global_options.process_cmd = (lilypond_binary
- + ' --formats=%s --backend eps ' % formats)
+ global_options.process_cmd = lilypond_binary \
+ + ' --formats=%s --backend eps ' % formats
if global_options.process_cmd:
- global_options.process_cmd += string.join ([(' -I %s' % ly.mkarg (p))
+ global_options.process_cmd += string.join ([(' -I %s' % commands.mkarg (p))
for p in global_options.include_path])
- if global_options.format in (TEXINFO, LATEX):
- ## prevent PDF from being switched on by default.
- global_options.process_cmd += ' --formats=eps '
-
- if (global_options.format in (TEXINFO, LATEX)
- and global_options.create_pdf):
- global_options.process_cmd += "--pdf -dinclude-eps-fonts -dgs-load-fonts "
-
-
-
- if global_options.verbose:
- global_options.process_cmd += " --verbose "
-
- global_options.process_cmd += " -dread-file-list -dpad-eps-boxes "
-
identify ()
try:
exit (1)
if global_options.format in (TEXINFO, LATEX):
+ if not global_options.psfonts:
+ warning (_ ("option --psfonts not used"))
+ warning (_ ("processing with dvips will have no fonts"))
+
psfonts_file = os.path.join (global_options.output_name, basename + '.psfonts')
output = os.path.join (global_options.output_name, basename + '.dvi' )
- if not global_options.psfonts and not global_options.create_pdf:
- warning (_ ("option --psfonts not used"))
- warning (_ ("processing with dvips will have no fonts"))
- else:
- progress ('\n')
- progress (_ ("DVIPS usage:"))
- progress ('\n')
- progress (" dvips -h %(psfonts_file)s %(output)s" % vars ())
- progress ('\n')
+ progress ('\n')
+ progress (_ ("DVIPS usage:"))
+ progress ('\n')
+ progress (" dvips -h %(psfonts_file)s %(output)s" % vars ())
+ progress ('\n')
inputs = note_input_file ('')
inputs.pop ()
################################################################
# Users of python modules should include this snippet.
#
+libdir = '@local_lilypond_libdir@'
+if not os.path.isdir (libdir):
+ libdir = '@lilypond_libdir@'
-for d in ['@lilypond_datadir@',
- '@lilypond_libdir@']:
- sys.path.insert (0, os.path.join (d, 'python'))
+# ugh
+datadir = '@local_lilypond_datadir@'
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir= datadir[:-1]
+ libdir = datadir.replace ('/share/', '/lib/')
+
+if os.path.exists (os.path.join (datadir, 'lib/lilypond/@TOPLEVEL_VERSION@/')):
+ libdir = os.path.join (libdir, 'lib/lilypond/@TOPLEVEL_VERSION@/')
+
+if os.path.exists (os.path.join (datadir, 'lib/lilypond/current/')):
+ libdir = os.path.join (libdir, 'lib/lilypond/current/')
+
+sys.path.insert (0, os.path.join (libdir, 'python'))
# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
-for p in ['share', 'lib']:
- datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
- sys.path.insert (0, datadir)
+bindir = os.path.split (sys.argv[0])[0]
+for prefix_component in ['share', 'lib']:
+ datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % prefix_component)
+ sys.path.insert (0, datadir)
import midi
import lilylib as ly
-for d in ['@lilypond_datadir@',
- '@lilypond_libdir@']:
- sys.path.insert (0, os.path.join (d, 'python'))
-# dynamic relocation, for GUB binaries.
-bindir = os.path.abspath (os.path.split (sys.argv[0])[0])
-for p in ['share', 'lib']:
- datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p)
- sys.path.insert (0, datadir)
+datadir = '@local_lilypond_datadir@'
+if not os.path.isdir (datadir):
+ datadir = '@lilypond_datadir@'
+if os.environ.has_key ('LILYPONDPREFIX'):
+ datadir = os.environ['LILYPONDPREFIX']
+ while datadir[-1] == os.sep:
+ datadir = datadir[:-1]
+
+if os.path.exists (os.path.join (datadir, 'share/lilypond/@TOPLEVEL_VERSION@/')):
+ datadir = os.path.join (datadir, 'share/lilypond/@TOPLEVEL_VERSION@/')
+elif os.path.exists (os.path.join (datadir, 'share/lilypond/current/')):
+ datadir = os.path.join (datadir, 'share/lilypond/current/')
+sys.path.insert (0, os.path.join (datadir, 'python'))
+# dynamic relocation, for GUB binaries.
+bindir = os.path.split (sys.argv[0])[0]
+
+for prefix_component in ['share', 'lib']:
+ datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % prefix_component)
+ sys.path.insert (0, datadir)
import lilylib as ly
try:
(n,a) = {
'major' : (0,0),
- 'minor' : (5,0),
+ 'minor' : (6,0),
}[mode]
start_pitch.step = n
start_pitch.alteration = a
fifth.step *= -1
fifth.normalize ()
+ start_pitch = musicexp.Pitch()
for x in range (fifths):
start_pitch = start_pitch.transposed (fifth)
## -V: Workaround for python
changequote(<<, >>)#dnl
-
## Assume and hunt for dotted version multiplet.
## use eval trickery, because we cannot use multi-level $() instead of ``
## for compatibility reasons.
-
- ## grab the first version number in --version output.
- eval _ver=\"\`("$1" --version || "$1" -V) 2>&1 | grep '\(^\| \)[0-9][0-9]*\.[0-9]' \
+ ## FIXME: what systems still do not have $() in /bin/sh?
+ eval _ver=\"\`("$1" --version || "$1" -V) 2>&1 | grep '[0-9]\.[0-9]' \
| head -n 1 \
- | tr ' ' '\n' | grep '[0-9]\.[0-9]' | head -n 1 | sed 's/\([0-9.]*\).*/\1/g'\`\"
-
+ | sed -e 's/.*[^-.0-9]\([0-9][0-9]*\.[0-9][.0-9]*\).*/\1/' \
+ -e 's/^[^.0-9]*//' -e 's/[^.0-9]*$//'\`\"
if test -z "$_ver"; then
## If empty, try date [fontforge]
eval _ver=\"\`("$1" --version || "$1" -V) 2>&1 | grep '[0-9]\{6,8\}' \
build_package_datadir=$ugh_ugh_autoconf250_builddir/out$CONFIGSUFFIX/share/$package
- DATADIR=`echo ${datadir} | sed "s!\\\${datarootdir}!${prefix}/share!"`
- DATADIR=`echo ${DATADIR} | sed "s!\\\${prefix}!$presome!"`
+ DATADIR=`echo ${datadir} | sed "s!\\\${prefix}!$presome!"`
BUILD_PACKAGE_DATADIR=`echo ${build_package_datadir} | sed "s!\\\${prefix}!$presome!"`
AC_SUBST(datadir)
- AC_SUBST(datarootdir)
AC_SUBST(build_package_datadir)
AC_DEFINE_UNQUOTED(DATADIR, ["${DATADIR}"])
AC_DEFINE_UNQUOTED(BUILD_PACKAGE_DATADIR, ["${BUILD_PACKAGE_DATADIR}"])
of @PACKAGE_NAME@
"""
-built = r'''
+built = r"""
<div style="background-color: #e8ffe8; padding: 2; border: #c0ffc0 1px solid;">
%(wiki_string)s
<p>
Report errors to <a href="%(mail_address_url)s">%(mail_address)s</a>.</font></address>
</p>
</div>
-'''
-
+"""
+def gulp_file (f):
+ try:
+ i = open(f)
+ i.seek (0, 2)
+ n = i.tell ()
+ i.seek (0,0)
+ except:
+ sys.stderr.write ("can't open file: %s\n" % f)
+ return ''
+ s = i.read (n)
+ if len (s) <= 0:
+ sys.stderr.write ("gulped empty file: %s\n" % f)
+ i.close ()
+ return s
def help ():
sys.stdout.write (r"""Usage: add-html-footer [OPTIONS]... HTML-FILE
def compose (default, file):
s = default
if file:
- s = open (file).read ()
+ s = gulp_file (file)
return s
set_gcos ()
return s
def do_file (f):
- s = open (f).read()
+ s = gulp_file (f)
s = re.sub ('%', '%%', s)
prepend \`local-' to restrict operation to the current directory.\n\
Example: \`local-clean'.\n"
-# "
local-help:
local-dist: $(DIST_FILES) $(OUT_DIST_FILES) $(NON_ESSENTIAL_DIST_FILES)
src-wildcard = $(subst $(src-dir)/,,$(wildcard $(src-dir)/$(1)))
ifeq ($(distdir),)
- distdir = $(top-build-dir)/$(outdir)/$(DIST_NAME)
+ distdir = $(top-src-dir)/$(outdir)/$(DIST_NAME)
DIST_NAME = $(package)-$(TOPLEVEL_VERSION)
endif
distname = $(package)-$(TOPLEVEL_VERSION)
$(outdir)/%/%.html: $(outdir)/%.texi
$(MAKEINFO) --output=$@ --css-include=$(top-src-dir)/Documentation/texinfo.css --html $<
-$(outdir)/%.pdf: $(outdir)/%.texi
- cd $(outdir); texi2pdf $(TEXI2PDF_FLAGS) --batch $(TEXINFO_PAPERSIZE_OPTION) $(<F)
+
+$(outdir)/%.dvi: $(outdir)/%.texi
+ cd $(outdir); texi2dvi $(TEXI2DVI_FLAGS) --batch $(TEXINFO_PAPERSIZE_OPTION) $(<F)
$(outdir)/%.txt: $(outdir)/%.texi
$(MAKEINFO) -I $(src-dir) -I $(outdir) --no-split --no-headers --output $@ $<
default: local-doc
-local-WWW: $(HTML_FILES) $(PDF_FILES) $(TO_TOP_FILES)
+copy-to-top: $(TO_TOP_FILES)
+ $(foreach i, $(TO_TOP_FILES), \
+ cp $(i) $(top-build-dir) && ) true
+
+local-WWW: $(HTML_FILES) $(PDF_FILES) copy-to-top
-make-txt-files: $(addprefix $(outdir)/,$(addsuffix .txt,$(TO_TOP_FILES)))
do-top-doc:
- -$(MAKE) -C Documentation/topdocs/ TO_TOP_FILES="$(TOPDOC_FILES)" make-txt-files
+ -$(MAKE) -C Documentation/topdocs/ README_TOP_FILES="$(README_TXT_FILES)" copy-to-top
$(README_TXT_FILES): do-top-doc
depth = ..
TEX_FILES = $(filter-out texinfo.tex, $(call src-wildcard,*.tex))
-EXTRA_DIST_FILES = $(TEX_FILES) texinfo.tex texinfo.cnf quotes.patch
+EXTRA_DIST_FILES = $(TEX_FILES) texinfo.tex texinfo.cnf
STEPMAKE_TEMPLATES=install install-out
INSTALLATION_DIR=$(local_lilypond_datadir)/tex/
+++ /dev/null
---- texinfo/doc/texinfo.tex 2006-06-02 03:19:04.000000000 +0200
-+++ texinfo.tex 2006-06-02 03:19:10.000000000 +0200
-@@ -1878,9 +1878,12 @@
- {
- \catcode`\-=\active
- \catcode`\_=\active
-+ \catcode`\'=\active
- %
- \global\def\code{\begingroup
- \catcode`\-=\active \catcode`\_=\active
-+ \catcode`\'=\active
-+ \let'\singlequotechar
- \ifallowcodebreaks
- \let-\codedash
- \let_\codeunder
-@@ -5059,11 +5062,10 @@
- %
- \maketwodispenvs {lisp}{example}{%
- \nonfillstart
-- \tt
-+ \tt\quoteexpand
- \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
- \gobble % eat return
- }
--
- % @display/@smalldisplay: same as @lisp except keep current font.
- %
- \makedispenv {display}{%
-@@ -5191,6 +5193,12 @@
- \newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
- %
- \def\starttabbox{\setbox0=\hbox\bgroup}
-+%
-+%
-+% Don't replace quotes with curly quotes. This makes cut & pasting
-+% from a PDF file problematic.
-+%
-+\def\singlequotechar{\char'15\relax}
- \begingroup
- \catcode`\^^I=\active
- \gdef\tabexpand{%
-@@ -5203,6 +5211,11 @@
- \wd0=\dimen0 \box0 \starttabbox
- }%
- }
-+ \catcode`\'=\active
-+ \gdef\quoteexpand{%
-+ \catcode`\'=\active
-+ \def'{\singlequotechar}
-+ }%
- \endgroup
- \def\setupverbatim{%
- \let\nonarrowing = t%
-@@ -5212,6 +5225,7 @@
- \def\par{\leavevmode\egroup\box0\endgraf}%
- \catcode`\`=\active
- \tabexpand
-+ \quoteexpand
- % Respect line breaks,
- % print special symbols as themselves, and
- % make each space count
-@c -*- coding: utf-8 -*-
-
-@c We map some UTF-8 characters to corresponding texinfo macros.
+@c We map some latin-1 characters to corresponding texinfo macros.
@tex
-
-% This UTF-8 parser is based on LaTeX's `utf8.def'.
-
-\newcount\countX
-\newcount\countY
-\newcount\countZ
-
-\gdef\UTFviiiTwoOctets#1#2{%
- \expandafter
- \UTFviiiDefined\csname u8:#1\string #2\endcsname}
-\gdef\UTFviiiThreeOctets#1#2#3{%
- \expandafter
- \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
-\gdef\UTFviiiFourOctets#1#2#3#4{%
- \expandafter
- \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
-
-\gdef\UTFviiiDefined#1{%
- \ifx #1\relax
- \message{%
- \linenumber Unicode char \string #1 not set up for use with texinfo}
- \else
- \expandafter #1%
- \fi
-}
-
-\begingroup
- \catcode`\~13
- \catcode`\"12
-
- \def\UTFviiiLoop{%
- \global\catcode\countX\active
- \uccode`\~\countX
- \uppercase\expandafter{\UTFviiiTmp}%
- \advance\countX by 1
- \ifnum\countX < \countY
- \expandafter\UTFviiiLoop
- \fi}
-
- \countX = "C2
- \countY = "E0
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
- \UTFviiiLoop
-
- \countX = "E0
- \countY = "F0
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
- \UTFviiiLoop
-
- \countX = "F0
- \countY = "F4
- \def\UTFviiiTmp{%
- \xdef~{\noexpand\UTFviiiFourOctets\string~}}
- \UTFviiiLoop
-\endgroup
-
-\begingroup
- \catcode`\"=12
- \catcode`\<=12
- \catcode`\.=12
- \catcode`\,=12
- \catcode`\;=12
- \catcode`\!=12
- \catcode`\~=13
-
- \gdef\DeclareUnicodeCharacter#1#2{%
- \countZ = "#1\relax
- \wlog{\space\space defining Unicode char U+#1 (decimal \the\countZ)}%
- \begingroup
- \parseXMLCharref
- \def\UTFviiiTwoOctets##1##2{%
- \csname u8:##1\string ##2\endcsname}%
- \def\UTFviiiThreeOctets##1##2##3{%
- \csname u8:##1\string ##2\string ##3\endcsname}%
- \def\UTFviiiFourOctets##1##2##3##4{%
- \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
- \expandafter\expandafter\expandafter\expandafter
- \expandafter\expandafter\expandafter
- \gdef\UTFviiiTmp{#2}%
- \endgroup}
-
- \gdef\parseXMLCharref{%
- \ifnum\countZ < "A0\relax
- \errhelp = \EMsimple
- \errmessage{Cannot define Unicode char value < 00A0}%
- \else\ifnum\countZ < "800\relax
- \parseUTFviiiA,%
- \parseUTFviiiB C\UTFviiiTwoOctets.,%
- \else\ifnum\countZ < "10000\relax
- \parseUTFviiiA;%
- \parseUTFviiiA,%
- \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
- \else
- \parseUTFviiiA;%
- \parseUTFviiiA,%
- \parseUTFviiiA!%
- \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
- \fi\fi\fi
- }
-
- \gdef\parseUTFviiiA#1{%
- \countX = \countZ
- \divide\countZ by 64
- \countY = \countZ
- \multiply\countZ by 64
- \advance\countX by -\countZ
- \advance\countX by 128
- \uccode `#1\countX
- \countZ = \countY}
-
- \gdef\parseUTFviiiB#1#2#3#4{%
- \advance\countZ by "#10\relax
- \uccode `#3\countZ
- \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
-\endgroup
-
-\DeclareUnicodeCharacter{00A0}{\tie}
-\DeclareUnicodeCharacter{00A1}{\exclamdown} % ¡
-\DeclareUnicodeCharacter{00A3}{\pounds} % £
-\DeclareUnicodeCharacter{00A8}{\"{ }} % ¨
-\DeclareUnicodeCharacter{00A9}{\copyright} % ©
-\DeclareUnicodeCharacter{00AA}{\ordf} % ª
-\DeclareUnicodeCharacter{00AD}{\-} % discretionary hyphen
-\DeclareUnicodeCharacter{00AE}{\registeredsymbol} % ®
-\DeclareUnicodeCharacter{00AF}{\={ }} % ¯
-
-\DeclareUnicodeCharacter{00B0}{\ringaccent{ }} % °
-\DeclareUnicodeCharacter{00B4}{\'{ }} % ´
-\DeclareUnicodeCharacter{00B8}{\,{ }} % ¸
-\DeclareUnicodeCharacter{00BA}{\ordm} % º
-\DeclareUnicodeCharacter{00BF}{\questiondown} % ¿
-
-\DeclareUnicodeCharacter{00C0}{\`A} % À
-\DeclareUnicodeCharacter{00C1}{\'A} % Á
-\DeclareUnicodeCharacter{00C2}{\^A} % Â
-\DeclareUnicodeCharacter{00C3}{\~A} % Ã
-\DeclareUnicodeCharacter{00C4}{\"A} % Ä
-\DeclareUnicodeCharacter{00C5}{\AA} % Å
-\DeclareUnicodeCharacter{00C6}{\AE} % Æ
-\DeclareUnicodeCharacter{00C7}{\,{C}} % Ç
-\DeclareUnicodeCharacter{00C8}{\`E} % È
-\DeclareUnicodeCharacter{00C9}{\'E} % É
-\DeclareUnicodeCharacter{00CA}{\^E} % Ê
-\DeclareUnicodeCharacter{00CB}{\"E} % Ë
-\DeclareUnicodeCharacter{00CC}{\`I} % Ì
-\DeclareUnicodeCharacter{00CD}{\'I} % Í
-\DeclareUnicodeCharacter{00CE}{\^I} % Î
-\DeclareUnicodeCharacter{00CF}{\"I} % Ï
-
-\DeclareUnicodeCharacter{00D1}{\~N} % Ñ
-\DeclareUnicodeCharacter{00D2}{\`O} % Ò
-\DeclareUnicodeCharacter{00D3}{\'O} % Ó
-\DeclareUnicodeCharacter{00D4}{\^O} % Ô
-\DeclareUnicodeCharacter{00D5}{\~O} % Õ
-\DeclareUnicodeCharacter{00D6}{\"O} % Ö
-\DeclareUnicodeCharacter{00D8}{\O} % Ø
-\DeclareUnicodeCharacter{00D9}{\`U} % Ù
-\DeclareUnicodeCharacter{00DA}{\'U} % Ú
-\DeclareUnicodeCharacter{00DB}{\^U} % Û
-\DeclareUnicodeCharacter{00DC}{\"U} % Ü
-\DeclareUnicodeCharacter{00DD}{\'Y} % Ý
-\DeclareUnicodeCharacter{00DF}{\ss} % ß
-
-\DeclareUnicodeCharacter{00E0}{\`a} % à
-\DeclareUnicodeCharacter{00E1}{\'a} % á
-\DeclareUnicodeCharacter{00E2}{\^a} % â
-\DeclareUnicodeCharacter{00E3}{\~a} % ã
-\DeclareUnicodeCharacter{00E4}{\"a} % ä
-\DeclareUnicodeCharacter{00E5}{\aa} % å
-\DeclareUnicodeCharacter{00E6}{\ae} % æ
-\DeclareUnicodeCharacter{00E7}{\,{c}} % ç
-\DeclareUnicodeCharacter{00E8}{\`e} % è
-\DeclareUnicodeCharacter{00E9}{\'e} % é
-\DeclareUnicodeCharacter{00EA}{\^e} % ê
-\DeclareUnicodeCharacter{00EB}{\"e} % ë
-\DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} % ì
-\DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} % í
-\DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} % î
-\DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} % ï
-
-\DeclareUnicodeCharacter{00F1}{\~n} % ñ
-\DeclareUnicodeCharacter{00F2}{\`o} % ò
-\DeclareUnicodeCharacter{00F3}{\'o} % ó
-\DeclareUnicodeCharacter{00F4}{\^o} % ô
-\DeclareUnicodeCharacter{00F5}{\~o} % õ
-\DeclareUnicodeCharacter{00F6}{\"o} % ö
-\DeclareUnicodeCharacter{00F8}{\o} % ø
-\DeclareUnicodeCharacter{00F9}{\`u} % ù
-\DeclareUnicodeCharacter{00FA}{\'u} % ú
-\DeclareUnicodeCharacter{00FB}{\^u} % û
-\DeclareUnicodeCharacter{00FC}{\"u} % ü
-\DeclareUnicodeCharacter{00FD}{\'y} % ý
-\DeclareUnicodeCharacter{00FF}{\"y} % ÿ
-
-\DeclareUnicodeCharacter{0100}{\=A} % Ā
-\DeclareUnicodeCharacter{0101}{\=a} % ā
-\DeclareUnicodeCharacter{0102}{\u{A}} % Ă
-\DeclareUnicodeCharacter{0103}{\u{a}} % ă
-\DeclareUnicodeCharacter{0106}{\'C} % Ć
-\DeclareUnicodeCharacter{0107}{\'c} % ć
-\DeclareUnicodeCharacter{0108}{\^C} % Ĉ
-\DeclareUnicodeCharacter{0109}{\^c} % ĉ
-\DeclareUnicodeCharacter{010A}{\dotaccent{C}} % Ċ
-\DeclareUnicodeCharacter{010B}{\dotaccent{c}} % ċ
-\DeclareUnicodeCharacter{010C}{\v{C}} % Č
-\DeclareUnicodeCharacter{010D}{\v{c}} % č
-\DeclareUnicodeCharacter{010E}{\v{D}} % Ď
-%\DeclareUnicodeCharacter{010F}{\v{d}} % ď
-
-\DeclareUnicodeCharacter{0112}{\=E} % Ē
-\DeclareUnicodeCharacter{0113}{\=e} % ē
-\DeclareUnicodeCharacter{0114}{\u{E}} % Ĕ
-\DeclareUnicodeCharacter{0115}{\u{e}} % ĕ
-\DeclareUnicodeCharacter{0116}{\dotaccent{E}} % Ė
-\DeclareUnicodeCharacter{0117}{\dotaccent{e}} % ė
-\DeclareUnicodeCharacter{011A}{\v{E}} % Ě
-\DeclareUnicodeCharacter{011B}{\v{e}} % ě
-\DeclareUnicodeCharacter{011C}{\^G} % Ĝ
-\DeclareUnicodeCharacter{011D}{\^g} % ĝ
-\DeclareUnicodeCharacter{011E}{\u{G}} % Ğ
-\DeclareUnicodeCharacter{011F}{\u{g}} % ğ
-
-\DeclareUnicodeCharacter{0120}{\dotaccent{G}} % Ġ
-\DeclareUnicodeCharacter{0121}{\dotaccent{g}} % ġ
-\DeclareUnicodeCharacter{0124}{\^H} % Ĥ
-\DeclareUnicodeCharacter{0125}{\^h} % ĥ
-\DeclareUnicodeCharacter{0128}{\~I} % Ĩ
-\DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} % ĩ
-\DeclareUnicodeCharacter{012A}{\=I} % Ī
-\DeclareUnicodeCharacter{012B}{\={\dotless{i}}} % ī
-\DeclareUnicodeCharacter{012C}{\u{I}} % Ĭ
-\DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} % ĭ
-
-\DeclareUnicodeCharacter{0130}{\dotaccent{I}} % İ
-\DeclareUnicodeCharacter{0131}{\dotless{i}} % ı
-\DeclareUnicodeCharacter{0132}{IJ} % IJ
-\DeclareUnicodeCharacter{0133}{ij} % ij
-\DeclareUnicodeCharacter{0134}{\^J} % Ĵ
-\DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} % ĵ
-\DeclareUnicodeCharacter{0139}{\'L} % Ĺ
-\DeclareUnicodeCharacter{013A}{\'l} % ĺ
-
-\DeclareUnicodeCharacter{0141}{\L} % Ł
-\DeclareUnicodeCharacter{0142}{\l} % ł
-\DeclareUnicodeCharacter{0143}{\'N} % Ń
-\DeclareUnicodeCharacter{0144}{\'n} % ń
-\DeclareUnicodeCharacter{0147}{\v{N}} % Ň
-\DeclareUnicodeCharacter{0148}{\v{n}} % ň
-\DeclareUnicodeCharacter{014C}{\=O} % Ō
-\DeclareUnicodeCharacter{014D}{\=o} % ō
-\DeclareUnicodeCharacter{014E}{\u{O}} % Ŏ
-\DeclareUnicodeCharacter{014F}{\u{o}} % ŏ
-
-\DeclareUnicodeCharacter{0150}{\H{O}} % Ő
-\DeclareUnicodeCharacter{0151}{\H{o}} % ő
-\DeclareUnicodeCharacter{0152}{\OE} % Œ
-\DeclareUnicodeCharacter{0153}{\oe} % œ
-\DeclareUnicodeCharacter{0154}{\'R} % Ŕ
-\DeclareUnicodeCharacter{0155}{\'r} % ŕ
-\DeclareUnicodeCharacter{0158}{\v{R}} % Ř
-\DeclareUnicodeCharacter{0159}{\v{r}} % ř
-\DeclareUnicodeCharacter{015A}{\'S} % Ś
-\DeclareUnicodeCharacter{015B}{\'s} % ś
-\DeclareUnicodeCharacter{015C}{\^S} % Ŝ
-\DeclareUnicodeCharacter{015D}{\^s} % ŝ
-\DeclareUnicodeCharacter{015E}{\,{S}} % Ş
-\DeclareUnicodeCharacter{015F}{\,{s}} % ş
-
-\DeclareUnicodeCharacter{0160}{\v{S}} % Š
-\DeclareUnicodeCharacter{0161}{\v{s}} % š
-\DeclareUnicodeCharacter{0162}{\,{t}} % Ţ
-\DeclareUnicodeCharacter{0163}{\,{T}} % ţ
-\DeclareUnicodeCharacter{0164}{\v{T}} % Ť
-%\DeclareUnicodeCharacter{0165}{\v{t}} % ť
-\DeclareUnicodeCharacter{0168}{\~U} % Ũ
-\DeclareUnicodeCharacter{0169}{\~u} % ũ
-\DeclareUnicodeCharacter{016A}{\=U} % Ū
-\DeclareUnicodeCharacter{016B}{\=u} % ū
-\DeclareUnicodeCharacter{016C}{\u{U}} % Ŭ
-\DeclareUnicodeCharacter{016D}{\u{u}} % ŭ
-\DeclareUnicodeCharacter{016E}{\ringaccent{U}} % Ů
-\DeclareUnicodeCharacter{016F}{\ringaccent{u}} % ů
-
-\DeclareUnicodeCharacter{0170}{\H{U}} % Ű
-\DeclareUnicodeCharacter{0171}{\H{u}} % ű
-\DeclareUnicodeCharacter{0174}{\^W} % Ŵ
-\DeclareUnicodeCharacter{0175}{\^w} % ŵ
-\DeclareUnicodeCharacter{0176}{\^Y} % Ŷ
-\DeclareUnicodeCharacter{0177}{\^y} % ŷ
-\DeclareUnicodeCharacter{0178}{\"Y} % Ÿ
-\DeclareUnicodeCharacter{0179}{\'Z} % Ź
-\DeclareUnicodeCharacter{017A}{\'z} % ź
-\DeclareUnicodeCharacter{017B}{\dotaccent{Z}} % Ż
-\DeclareUnicodeCharacter{017C}{\dotaccent{z}} % ż
-\DeclareUnicodeCharacter{017D}{\v{Z}} % Ž
-\DeclareUnicodeCharacter{017E}{\v{z}} % ž
-
-\DeclareUnicodeCharacter{01C4}{D\v{Z}} % DŽ
-\DeclareUnicodeCharacter{01C5}{D\v{z}} % Dž
-\DeclareUnicodeCharacter{01C6}{d\v{z}} % dž
-\DeclareUnicodeCharacter{01C7}{LJ} % LJ
-\DeclareUnicodeCharacter{01C8}{Lj} % Lj
-\DeclareUnicodeCharacter{01C9}{lj} % lj
-\DeclareUnicodeCharacter{01CA}{NJ} % NJ
-\DeclareUnicodeCharacter{01CB}{Nj} % Nj
-\DeclareUnicodeCharacter{01CC}{nj} % nj
-\DeclareUnicodeCharacter{01CD}{\v{A}} % Ǎ
-\DeclareUnicodeCharacter{01CE}{\v{a}} % ǎ
-\DeclareUnicodeCharacter{01CF}{\v{I}} % Ǐ
-
-\DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} % ǐ
-\DeclareUnicodeCharacter{01D1}{\v{O}} % Ǒ
-\DeclareUnicodeCharacter{01D2}{\v{o}} % ǒ
-\DeclareUnicodeCharacter{01D3}{\v{U}} % Ǔ
-\DeclareUnicodeCharacter{01D4}{\v{u}} % ǔ
-
-\DeclareUnicodeCharacter{01E2}{\={\AE}} % Ǣ
-\DeclareUnicodeCharacter{01E3}{\={\ae}} % ǣ
-\DeclareUnicodeCharacter{01E6}{\v{G}} % Ǧ
-\DeclareUnicodeCharacter{01E7}{\v{g}} % ǧ
-\DeclareUnicodeCharacter{01E8}{\v{K}} % Ǩ
-\DeclareUnicodeCharacter{01E9}{\v{k}} % ǩ
-
-\DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} % ǰ
-\DeclareUnicodeCharacter{01F1}{DZ} % DZ
-\DeclareUnicodeCharacter{01F2}{Dz} % Dz
-\DeclareUnicodeCharacter{01F3}{dz} % dz
-\DeclareUnicodeCharacter{01F4}{\'G} % Ǵ
-\DeclareUnicodeCharacter{01F5}{\'g} % ǵ
-\DeclareUnicodeCharacter{01F8}{\`N} % Ǹ
-\DeclareUnicodeCharacter{01F9}{\`n} % ǹ
-\DeclareUnicodeCharacter{01FC}{\'{\AE}} % Ǽ
-\DeclareUnicodeCharacter{01FD}{\'{\ae}} % ǽ
-\DeclareUnicodeCharacter{01FE}{\'{\O}} % Ǿ
-\DeclareUnicodeCharacter{01FF}{\'{\o}} % ǿ
-
-\DeclareUnicodeCharacter{021E}{\v{H}} % Ȟ
-\DeclareUnicodeCharacter{021F}{\v{h}} % ȟ
-
-\DeclareUnicodeCharacter{0226}{\dotaccent{A}} % Ȧ
-\DeclareUnicodeCharacter{0227}{\dotaccent{a}} % ȧ
-\DeclareUnicodeCharacter{0228}{\,{E}} % Ȩ
-\DeclareUnicodeCharacter{0229}{\,{e}} % ȩ
-\DeclareUnicodeCharacter{022E}{\dotaccent{O}} % Ȯ
-\DeclareUnicodeCharacter{022F}{\dotaccent{o}} % ȯ
-
-\DeclareUnicodeCharacter{0232}{\=Y} % Ȳ
-\DeclareUnicodeCharacter{0233}{\=y} % ȳ
-\DeclareUnicodeCharacter{0237}{\dotless{j}} % ȷ
-
-\DeclareUnicodeCharacter{1E02}{\dotaccent{B}} % Ḃ
-\DeclareUnicodeCharacter{1E03}{\dotaccent{b}} % ḃ
-\DeclareUnicodeCharacter{1E04}{\udotaccent{B}} % Ḅ
-\DeclareUnicodeCharacter{1E05}{\udotaccent{b}} % ḅ
-\DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} % Ḇ
-\DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} % ḇ
-\DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} % Ḋ
-\DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} % ḋ
-\DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} % Ḍ
-\DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} % ḍ
-\DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} % Ḏ
-\DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} % ḏ
-
-\DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} % Ḟ
-\DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} % ḟ
-
-\DeclareUnicodeCharacter{1E20}{\=G} % Ḡ
-\DeclareUnicodeCharacter{1E21}{\=g} % ḡ
-\DeclareUnicodeCharacter{1E22}{\dotaccent{H}} % Ḣ
-\DeclareUnicodeCharacter{1E23}{\dotaccent{h}} % ḣ
-\DeclareUnicodeCharacter{1E24}{\udotaccent{H}} % Ḥ
-\DeclareUnicodeCharacter{1E25}{\udotaccent{h}} % ḥ
-\DeclareUnicodeCharacter{1E26}{\"H} % Ḧ
-\DeclareUnicodeCharacter{1E27}{\"h} % ḧ
-
-\DeclareUnicodeCharacter{1E30}{\'K} % Ḱ
-\DeclareUnicodeCharacter{1E31}{\'k} % ḱ
-\DeclareUnicodeCharacter{1E32}{\udotaccent{K}} % Ḳ
-\DeclareUnicodeCharacter{1E33}{\udotaccent{k}} % ḳ
-\DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} % Ḵ
-\DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} % ḵ
-\DeclareUnicodeCharacter{1E36}{\udotaccent{L}} % Ḷ
-\DeclareUnicodeCharacter{1E37}{\udotaccent{l}} % ḷ
-\DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} % Ḻ
-\DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} % ḻ
-\DeclareUnicodeCharacter{1E3E}{\'M} % Ḿ
-\DeclareUnicodeCharacter{1E3F}{\'m} % ḿ
-
-\DeclareUnicodeCharacter{1E40}{\dotaccent{M}} % Ṁ
-\DeclareUnicodeCharacter{1E41}{\dotaccent{m}} % ṁ
-\DeclareUnicodeCharacter{1E42}{\udotaccent{M}} % Ṃ
-\DeclareUnicodeCharacter{1E43}{\udotaccent{m}} % ṃ
-\DeclareUnicodeCharacter{1E44}{\dotaccent{N}} % Ṅ
-\DeclareUnicodeCharacter{1E45}{\dotaccent{n}} % ṅ
-\DeclareUnicodeCharacter{1E46}{\udotaccent{N}} % Ṇ
-\DeclareUnicodeCharacter{1E47}{\udotaccent{n}} % ṇ
-\DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} % Ṉ
-\DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} % ṉ
-
-\DeclareUnicodeCharacter{1E54}{\'P} % Ṕ
-\DeclareUnicodeCharacter{1E55}{\'p} % ṕ
-\DeclareUnicodeCharacter{1E56}{\dotaccent{P}} % Ṗ
-\DeclareUnicodeCharacter{1E57}{\dotaccent{p}} % ṗ
-\DeclareUnicodeCharacter{1E58}{\dotaccent{R}} % Ṙ
-\DeclareUnicodeCharacter{1E59}{\dotaccent{r}} % ṙ
-\DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} % Ṛ
-\DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} % ṛ
-\DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} % Ṟ
-\DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} % ṟ
-
-\DeclareUnicodeCharacter{1E60}{\dotaccent{S}} % Ṡ
-\DeclareUnicodeCharacter{1E61}{\dotaccent{s}} % ṡ
-\DeclareUnicodeCharacter{1E62}{\udotaccent{S}} % Ṣ
-\DeclareUnicodeCharacter{1E63}{\udotaccent{s}} % ṣ
-\DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} % Ṫ
-\DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} % ṫ
-\DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} % Ṭ
-\DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} % ṭ
-\DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} % Ṯ
-\DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} % ṯ
-
-\DeclareUnicodeCharacter{1E7C}{\~V} % Ṽ
-\DeclareUnicodeCharacter{1E7D}{\~v} % ṽ
-\DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} % Ṿ
-\DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} % ṿ
-
-\DeclareUnicodeCharacter{1E80}{\`W} % Ẁ
-\DeclareUnicodeCharacter{1E81}{\`w} % ẁ
-\DeclareUnicodeCharacter{1E82}{\'W} % Ẃ
-\DeclareUnicodeCharacter{1E83}{\'w} % ẃ
-\DeclareUnicodeCharacter{1E84}{\"W} % Ẅ
-\DeclareUnicodeCharacter{1E85}{\"w} % ẅ
-\DeclareUnicodeCharacter{1E86}{\dotaccent{W}} % Ẇ
-\DeclareUnicodeCharacter{1E87}{\dotaccent{w}} % ẇ
-\DeclareUnicodeCharacter{1E88}{\udotaccent{W}} % Ẉ
-\DeclareUnicodeCharacter{1E89}{\udotaccent{w}} % ẉ
-\DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} % Ẋ
-\DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} % ẋ
-\DeclareUnicodeCharacter{1E8C}{\"X} % Ẍ
-\DeclareUnicodeCharacter{1E8D}{\"x} % ẍ
-\DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} % Ẏ
-\DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} % ẏ
-
-\DeclareUnicodeCharacter{1E90}{\^Z} % Ẑ
-\DeclareUnicodeCharacter{1E91}{\^z} % ẑ
-\DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} % Ẓ
-\DeclareUnicodeCharacter{1E93}{\udotaccent{z}} % ẓ
-\DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} % Ẕ
-\DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} % ẕ
-\DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} % ẖ
-\DeclareUnicodeCharacter{1E97}{\"t} % ẗ
-\DeclareUnicodeCharacter{1E98}{\ringaccent{w}} % ẘ
-\DeclareUnicodeCharacter{1E99}{\ringaccent{y}} % ẙ
-
-\DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} % Ạ
-\DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} % ạ
-
-\DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} % Ẹ
-\DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} % ẹ
-\DeclareUnicodeCharacter{1EBC}{\~E} % Ẽ
-\DeclareUnicodeCharacter{1EBD}{\~e} % ẽ
-
-\DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} % Ị
-\DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} % ị
-\DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} % Ọ
-\DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} % ọ
-
-\DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} % Ụ
-\DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} % ụ
-
-\DeclareUnicodeCharacter{1EF2}{\`Y} % Ỳ
-\DeclareUnicodeCharacter{1EF3}{\`y} % ỳ
-\DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} % Ỵ
-%\DeclareUnicodeCharacter{1EF5}{\udotaccent{y}} % ỵ
-\DeclareUnicodeCharacter{1EF8}{\~Y} % Ỹ
-\DeclareUnicodeCharacter{1EF9}{\~y} % ỹ
-
-\DeclareUnicodeCharacter{2013}{--} % –
-\DeclareUnicodeCharacter{2014}{---} % —
-\DeclareUnicodeCharacter{2022}{\bullet} % •
-\DeclareUnicodeCharacter{2026}{\dots} % …
-\DeclareUnicodeCharacter{20AC}{\euro} % €
-
-\DeclareUnicodeCharacter{2192}{\expansion} % →
-\DeclareUnicodeCharacter{21D2}{\result} % ⇒
-
-\DeclareUnicodeCharacter{2212}{\minus} % −
-\DeclareUnicodeCharacter{2217}{\point} % ∗
-\DeclareUnicodeCharacter{2261}{\equiv} % ≡
-
+\global\catcode`^^a0\active % ` '
+\gdef^^a0{\tie}
+\global\catcode`^^a1\active % ¡
+\gdef^^a1{\exclamdown}
+%\global\catcode`^^a2\active % ¢
+%\gdef^^a2{}
+\global\catcode`^^a3\active % £
+\gdef^^a3{\pounds}
+%\global\catcode`^^a4\active % ¤
+%\gdef^^a4{}
+%\global\catcode`^^a5\active % ¥
+%\gdef^^a5{}
+%\global\catcode`^^a6\active % ¦
+%\gdef^^a6{}
+%\global\catcode`^^a7\active % §
+%\gdef^^a7{}
+\global\catcode`^^a8\active % ¨
+\gdef^^a8{\"{ }}
+\global\catcode`^^a9\active % ©
+\gdef^^a9{\copyright}
+\global\catcode`^^aa\active % ª
+\gdef^^aa{\ordf}
+%\global\catcode`^^ab\active % «
+%\gdef^^ab{}
+%\global\catcode`^^ac\active % ¬
+%\gdef^^ac{}
+%\global\catcode`^^ad\active %
+%\gdef^^ad{}
+\global\catcode`^^ae\active % ®
+\gdef^^ae{\registeredsymbol}
+\global\catcode`^^af\active % ¯
+\gdef^^af{\={ }}
+\global\catcode`^^b0\active % °
+\gdef^^b0{\ringaccent{ }}
+%\global\catcode`^^b1\active % ±
+%\gdef^^b1{}
+%\global\catcode`^^b2\active % ²
+%\gdef^^b2{}
+%\global\catcode`^^b3\active % ³
+%\gdef^^b3{}
+\global\catcode`^^b4\active % ´
+\gdef^^b4{\'{ }}
+%\global\catcode`^^b5\active % µ
+%\gdef^^b5{}
+%\global\catcode`^^b6\active % ¶
+%\gdef^^b6{}
+%\global\catcode`^^b7\active % ·
+%\gdef^^b7{}
+\global\catcode`^^b8\active % ¸
+\gdef^^b8{\,{ }}
+%\global\catcode`^^b9\active % ¹
+%\gdef^^b9{}
+\global\catcode`^^ba\active % º
+\gdef^^ba{\ordm}
+%\global\catcode`^^bb\active % »
+%\gdef^^bb{}
+%\global\catcode`^^bc\active % ¼
+%\gdef^^bc{}
+%\global\catcode`^^bd\active % ½
+%\gdef^^bd{}
+%\global\catcode`^^be\active % ¾
+%\gdef^^be{}
+\global\catcode`^^bf\active % ¿
+\gdef^^bf{\exclamdown}
+\global\catcode`^^c0\active % À
+\gdef^^c0{\`A}
+\global\catcode`^^c1\active % Á
+\gdef^^c1{\'A}
+\global\catcode`^^c2\active % Â
+\gdef^^c2{\^A}
+\global\catcode`^^c3\active % Ã
+\gdef^^c3{\~A}
+\global\catcode`^^c4\active % Ä
+\gdef^^c4{\"A}
+\global\catcode`^^c5\active % Å
+\gdef^^c5{\AA}
+\global\catcode`^^c6\active % Æ
+\gdef^^c6{\AE}
+\global\catcode`^^c7\active % Ç
+\gdef^^c7{\,{C}}
+\global\catcode`^^c8\active % È
+\gdef^^c8{\`E}
+\global\catcode`^^c9\active % É
+\gdef^^c9{\'E}
+\global\catcode`^^ca\active % Ê
+\gdef^^ca{\^E}
+\global\catcode`^^cb\active % Ë
+\gdef^^cb{\"E}
+\global\catcode`^^cc\active % Ì
+\gdef^^cc{\`I}
+\global\catcode`^^cd\active % Í
+\gdef^^cd{\'I}
+\global\catcode`^^ce\active % Î
+\gdef^^ce{\^I}
+\global\catcode`^^cf\active % Ï
+\gdef^^cf{\"I}
+%\global\catcode`^^d0\active % Ð
+%\gdef^^d0{}
+\global\catcode`^^d1\active % Ñ
+\gdef^^d1{\~N}
+\global\catcode`^^d2\active % Ò
+\gdef^^d2{\`O}
+\global\catcode`^^d3\active % Ó
+\gdef^^d3{\'O}
+\global\catcode`^^d4\active % Ô
+\gdef^^d4{\^O}
+\global\catcode`^^d5\active % Õ
+\gdef^^d5{\~O}
+\global\catcode`^^d6\active % Ö
+\gdef^^d6{\"O}
+%\global\catcode`^^d7\active % ×
+%\gdef^^d7{}
+\global\catcode`^^d8\active % Ø
+\gdef^^d8{\O}
+\global\catcode`^^d9\active % Ù
+\gdef^^d9{\`U}
+\global\catcode`^^da\active % Ú
+\gdef^^da{\'U}
+\global\catcode`^^db\active % Û
+\gdef^^db{\^U}
+\global\catcode`^^dc\active % Ü
+\gdef^^dc{\"U}
+\global\catcode`^^dd\active % Ý
+\gdef^^dd{\'Y}
+%\global\catcode`^^de\active % Þ
+%\gdef^^de{}
+\global\catcode`^^df\active % ß
+\gdef^^df{\ss}
+\global\catcode`^^e0\active % à
+\gdef^^e0{\`a}
+\global\catcode`^^e1\active % á
+\gdef^^e1{\'a}
+\global\catcode`^^e2\active % â
+\gdef^^e2{\^a}
+\global\catcode`^^e3\active % ã
+\gdef^^e3{\~a}
+\global\catcode`^^e4\active % ä
+\gdef^^e4{\"a}
+\global\catcode`^^e5\active % å
+\gdef^^e5{\aa}
+\global\catcode`^^e6\active % æ
+\gdef^^e6{\ae}
+\global\catcode`^^e7\active % ç
+\gdef^^e7{\,{c}}
+\global\catcode`^^e8\active % è
+\gdef^^e8{\`e}
+\global\catcode`^^e9\active % é
+\gdef^^e9{\'e}
+\global\catcode`^^ea\active % ê
+\gdef^^ea{\^e}
+\global\catcode`^^eb\active % ë
+\gdef^^eb{\"e}
+\global\catcode`^^ec\active % ì
+\gdef^^ec{\`{\dotless{i}}}
+\global\catcode`^^ed\active % í
+\gdef^^ed{\'{\dotless{i}}}
+\global\catcode`^^ee\active % î
+\gdef^^ee{\^{\dotless{i}}}
+\global\catcode`^^ef\active % ï
+\gdef^^ef{\"{\dotless{i}}}
+%\global\catcode`^^f0\active % ð
+%\gdef^^f0{}
+\global\catcode`^^f1\active % ñ
+\gdef^^f1{\~n}
+\global\catcode`^^f2\active % ò
+\gdef^^f2{\`o}
+\global\catcode`^^f3\active % ó
+\gdef^^f3{\'o}
+\global\catcode`^^f4\active % ô
+\gdef^^f4{\^o}
+\global\catcode`^^f5\active % õ
+\gdef^^f5{\~o}
+\global\catcode`^^f6\active % ö
+\gdef^^f6{\"o}
+%\global\catcode`^^f7\active % ÷
+%\gdef^^f7{}
+\global\catcode`^^f8\active % ø
+\gdef^^f8{\o}
+\global\catcode`^^f9\active % ù
+\gdef^^f9{\`u}
+\global\catcode`^^fa\active % ú
+\gdef^^fa{\'u}
+\global\catcode`^^fb\active % û
+\gdef^^fb{\^u}
+\global\catcode`^^fc\active % ü
+\gdef^^fc{\"u}
+\global\catcode`^^fd\active % ý
+\gdef^^fd{\'y}
+%\global\catcode`^^fe\active % þ
+%\gdef^^fe{}
+\global\catcode`^^ff\active % ÿ
+\gdef^^ff{\"y}
@end tex
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2006-06-01.17}
+\def\texinfoversion{2006-02-13.16}
%
% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free
%
\def\parsearg{\parseargusing{}}
\def\parseargusing#1#2{%
- \def\argtorun{#2}%
+ \def\next{#2}%
\begingroup
\obeylines
\spaceisspace
\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
\def\temp{#3}%
\ifx\temp\empty
- % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ % We cannot use \next here, as it holds the macro to run;
+ % thus we reuse \temp.
\let\temp\finishparsearg
\else
\let\temp\argcheckspaces
% If a _delimited_ argument is enclosed in braces, they get stripped; so
% to get _exactly_ the rest of the line, we had to prevent such situation.
% We prepended an \empty token at the very beginning and we expand it now,
-% just before passing the control to \argtorun.
+% just before passing the control to \next.
% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
% either the null string, or it ends with \^^M---thus there is no danger
% that a pair of braces would be stripped.
%
% But first, we have to remove the trailing space token.
%
-\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
% \parseargdef\foo{...}
% is roughly equivalent to
\def\minus{$-$}
% @dots{} outputs an ellipsis using the current font.
-% We do .5em per period so that it has the same spacing in the cm
-% typewriter fonts as three actual period characters; on the other hand,
-% in other typewriter fonts three periods are wider than 1.5em. So do
-% whichever is larger.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
%
\def\dots{%
\leavevmode
- \setbox0=\hbox{...}% get width of three periods
- \ifdim\wd0 > 1.5em
- \dimen0 = \wd0
- \else
- \dimen0 = 1.5em
- \fi
- \hbox to \dimen0{%
- \hskip 0pt plus.25fil
- .\hskip 0pt plus1fil
- .\hskip 0pt plus1fil
- .\hskip 0pt plus.5fil
+ \hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil
+ .\hfil.\hfil.%
+ \hskip 0pt plus 0.5fil
}%
}
\ifpdf
\input pdfcolor
\pdfcatalog{/PageMode /UseOutlines}%
- % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
\def\dopdfimage#1#2#3{%
- \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
- \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ \def\imagewidth{#2}%
+ \def\imageheight{#3}%
% without \immediate, pdftex seg faults when the same image is
% included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
\ifnum\pdftexversion < 14
\else
\immediate\pdfximage
\fi
- \ifdim \wd0 >0pt width \imagewidth \fi
- \ifdim \wd2 >0pt height \imageheight \fi
+ \ifx\empty\imagewidth\else width \imagewidth \fi
+ \ifx\empty\imageheight\else height \imageheight \fi
\ifnum\pdftexversion<13
#1.pdf%
\else
% We don't need math for this font style.
\def\ttsl{\setfontstyle{ttsl}}
-
% Default leading.
\newdimen\textleading \textleading = 13.2pt
}%
}
-
% Set the font macro #1 to the font named #2, adding on the
% specified font prefix (normally `cm').
% #3 is the font's design size, #4 is a scale factor
\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
-
% Use cm as the default font prefix.
% To specify the font prefix, you must define \fontprefix
% before you read in texinfo.tex.
\def\scshape{csc}
\def\scbshape{csc}
-% Definitions for a main text size of 11pt. This is the default in
-% Texinfo.
-%
-\def\definetextfontsizexi{
% Text fonts (11.2pt, magstep1).
\def\textnominalsize{11pt}
\edef\mainmagstep{\magstephalf}
\font\reducedi=cmmi10
\font\reducedsy=cmsy10
-% reset the current fonts
-\textfonts
-\rm
-} % end of 11pt text font size definitions
-
-
-% Definitions to make the main text be 10pt Computer Modern, with
-% section, chapter, etc., sizes following suit. This is for the GNU
-% Press printing of the Emacs 22 manual. Maybe other manuals in the
-% future. Used with @smallbook, which sets the leading to 12pt.
-%
-\def\definetextfontsizex{%
-% Text fonts (10pt).
-\def\textnominalsize{10pt}
-\edef\mainmagstep{1000}
-\setfont\textrm\rmshape{10}{\mainmagstep}
-\setfont\texttt\ttshape{10}{\mainmagstep}
-\setfont\textbf\bfshape{10}{\mainmagstep}
-\setfont\textit\itshape{10}{\mainmagstep}
-\setfont\textsl\slshape{10}{\mainmagstep}
-\setfont\textsf\sfshape{10}{\mainmagstep}
-\setfont\textsc\scshape{10}{\mainmagstep}
-\setfont\textttsl\ttslshape{10}{\mainmagstep}
-\font\texti=cmmi10 scaled \mainmagstep
-\font\textsy=cmsy10 scaled \mainmagstep
-
-% A few fonts for @defun names and args.
-\setfont\defbf\bfshape{10}{\magstephalf}
-\setfont\deftt\ttshape{10}{\magstephalf}
-\setfont\defttsl\ttslshape{10}{\magstephalf}
-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
-
-% Fonts for indices, footnotes, small examples (9pt).
-\def\smallnominalsize{9pt}
-\setfont\smallrm\rmshape{9}{1000}
-\setfont\smalltt\ttshape{9}{1000}
-\setfont\smallbf\bfshape{10}{900}
-\setfont\smallit\itshape{9}{1000}
-\setfont\smallsl\slshape{9}{1000}
-\setfont\smallsf\sfshape{9}{1000}
-\setfont\smallsc\scshape{10}{900}
-\setfont\smallttsl\ttslshape{10}{900}
-\font\smalli=cmmi9
-\font\smallsy=cmsy9
-
-% Fonts for small examples (8pt).
-\def\smallernominalsize{8pt}
-\setfont\smallerrm\rmshape{8}{1000}
-\setfont\smallertt\ttshape{8}{1000}
-\setfont\smallerbf\bfshape{10}{800}
-\setfont\smallerit\itshape{8}{1000}
-\setfont\smallersl\slshape{8}{1000}
-\setfont\smallersf\sfshape{8}{1000}
-\setfont\smallersc\scshape{10}{800}
-\setfont\smallerttsl\ttslshape{10}{800}
-\font\smalleri=cmmi8
-\font\smallersy=cmsy8
-
-% Fonts for title page (20.4pt):
-\def\titlenominalsize{20pt}
-\setfont\titlerm\rmbshape{12}{\magstep3}
-\setfont\titleit\itbshape{10}{\magstep4}
-\setfont\titlesl\slbshape{10}{\magstep4}
-\setfont\titlett\ttbshape{12}{\magstep3}
-\setfont\titlettsl\ttslshape{10}{\magstep4}
-\setfont\titlesf\sfbshape{17}{\magstep1}
-\let\titlebf=\titlerm
-\setfont\titlesc\scbshape{10}{\magstep4}
-\font\titlei=cmmi12 scaled \magstep3
-\font\titlesy=cmsy10 scaled \magstep4
-\def\authorrm{\secrm}
-\def\authortt{\sectt}
-
-% Chapter fonts (14.4pt).
-\def\chapnominalsize{14pt}
-\setfont\chaprm\rmbshape{12}{\magstep1}
-\setfont\chapit\itbshape{10}{\magstep2}
-\setfont\chapsl\slbshape{10}{\magstep2}
-\setfont\chaptt\ttbshape{12}{\magstep1}
-\setfont\chapttsl\ttslshape{10}{\magstep2}
-\setfont\chapsf\sfbshape{12}{\magstep1}
-\let\chapbf\chaprm
-\setfont\chapsc\scbshape{10}{\magstep2}
-\font\chapi=cmmi12 scaled \magstep1
-\font\chapsy=cmsy10 scaled \magstep2
-
-% Section fonts (12pt).
-\def\secnominalsize{12pt}
-\setfont\secrm\rmbshape{12}{1000}
-\setfont\secit\itbshape{10}{\magstep1}
-\setfont\secsl\slbshape{10}{\magstep1}
-\setfont\sectt\ttbshape{12}{1000}
-\setfont\secttsl\ttslshape{10}{\magstep1}
-\setfont\secsf\sfbshape{12}{1000}
-\let\secbf\secrm
-\setfont\secsc\scbshape{10}{\magstep1}
-\font\seci=cmmi12
-\font\secsy=cmsy10 scaled \magstep1
-
-% Subsection fonts (10pt).
-\def\ssecnominalsize{10pt}
-\setfont\ssecrm\rmbshape{10}{1000}
-\setfont\ssecit\itbshape{10}{1000}
-\setfont\ssecsl\slbshape{10}{1000}
-\setfont\ssectt\ttbshape{10}{1000}
-\setfont\ssecttsl\ttslshape{10}{1000}
-\setfont\ssecsf\sfbshape{10}{1000}
-\let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{1000}
-\font\sseci=cmmi10
-\font\ssecsy=cmsy10
-
-% Reduced fonts for @acro in text (9pt).
-\def\reducednominalsize{9pt}
-\setfont\reducedrm\rmshape{9}{1000}
-\setfont\reducedtt\ttshape{9}{1000}
-\setfont\reducedbf\bfshape{10}{900}
-\setfont\reducedit\itshape{9}{1000}
-\setfont\reducedsl\slshape{9}{1000}
-\setfont\reducedsf\sfshape{9}{1000}
-\setfont\reducedsc\scshape{10}{900}
-\setfont\reducedttsl\ttslshape{10}{900}
-\font\reducedi=cmmi9
-\font\reducedsy=cmsy9
-
-% reduce space between paragraphs
-\divide\parskip by 2
-
-% reset the current fonts
-\textfonts
-\rm
-} % end of 10pt text font size definitions
-
-
-% We provide the user-level command
-% @fonttextsize 10
-% (or 11) to redefine the text font size. pt is assumed.
-%
-\def\xword{10}
-\def\xiword{11}
-%
-\parseargdef\fonttextsize{%
- \def\textsizearg{#1}%
- \wlog{doing @fonttextsize \textsizearg}%
- %
- % Set \globaldefs so that documents can use this inside @tex, since
- % makeinfo 4.8 does not support it, but we need it nonetheless.
- %
- \begingroup \globaldefs=1
- \ifx\textsizearg\xword \definetextfontsizex
- \else \ifx\textsizearg\xiword \definetextfontsizexi
- \else
- \errhelp=\EMsimple
- \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
- \fi\fi
- \endgroup
-}
-
-
% In order for the font changes to affect most math symbols and letters,
% we have to define the \textfont of the standard families. Since
% texinfo doesn't allow for producing subscripts and superscripts except
% Set up the default fonts, so we can use them for creating boxes.
%
-\definetextfontsizexi
+\textfonts \rm
% Define these so they can be easily changed for other fonts.
\def\angleleft{$\langle$}
\escapechar = `\\ % use backslash in output files.
\def\@{@}% change to @@ when we switch to @ as escape char in index files.
\def\ {\realbackslash\space }%
- %
% Need these in case \tex is in effect and \{ is a \delimiter again.
% But can't use \lbracecmd and \rbracecmd because texindex assumes
% braces and backslashes are used only as delimiters.
\let\{ = \mylbrace
\let\} = \myrbrace
%
- % I don't entirely understand this, but when an index entry is
- % generated from a macro call, the \endinput which \scanmacro inserts
- % causes processing to be prematurely terminated. This is,
- % apparently, because \indexsorttmp is fully expanded, and \endinput
- % is an expandable command. The redefinition below makes \endinput
- % disappear altogether for that purpose -- although logging shows that
- % processing continues to some further point. On the other hand, it
- % seems \endinput does not hurt in the printed index arg, since that
- % is still getting written without apparent harm.
- %
- % Sample source (mac-idx3.tex, reported by Graham Percival to
- % help-texinfo, 22may06):
- % @macro funindex {WORD}
- % @findex xyz
- % @end macro
- % ...
- % @funindex commtest
- %
- % The above is not enough to reproduce the bug, but it gives the flavor.
- %
- % Sample whatsit resulting:
- % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
- %
- % So:
- \let\endinput = \empty
- %
% Do the redefinitions.
\commondummies
}
\ifx\temptype\Ynothingkeyword
\setbox0 = \hbox{}%
\def\toctype{unnchap}%
- \gdef\thischapternum{}%
\gdef\thischapter{#1}%
\else\ifx\temptype\Yomitfromtockeyword
\setbox0 = \hbox{}% contents like unnumbered, but no toc entry
\def\toctype{omit}%
- \gdef\thischapternum{}%
\gdef\thischapter{}%
\else\ifx\temptype\Yappendixkeyword
\setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
\def\toctype{app}%
- \xdef\thischapternum{\appendixletter}%
% We don't substitute the actual chapter name into \thischapter
% because we don't want its macros evaluated now. And we don't
% use \thissection because that changes with each section.
\else
\setbox0 = \hbox{#3\enspace}%
\def\toctype{numchap}%
- \xdef\thischapternum{\the\chapno}%
\xdef\thischapter{\putwordChapter{} \the\chapno:
\noexpand\thischaptername}%
\fi\fi\fi
%
\maketwodispenvs {lisp}{example}{%
\nonfillstart
- \tt\quoteexpand
+ \tt
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
\gobble % eat return
}
\spaceisspace
%
% Append \endinput to make sure that TeX does not see the ending newline.
+ %
% I've verified that it is necessary both for e-TeX and for ordinary TeX
% --kasal, 29nov03
\scantokens{#1\endinput}%
% {. If so it reads up to the closing }, if not, it reads the whole
% line. Whatever was read is then fed to the next control sequence
% as an argument (by \parsebrace or \parsearg)
-\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
\def\braceorlinexxx{%
\ifx\nchar\bgroup\else
\expandafter\parsearg
- \fi \macnamexxx}
+ \fi \next}
% @alias.