From 9f3572d98bb948c9689cd1f75401a029451fa001 Mon Sep 17 00:00:00 2001 From: Erlend Aasland Date: Wed, 31 May 2006 01:47:30 +0000 Subject: [PATCH] Fix some bugs in the dynamic engraver and PostScript backend --- ChangeLog | 2452 +---------------- DEDICATION | 4 +- Documentation/GNUmakefile | 2 +- Documentation/misc/GNUmakefile | 2 +- Documentation/pictures/GNUmakefile | 2 +- Documentation/topdocs/GNUmakefile | 1 - Documentation/topdocs/NEWS.tely | 166 +- Documentation/user/GNUmakefile | 29 +- Documentation/user/README.txt | 10 +- Documentation/user/SConscript | 13 +- Documentation/user/advanced-notation.itely | 201 +- Documentation/user/basic-notation.itely | 495 ++-- Documentation/user/changing-defaults.itely | 86 +- Documentation/user/convert-ly.txt | 47 - Documentation/user/converters.itely | 5 +- Documentation/user/examples.itely | 104 +- Documentation/user/global.itely | 1514 ++++++++-- Documentation/user/instrument-notation.itely | 149 +- Documentation/user/introduction.itely | 9 +- Documentation/user/invoking.itely | 43 +- Documentation/user/lilypond-book.itely | 113 +- Documentation/user/lilypond.tely | 57 +- Documentation/user/macros.itexi | 8 +- Documentation/user/music-glossary.tely | 131 +- Documentation/user/page.itely | 1159 -------- .../user/programming-interface.itely | 70 +- Documentation/user/putting.itely | 19 +- Documentation/user/scheme-tutorial.itely | 11 +- Documentation/user/tutorial.itely | 19 +- Documentation/user/tweaks.itely | 97 +- Documentation/user/working.itely | 231 +- GNUmakefile.in | 41 +- HACKING | 46 +- INSTALL.txt | 415 +++ README.txt | 99 + SConstruct | 295 +- THANKS | 51 +- VERSION | 2 +- buildscripts/builder.py | 80 +- buildscripts/mutopia-index.py | 6 +- buildscripts/output-distance.py | 631 +---- buildscripts/readlink.py | 6 - config.make.in | 5 +- configure.in | 4 +- cygwin/postinstall-lilypond.sh | 3 +- elisp/lilypond-mode.el | 4 +- flower/file-name.cc | 37 +- flower/include/GNUmakefile | 9 - flower/include/file-name.hh | 3 - flower/include/flower-proto.hh | 2 +- flower/include/international.hh | 6 - flower/include/interval.hh | 4 +- flower/include/matrix.hh | 66 - flower/include/std-string.hh | 9 - flower/include/std-vector.hh | 168 +- flower/international.cc | 8 +- flower/std-string.cc | 8 +- input/GNUmakefile | 2 +- input/les-nereides.ly | 2 +- input/manual/GNUmakefile | 16 - input/manual/README | 5 - input/manual/SConscript | 4 - .../E.Satie/petite-ouverture-a-danser.ly | 12 +- input/mutopia/F.Schubert/morgenlied.ly | 7 +- input/mutopia/F.Schubert/standchen.ly | 12 +- .../J.S.Bach/baerenreiter-sarabande.ly | 15 +- input/mutopia/J.S.Bach/bwv940.ly | 12 +- input/mutopia/J.S.Bach/wtk1-fugue2.ly | 5 +- input/mutopia/R.Schumann/romanze-op28-2.ly | 18 +- input/mutopia/W.A.Mozart/mozart-hrn-3.ly | 40 +- input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily | 1 - input/no-notation/display-lily-tests.ly | 2 +- input/no-notation/dynamic-absolute-volume.ly | 14 +- input/no-notation/midi-volume-equaliser.ly | 56 +- input/proportional.ly | 4 +- input/puer-fragment.ly | 4 +- input/regression/+.ly | 3 - input/regression/accidental-forced-tie.ly | 13 - .../regression/alignment-vertical-spacing.ly | 6 +- input/regression/bar-line-dashed.ly | 17 - input/regression/bar-scripts.ly | 8 +- input/regression/beaming-ternary-metrum.ly | 13 +- input/regression/beaming.ly | 9 +- input/regression/bend-after.ly | 25 - input/regression/breathing-sign-ancient.ly | 29 +- input/regression/drums.ly | 16 +- input/regression/figured-bass-staff.ly | 13 +- input/regression/instrument-name-hara-kiri.ly | 6 +- input/regression/instrument-name-markup.ly | 6 +- input/regression/instrument-name-partial.ly | 4 +- input/regression/instrument-name.ly | 8 +- input/regression/instrument-switch.ly | 31 - input/regression/metronome-marking.ly | 2 +- .../multi-measure-rest-instr-name.ly | 6 +- input/regression/note-head-solfa.ly | 4 +- .../optimal-page-breaking-hstretch.ly | 24 - .../regression/page-layout-manual-position.ly | 6 +- input/regression/page-layout.ly | 7 +- input/regression/page-spacing.ly | 2 +- .../page-turn-page-breaking-badturns.ly | 22 - input/regression/page-turn-page-breaking.ly | 32 - input/regression/prefatory-spacing-matter.ly | 4 +- input/regression/quote-cue-during.ly | 8 +- input/regression/quote-during.ly | 8 +- input/regression/quote-grace.ly | 6 +- input/regression/quote-tie.ly | 29 - input/regression/quote.ly | 8 +- input/regression/repeat-percent-grace.ly | 14 - input/regression/rest-note-collision.ly | 31 - input/regression/spacing-grace.ly | 37 +- input/regression/spacing-loose-grace.ly | 30 - input/regression/spacing-no-note.ly | 13 - input/regression/spacing-section.ly | 26 - input/regression/stencil-color-rotation.ly | 10 - input/regression/tag-filter.ly | 8 +- input/regression/tie-busy-grobs.ly | 27 + input/regression/tie-chord-partial.ly | 15 - input/regression/tie-whole.ly | 16 - input/regression/tuplet-beam.ly | 2 +- input/regression/tuplet-broken.ly | 4 +- input/regression/tuplet-full-length-note.ly | 24 - input/regression/tuplet-gap.ly | 4 +- input/regression/tuplet-nest.ly | 4 +- input/regression/utf-8-mixed-text.ly | 10 - input/regression/volta-broken-left-edge.ly | 6 +- input/sakura-sakura.ly | 12 +- input/{manual => }/screech-boink.ly | 12 +- input/test/+.ly | 4 - input/test/add-staccato.ly | 15 +- input/test/add-text-script.ly | 19 +- input/{manual => test}/bar-lines.ly | 10 +- .../bar-number-regular-interval.ly | 0 input/{manual => test}/chord-names-jazz.ly | 14 +- .../{manual => test}/chord-names-languages.ly | 10 +- input/test/coriolan-margin.ly | 46 +- input/{manual => test}/divisiones.ly | 1 + input/{manual => test}/engraver-example.ily | 0 input/test/engraver-one-by-one.ly | 4 +- input/test/extra-staff.ly | 2 +- input/{manual => test}/font-table.ly | 1 - input/test/instrument-name-align.ly | 8 +- input/test/instrument-name-grandstaff.ly | 8 +- input/test/music-box.ly | 35 +- input/{manual => test}/ossia.ly | 0 input/test/reverse-music.ly | 17 +- .../{manual => test}/script-abbreviations.ly | 0 input/{manual => test}/script-chart.ly | 0 input/test/smart-transpose.ly | 15 +- input/test/staff-container.ly | 2 +- input/test/temporary-stave.ly | 2 +- input/test/time-signature-staff.ly | 2 +- input/test/unfold-all-repeats.ly | 27 + input/typography-demo.ly | 14 +- lily/SConscript | 1 + lily/accidental-engraver.cc | 51 +- lily/accidental-placement.cc | 48 +- lily/accidental.cc | 9 +- lily/align-interface.cc | 105 +- lily/all-font-metrics.cc | 52 + lily/ambitus-engraver.cc | 12 +- lily/apply-context-iterator.cc | 3 + lily/arpeggio-engraver.cc | 35 +- lily/audio-element-info.cc | 2 +- lily/audio-item.cc | 3 +- lily/audio-staff.cc | 8 +- lily/auto-beam-engraver.cc | 42 +- lily/auto-change-iterator.cc | 7 +- lily/axis-group-engraver.cc | 4 +- lily/axis-group-interface.cc | 162 +- lily/bar-engraver.cc | 1 + lily/bar-line.cc | 88 +- lily/beam-engraver.cc | 69 +- lily/beam-performer.cc | 28 +- lily/beam.cc | 13 +- lily/beaming-pattern.cc | 64 +- lily/binary-source-file.cc | 94 + lily/book.cc | 47 +- lily/box.cc | 10 +- lily/break-algorithm.cc | 40 + lily/break-align-engraver.cc | 5 +- lily/break-align-interface.cc | 2 +- lily/break-substitution.cc | 6 +- lily/breathing-sign-engraver.cc | 27 +- lily/breathing-sign.cc | 9 +- lily/change-iterator.cc | 4 +- lily/chord-name-engraver.cc | 47 +- lily/chord-tremolo-engraver.cc | 48 +- lily/cluster-engraver.cc | 28 +- lily/coherent-ligature-engraver.cc | 44 +- lily/completion-note-heads-engraver.cc | 87 +- lily/constrained-breaking.cc | 266 +- lily/context-def.cc | 119 +- lily/context-handle.cc | 6 + lily/context-property.cc | 54 +- lily/context-scheme.cc | 2 +- lily/context.cc | 276 +- lily/control-track-performer.cc | 70 - lily/custos-engraver.cc | 9 +- lily/dispatcher-scheme.cc | 2 +- lily/dispatcher.cc | 32 +- lily/dot-column.cc | 4 +- lily/dots-engraver.cc | 65 - lily/drum-note-engraver.cc | 61 +- lily/drum-note-performer.cc | 53 +- lily/duration-scheme.cc | 8 - lily/dynamic-engraver.cc | 78 +- lily/dynamic-performer.cc | 23 +- lily/dynamic-text-spanner.cc | 9 - lily/easy-notation.cc | 9 +- lily/engraver-group.cc | 49 +- lily/engraver.cc | 100 +- lily/event-chord-iterator.cc | 8 - lily/extender-engraver.cc | 21 +- lily/fall-engraver.cc | 117 - lily/figured-bass-engraver.cc | 129 +- lily/figured-bass-position-engraver.cc | 44 +- lily/fingering-engraver.cc | 34 +- lily/folded-repeat-iterator.cc | 2 +- lily/font-config.cc | 15 +- lily/font-metric-scheme.cc | 14 +- lily/font-metric.cc | 6 - lily/forbid-break-engraver.cc | 4 +- lily/general-scheme.cc | 16 - lily/glissando-engraver.cc | 21 +- lily/global-context-scheme.cc | 100 +- lily/global-context.cc | 106 +- lily/gourlay-breaking.cc | 264 ++ lily/grace-spacing-engraver.cc | 79 - lily/gregorian-ligature-engraver.cc | 20 +- lily/grob-array.cc | 2 +- lily/grob-closure.cc | 27 +- lily/grob-info.cc | 21 +- lily/grob-pq-engraver.cc | 19 +- lily/grob-property.cc | 47 +- lily/grob-scheme.cc | 30 +- lily/grob.cc | 97 +- lily/hara-kiri-engraver.cc | 6 +- lily/hara-kiri-group-spanner.cc | 87 +- lily/horizontal-bracket-engraver.cc | 44 +- lily/hyphen-engraver.cc | 22 +- lily/include/GNUmakefile | 8 - lily/include/align-interface.hh | 6 - lily/include/all-font-metrics.hh | 2 + lily/include/audio-element-info.hh | 4 +- lily/include/audio-element.hh | 3 +- lily/include/audio-item.hh | 3 +- lily/include/axis-group-interface.hh | 7 - lily/include/bar-line.hh | 1 - lily/include/beaming-pattern.hh | 3 - lily/include/binary-source-file.hh | 27 + lily/include/book-paper-def.hh | 1 + lily/include/book.hh | 7 +- lily/include/box.hh | 1 - lily/include/break-algorithm.hh | 38 + lily/include/constrained-breaking.hh | 48 +- lily/include/context-def.hh | 11 +- lily/include/context-handle.hh | 1 + lily/include/context.hh | 45 +- lily/include/engraver-group.hh | 6 +- lily/include/engraver.hh | 21 +- lily/include/font-metric.hh | 5 +- lily/include/global-context.hh | 11 +- lily/include/gourlay-breaking.hh | 23 + lily/include/gregorian-ligature-engraver.hh | 5 +- lily/include/grob-info.hh | 4 +- lily/include/grob.hh | 16 +- lily/include/hara-kiri-group-spanner.hh | 2 - lily/include/input-smob.hh | 21 + lily/include/input.hh | 16 +- lily/include/item.hh | 2 - lily/include/kpath.hh | 1 + lily/include/ligature-engraver.hh | 6 +- lily/include/lily-guile-macros.hh | 38 +- lily/include/lily-guile.hh | 3 +- lily/include/lily-lexer.hh | 4 - lily/include/listener.hh | 44 +- lily/include/ly-smobs.icc | 4 +- lily/include/midi-item.hh | 19 +- lily/include/midi-walker.hh | 4 +- lily/include/modified-font-metric.hh | 1 - lily/include/moment.hh | 1 - lily/include/music-iterator.hh | 2 +- lily/include/music.hh | 7 +- lily/include/note-column.hh | 2 +- lily/include/optimal-page-breaking.hh | 29 - lily/include/output-def.hh | 4 +- lily/include/page-breaking.hh | 130 - lily/include/page-spacing.hh | 93 - lily/include/page-turn-page-breaking.hh | 78 - lily/include/pango-font.hh | 8 +- lily/include/paper-column-engraver.hh | 13 +- lily/include/paper-column.hh | 6 - lily/include/paper-score.hh | 5 - lily/include/percent-repeat-iterator.hh | 25 + lily/include/performer-group.hh | 6 +- lily/include/performer.hh | 2 + lily/include/pitch.hh | 15 +- lily/include/prob.hh | 5 - lily/include/score-context.hh | 24 + lily/include/score-engraver.hh | 15 +- lily/include/score-performer.hh | 22 +- lily/include/score-translator.hh | 25 + lily/include/score.hh | 7 +- lily/include/semi-tie.hh | 4 +- lily/include/sequential-music-iterator.hh | 26 + lily/include/side-position-interface.hh | 11 +- lily/include/simple-spacer.hh | 7 +- lily/include/slur-configuration.hh | 13 +- lily/include/slur.hh | 1 - lily/include/smobs.hh | 2 +- lily/include/source-file.hh | 47 +- lily/include/spacing-spanner.hh | 9 +- lily/include/spanner.hh | 4 +- lily/include/staff-symbol-engraver.hh | 40 + lily/include/staff-symbol-referencer.hh | 3 +- lily/include/stem-tremolo.hh | 3 +- lily/include/stem.hh | 1 - lily/include/stream-event.hh | 29 +- lily/include/tfm-reader.hh | 44 + lily/include/tfm.hh | 173 ++ lily/include/tie.hh | 4 +- lily/include/translator-group.hh | 11 +- lily/include/translator.hh | 42 +- lily/include/translator.icc | 40 +- lily/input-scheme.cc | 2 +- lily/input-smob.cc | 11 +- lily/input.cc | 9 - lily/instrument-name-engraver.cc | 121 +- lily/instrument-switch-engraver.cc | 62 - lily/item.cc | 27 +- lily/key-engraver.cc | 36 +- lily/key-performer.cc | 19 +- lily/keyword.cc | 8 +- lily/laissez-vibrer-engraver.cc | 18 +- lily/least-squares.cc | 13 +- lily/ledger-line-engraver.cc | 33 +- lily/lexer.ll | 205 +- lily/ligature-engraver.cc | 19 +- lily/lily-guile.cc | 17 +- lily/lily-lexer.cc | 1 + lily/lily-parser-scheme.cc | 36 +- lily/lily-parser.cc | 1 + lily/line-interface.cc | 1 - lily/line-spanner.cc | 8 +- lily/listener.cc | 11 +- lily/ly-module.cc | 11 +- lily/lyric-combine-music-iterator.cc | 21 +- lily/lyric-engraver.cc | 21 +- lily/lyric-extender.cc | 21 +- lily/lyric-performer.cc | 25 +- lily/main.cc | 10 +- lily/mark-engraver.cc | 21 +- lily/melisma-translator.cc | 14 +- lily/mensural-ligature-engraver.cc | 23 +- lily/mensural-ligature.cc | 15 +- lily/metronome-engraver.cc | 70 +- lily/midi-def.cc | 46 + lily/midi-item.cc | 43 +- lily/midi-walker.cc | 8 +- lily/multi-measure-rest-engraver.cc | 71 +- lily/multi-measure-rest.cc | 6 +- lily/music-function.cc | 19 + lily/music-iterator.cc | 9 +- lily/music.cc | 112 +- lily/new-fingering-engraver.cc | 107 +- lily/note-collision.cc | 6 +- lily/note-column.cc | 18 +- lily/note-head.cc | 17 +- lily/note-heads-engraver.cc | 60 +- lily/note-name-engraver.cc | 24 +- lily/note-performer.cc | 51 +- lily/note-spacing.cc | 32 +- lily/optimal-page-breaking.cc | 121 - lily/output-property-engraver.cc | 39 +- lily/page-breaking-scheme.cc | 30 - lily/page-breaking.cc | 427 --- lily/page-spacing.cc | 441 --- lily/page-turn-engraver.cc | 337 --- lily/page-turn-page-breaking.cc | 298 -- lily/pango-font.cc | 56 +- lily/paper-book.cc | 50 +- lily/paper-column-engraver.cc | 72 +- lily/paper-column.cc | 26 - lily/paper-outputter.cc | 2 +- lily/paper-score.cc | 37 +- lily/parenthesis-engraver.cc | 18 +- lily/parser.yy | 814 ++++-- lily/part-combine-engraver.cc | 30 +- lily/part-combine-iterator.cc | 183 +- lily/percent-repeat-engraver.cc | 104 +- lily/percent-repeat-iterator.cc | 16 +- lily/performance.cc | 84 +- lily/performer-group.cc | 24 + lily/performer.cc | 11 + lily/pfb.cc | 9 +- lily/phrasing-slur-engraver.cc | 62 +- lily/piano-pedal-engraver.cc | 215 +- lily/piano-pedal-performer.cc | 100 +- lily/pitch.cc | 34 +- lily/pitched-trill-engraver.cc | 49 +- lily/pointer-group-interface.cc | 2 +- lily/prob-scheme.cc | 4 +- lily/prob.cc | 7 +- lily/program-option.cc | 8 +- lily/property-iterator.cc | 53 +- lily/quote-iterator.cc | 32 +- lily/recording-group-engraver.cc | 8 +- lily/relocate.cc | 19 +- lily/repeat-tie-engraver.cc | 15 +- lily/rest-collision.cc | 26 +- lily/rest-engraver.cc | 51 +- lily/rest.cc | 2 +- lily/scale.cc | 109 - lily/score-context.cc | 50 + lily/score-engraver.cc | 57 +- lily/score-performer.cc | 91 +- lily/score-translator.cc | 31 + lily/score.cc | 15 +- lily/script-engraver.cc | 70 +- lily/semi-tie-column.cc | 2 +- lily/semi-tie.cc | 8 +- lily/sequential-iterator.cc | 9 +- lily/sequential-music-iterator.cc | 20 + lily/side-position-interface.cc | 114 +- lily/simple-closure.cc | 4 +- lily/simple-spacer.cc | 221 +- lily/simultaneous-music-iterator.cc | 8 +- lily/slash-repeat-engraver.cc | 51 +- lily/slur-configuration.cc | 1 - lily/slur-engraver.cc | 61 +- lily/slur-performer.cc | 34 +- lily/slur-scoring.cc | 17 +- lily/slur.cc | 45 +- lily/smobs.cc | 40 +- lily/source-file.cc | 180 +- lily/source.cc | 5 +- lily/spacing-basic.cc | 95 +- lily/spacing-determine-loose-columns.cc | 3 +- lily/spacing-engraver.cc | 106 +- lily/spacing-loose-columns.cc | 113 +- lily/spacing-options.cc | 99 - lily/spacing-spanner.cc | 97 +- lily/span-bar-engraver.cc | 2 +- lily/span-bar.cc | 2 +- lily/span-dynamic-performer.cc | 38 +- lily/spanner.cc | 20 +- lily/staff-collecting-engraver.cc | 12 - lily/staff-performer.cc | 8 + lily/staff-symbol-engraver.cc | 69 +- lily/staff-symbol-referencer.cc | 8 +- lily/stem-engraver.cc | 54 +- lily/stem-tremolo.cc | 39 +- lily/stem.cc | 48 +- lily/stencil-scheme.cc | 24 +- lily/stencil.cc | 3 +- lily/stream-event-scheme.cc | 24 +- lily/stream-event.cc | 95 +- lily/swallow-perf.cc | 3 +- lily/system-start-delimiter-engraver.cc | 3 +- lily/system-start-text.cc | 10 +- lily/system.cc | 27 +- lily/tab-note-heads-engraver.cc | 96 +- lily/tab-staff-symbol-engraver.cc | 27 +- lily/tempo-performer.cc | 50 +- lily/text-engraver.cc | 25 +- lily/text-interface.cc | 2 +- lily/text-spanner-engraver.cc | 27 +- lily/tfm-reader.cc | 292 ++ lily/tfm.cc | 132 + lily/tie-column.cc | 2 +- lily/tie-engraver.cc | 144 +- lily/tie-formatting-problem.cc | 21 +- lily/tie-performer.cc | 41 +- lily/tie.cc | 10 +- lily/time-scaled-music-iterator.cc | 139 +- lily/time-signature-performer.cc | 1 + lily/timing-translator.cc | 25 +- lily/translator-group.cc | 183 +- lily/translator.cc | 164 +- lily/trill-spanner-engraver.cc | 29 +- lily/tuplet-bracket.cc | 37 +- lily/tuplet-engraver.cc | 97 +- lily/tuplet-number.cc | 7 +- lily/tweak-engraver.cc | 10 +- lily/vaticana-ligature-engraver.cc | 25 +- lily/vaticana-ligature.cc | 4 +- lily/vertical-align-engraver.cc | 2 +- lily/volta-engraver.cc | 10 - lily/volta-repeat-iterator.cc | 2 +- ly/GNUmakefile | 2 +- ly/declarations-init.ly | 9 +- ly/english.ly | 48 +- ly/engraver-init.ly | 26 +- ly/gregorian-init.ly | 99 +- ly/init.ly | 4 +- ly/lilypond-book-preamble.ly | 13 - ly/midi-init.ly | 1 + ly/music-functions-init.ly | 657 ++--- ly/paper-defaults.ly | 21 +- ly/performer-init.ly | 42 +- ly/spanners-init.ly | 2 - ly/titling-init.ly | 2 +- make/lilypond-vars.make | 13 +- make/ly-rules.make | 12 +- make/ly-vars.make | 2 +- make/mutopia-rules.make | 17 +- make/mutopia-vars.make | 2 +- mf/SConscript | 107 +- mf/feta-bolletjes.mf | 10 +- po/de.po | 2 +- po/fi.po | 1182 ++++---- po/fr.po | 695 +++-- ps/lilyponddefs.ps | 4 + ps/music-drawing-routines.ps | 23 + python/convertrules.py | 92 +- python/lilylib.py | 57 +- python/midi.c | 13 +- python/musicxml.py | 2 +- scm/autochange.scm | 15 +- scm/backend-library.scm | 31 +- scm/c++.scm | 2 +- scm/chord-entry.scm | 15 +- scm/chord-ignatzek-names.scm | 2 +- scm/chord-name.scm | 2 +- scm/define-context-properties.scm | 43 +- scm/define-event-classes.scm | 113 +- scm/define-grob-interfaces.scm | 28 +- scm/define-grob-properties.scm | 57 +- scm/define-grobs.scm | 143 +- scm/define-markup-commands.scm | 17 +- scm/define-music-display-methods.scm | 19 +- scm/define-music-properties.scm | 36 +- scm/define-music-types.scm | 135 +- scm/define-stencil-commands.scm | 7 +- scm/document-backend.scm | 2 +- scm/document-functions.scm | 2 +- scm/document-markup.scm | 2 +- scm/document-music.scm | 2 +- scm/document-translation.scm | 2 +- scm/documentation-generate.scm | 4 +- scm/documentation-lib.scm | 4 +- scm/file-cache.scm | 2 +- scm/framework-eps.scm | 27 +- scm/framework-gnome.scm | 8 +- scm/framework-ps.scm | 41 +- scm/framework-tex.scm | 20 +- scm/framework-texstr.scm | 2 +- scm/layout-page-dump.scm | 148 - scm/layout-page-layout.scm | 771 +++--- scm/lily-library.scm | 37 +- scm/lily.scm | 75 +- scm/ly-syntax-constructors.scm | 180 +- scm/markup.scm | 2 +- scm/music-functions.scm | 80 +- scm/output-lib.scm | 231 +- scm/output-ps.scm | 68 +- scm/output-socket.scm | 10 +- scm/output-svg.scm | 50 +- scm/output-tex.scm | 10 +- scm/output-texstr.scm | 2 +- scm/page.scm | 99 +- scm/paper-system.scm | 152 +- scm/paper.scm | 9 +- scm/parser-clef.scm | 4 +- scm/parser-ly-from-scheme.scm | 5 +- scm/part-combiner.scm | 109 +- scm/ps-to-png.scm | 7 +- scm/safe-lily.scm | 3 +- scm/script.scm | 55 +- scm/standalone.scm | 2 +- scm/stencil.scm | 117 +- scm/titling.scm | 2 +- scm/to-xml.scm | 2 +- scm/translation-functions.scm | 31 +- scripts/abc2ly.py | 26 +- scripts/convert-ly.py | 360 +-- scripts/etf2ly.py | 30 +- scripts/lilypond-book.py | 136 +- scripts/midi2ly.py | 29 +- scripts/musicxml2ly.py | 30 +- stepmake/aclocal.m4 | 14 +- stepmake/bin/add-html-footer.py | 23 +- stepmake/stepmake/generic-targets.make | 1 - stepmake/stepmake/generic-vars.make | 2 +- stepmake/stepmake/po-vars.make | 1 - stepmake/stepmake/texinfo-rules.make | 5 +- stepmake/stepmake/topdocs-targets.make | 7 +- stepmake/stepmake/toplevel-targets.make | 2 +- tex/GNUmakefile | 2 +- tex/quotes.patch | 61 - tex/texinfo.cnf | 688 ++--- tex/texinfo.tex | 247 +- 592 files changed, 12606 insertions(+), 20501 deletions(-) delete mode 100644 Documentation/user/convert-ly.txt delete mode 100644 Documentation/user/page.itely create mode 100644 INSTALL.txt create mode 100644 README.txt delete mode 100644 buildscripts/readlink.py delete mode 100644 flower/include/GNUmakefile delete mode 100644 flower/include/matrix.hh delete mode 100644 input/manual/GNUmakefile delete mode 100644 input/manual/README delete mode 100644 input/manual/SConscript delete mode 100644 input/regression/accidental-forced-tie.ly delete mode 100644 input/regression/bar-line-dashed.ly delete mode 100644 input/regression/bend-after.ly delete mode 100644 input/regression/instrument-switch.ly delete mode 100644 input/regression/optimal-page-breaking-hstretch.ly delete mode 100644 input/regression/page-turn-page-breaking-badturns.ly delete mode 100644 input/regression/page-turn-page-breaking.ly delete mode 100644 input/regression/quote-tie.ly delete mode 100644 input/regression/repeat-percent-grace.ly delete mode 100644 input/regression/rest-note-collision.ly delete mode 100644 input/regression/spacing-loose-grace.ly delete mode 100644 input/regression/spacing-no-note.ly delete mode 100644 input/regression/spacing-section.ly delete mode 100644 input/regression/stencil-color-rotation.ly create mode 100644 input/regression/tie-busy-grobs.ly delete mode 100644 input/regression/tie-chord-partial.ly delete mode 100644 input/regression/tie-whole.ly delete mode 100644 input/regression/tuplet-full-length-note.ly delete mode 100644 input/regression/utf-8-mixed-text.ly rename input/{manual => }/screech-boink.ly (90%) rename input/{manual => test}/bar-lines.ly (70%) rename input/{manual => test}/bar-number-regular-interval.ly (100%) rename input/{manual => test}/chord-names-jazz.ly (92%) rename input/{manual => test}/chord-names-languages.ly (84%) rename input/{manual => test}/divisiones.ly (94%) rename input/{manual => test}/engraver-example.ily (100%) rename input/{manual => test}/font-table.ly (97%) rename input/{manual => test}/ossia.ly (100%) rename input/{manual => test}/script-abbreviations.ly (100%) rename input/{manual => test}/script-chart.ly (100%) create mode 100644 input/test/unfold-all-repeats.ly create mode 100644 lily/binary-source-file.cc create mode 100644 lily/break-algorithm.cc delete mode 100644 lily/control-track-performer.cc delete mode 100644 lily/dots-engraver.cc delete mode 100644 lily/fall-engraver.cc create mode 100644 lily/gourlay-breaking.cc delete mode 100644 lily/grace-spacing-engraver.cc delete mode 100644 lily/include/GNUmakefile create mode 100644 lily/include/binary-source-file.hh create mode 100644 lily/include/break-algorithm.hh create mode 100644 lily/include/gourlay-breaking.hh create mode 100644 lily/include/input-smob.hh delete mode 100644 lily/include/optimal-page-breaking.hh delete mode 100644 lily/include/page-breaking.hh delete mode 100644 lily/include/page-spacing.hh delete mode 100644 lily/include/page-turn-page-breaking.hh create mode 100644 lily/include/percent-repeat-iterator.hh create mode 100644 lily/include/score-context.hh create mode 100644 lily/include/score-translator.hh create mode 100644 lily/include/sequential-music-iterator.hh create mode 100644 lily/include/staff-symbol-engraver.hh create mode 100644 lily/include/tfm-reader.hh create mode 100644 lily/include/tfm.hh delete mode 100644 lily/instrument-switch-engraver.cc create mode 100644 lily/midi-def.cc delete mode 100644 lily/optimal-page-breaking.cc delete mode 100644 lily/page-breaking-scheme.cc delete mode 100644 lily/page-breaking.cc delete mode 100644 lily/page-spacing.cc delete mode 100644 lily/page-turn-engraver.cc delete mode 100644 lily/page-turn-page-breaking.cc delete mode 100644 lily/scale.cc create mode 100644 lily/score-context.cc create mode 100644 lily/score-translator.cc create mode 100644 lily/sequential-music-iterator.cc delete mode 100644 lily/spacing-options.cc create mode 100644 lily/tfm-reader.cc create mode 100644 lily/tfm.cc delete mode 100644 ly/lilypond-book-preamble.ly delete mode 100644 scm/layout-page-dump.scm delete mode 100644 stepmake/stepmake/po-vars.make delete mode 100644 tex/quotes.patch diff --git a/ChangeLog b/ChangeLog index 549e153de2..88550130b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2360 +1,10 @@ -2006-10-08 Nicolas Sceaux - - * Documentation/user/page.itely (Two-pass vertical spacing): add - documentation for two-pass spacing technique. - -2006-10-06 Graham Percival - - * Documentation/user/convert-ly.txt: new file; new - storage place for this file (moved from bugs/ CVS). - -2006-10-06 Jürgen Reuter - - * lily/note-head.cc: Fixed programming_error message. - -2006-10-06 Han-Wen Nienhuys - - * 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 - - * 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 - - * Documentation/user/advanced-notation.itely: added - info about instrument names for piano or other contexts, - thanks Marcus! - -2006-10-04 Han-Wen Nienhuys - - * 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 - - * python/lilylib.py (progress): Minor fix. - -2006-10-04 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * scm/define-grob-properties.scm (all-user-grob-properties): - mention stencil as user settable. - -2006-10-02 Joe Neeman - - * 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 - - * 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 - - * po/fi.po: Fix spaces, commas etc. in Finnish translation using - KBabel fix tool. - -2006-10-01 Nicolas Sceaux - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * lily/page-breaking.cc (make_pages): honour the first-page-number - property - -2006-09-27 Han-Wen Nienhuys - - * VERSION (PACKAGE_NAME): bump version. - -2006-09-26 Pal Benko - - * 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 - - * lily/part-combine-iterator.cc: solo1-event -> solo-one-event - -2006-09-26 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * Documentation/user/programming-iterfaces.itely: fix - def-music-function -> define-music... leftover. - -2006-09-23 Joe Neeman - - * lily/page-spacing.cc (min_page_count): by running the loop - backwards, we can calculate ragged_last properly. - -2006-09-22 Mats Bengtsson - - * 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 - - * 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 - - * Documentation/user/tweaks.itely (Fitting music onto fewer - pages): change settings to avoid warning messages. - -2006-09-21 Mats Bengtsson - - * Documentation/user/tweaks.itely (Fitting music onto fewer - pages): Add between-system-space setting. - -2006-09-21 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * Documentation/user/basic-notation.itely: add bug - warning about ties and octavation/clef. - -2006-09-18 Han-Wen Nienhuys - - * VERSION (PACKAGE_NAME): release 2.9.18 - -2006-08-29 Milan Zamazal - - * elisp/lilypond-mode.el (LilyPond-command-alist): Don't try to - figure out midi file names right here. - -2006-09-17 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * ly/engraver-init.ly: Make FiguredBass accepted in GrandStaff and - PianoStaff. - -2006-09-08 Joe Neeman - - * Documentation/user/page.itely: update page breaking documentation - -2006-09-07 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * Documentation/user/invoking.itely: small update on - MacOS X notes; thanks Trevor! - -2006-09-01 Han-Wen Nienhuys - - * 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 - - * 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 - - * Documentation/topdocs/NEWS.itely: add @c marker for - stuff I've processed. - - * Documentation/user/ various: info from NEWS. - -2006-08-27 Joe Neeman - - * lily/paper-column-engraver.cc (finalize): Oops, this change - should have gone in on 2006-08-23 - -2006-08-26 Mats Bengtsson - - * 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 - - * scripts/musicxml2ly.py: fix for importing - minor key signatures from MusicXML. (Phillip Kirlin) - -2006-08-24 Phillip Kirlin - - * python/musicxml.py: - (Attributes.get_key_signature): now correctly retrieves mode from - MusicXML. - -2006-08-25 Han-Wen Nienhuys - - * 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 - - * input/mutopia/*: upgrade to new midi tempo syntax (repairs make - web partially) - -2006-08-24 Han-Wen Nienhuys - - * 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 - - * Documentation/user/changing-defaults.itely, global.itely, - lilypond-book.itely, page.itely: minor changes from mailist. - -2006-08-23 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * scripts/lilypond-book.py (output): Remove obsolete(!?) - \catcode`\@=12 in the LaTeX output. - -2006-08-11 Han-Wen Nienhuys - - * scm/define-music-types.scm (music-descriptions): - use sustain-event iso. sustain-pedal-event. - -2006-08-11 Joe Neeman - - * scripts/convert-ly.py: honour the -n command-line switch - -2006-08-10 Han-Wen Nienhuys - - * scm/output-lib.scm (bar-line::calc-glyph-name): add dashed liine - break specification. - -2006-08-10 Joe Neeman - - * Documentation/user: convert-ly the user manual - -2006-08-09 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * lily/beam-engraver.cc (listen_beam): add method for - Grace_beam_engraver too. - -2006-08-03 Mats Bengtsson - - * 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 - - * 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 - - * input/test/instrument-name-align.ly: update version. - -2006-08-02 Mats Bengtsson - - * Documentation/user/lilypond-book.itely (Invoking lilypond-book): - Doc the --pdf flag to lilypond-book. - -2006-07-31 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * lily/instrument-name-engraver.cc: formatting. - - * python/convertrules.py (conv): bugfix for \epsfile. - -2006-07-25 Joe Neeman - - * lily/grob.cc: - - * lily/gourlay-breaking.cc: Oops, these should have been included - in my last commit - -2006-07-24 Han-Wen Nienhuys - - * scripts/*.py (program_name): cleanup relocation snippets. - - * scripts/convert-ly.py (datadir): remove LILYPONDPREFIX support. - -2006-07-24 Joe Neeman - - * 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 - - * VERSION (PACKAGE_NAME): release 2.9.13 - - * scm/define-grobs.scm (all-grob-descriptions): remove stray - assignment. - -2006-07-21 Han-Wen Nienhuys - - * 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 - - * lily/parser.yy: compile fix. - -2006-07-20 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * lily/parser.yy, lily/lexer.ll: added some simplifications by - Angelo Contardi. - -2006-07-19 Graham Percival - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * Documentation/user/ various: general improvements to - "working with lilypond files" section. - -2006-07-03 Erik Sandberg - - * 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 - - * Documentation/user/basic-notation.itely: clarify \repeatTie. - -2006-06-27 Erik Sandberg - - * lily/parser.yy: Wrap non-post-events in EventChords before - assigning them to identifiers. - -2006-06-27 Mats Bengtsson - - * 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 - - * Documentation/user/invoking.itely : minor update from mailist. - -2006-06-26 Erik Sandberg - - * 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 - - * Documentation/user/ various: small additions from mailist. - -2006-06-22 Mats Bengtsson - - * 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 - - * Documentation/user/ various: minor spelling fixes; - thanks Dave Luttinen! - - * Documentation/user/ various: small clarifications; - thanks Anthony Youngman! - -2006-06-20 Han-Wen Nienhuys - - * po/fr.po: add \n appropriately. - - * lily/lexer.ll: remove ? from version-seen? - -2006-06-19 John Mandereau - - * po/fr.po; update translation, by Jean-Charles Malahieude and - John Mandereau. - -2006-06-19 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * Documentation/user/ various: small fixes from mailist. - -2006-06-16 Han-Wen Nienhuys - - * 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 - - * VERSION (PACKAGE_NAME): release 2.9.9 - - * ly/lilypond-book-preamble.ly: add \version - -2006-06-14 Han-Wen Nienhuys - - * 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 - - * Documentation/user/tutorial.itely: trivial fix. - -2006-06-13 Erik Sandberg - - * 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 - - * 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 - - * Documentation/user/ page.itely, global.itely: editing - and reorg. - - * Documentation/user/ various: findex -> funindex. - -2006-06-10 Erik Sandberg - - * lily/time-scaled-music-iterator.cc: Use tupletSpannerDuration to - insert extra tuplet events. - -2006-06-10 Graham Percival - - * 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 - - * scm/define-markup-commands.scm (wordwrap-markups): use - output-def 'line-width if undefined. - - * HACKING: trim outdated info. - -2006-06-09 Mats Bengtsson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * input/test/ smart-transpose.ly, reverse-music.ly: - \applyMusic to music functions update, thanks Michael! - -2006-06-07 Graham Percival - - * 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 - - * SConstruct (LILYPONDPREFIX): Bootstrap fix. - -2006-06-06 Graham Percival - - * Documentation/user/advanced-notation.itely: add example - for segno/coda on barline. - - * tex/texinfo.tex: merge from upstream. - -2006-06-06 Jan Nieuwenhuizen - - * 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 - - * lily/font-config.cc (init_fontconfig): Only initialize if - global cache_file is found. - -2006-06-06 Erik Sandberg - - * ly/music-functions-init.ly: Updated \overrideProperty to use the - new \applyOutput. - -2006-06-06 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 - - * lily/tuplet-number.cc (print): prevent stencil from being - garbage collected. - -2006-06-05 Han-Wen Nienhuys - - * 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 - - * Documentation/user/music-glossary.tely: clarified example - from Francisco Vila, thanks! - -2006-06-05 Han-Wen Nienhuys - - * 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 - - * scm/paper-system.scm (paper-system-annotate): fix problem when - annotating an empty system - -2006-06-04 Han-Wen Nienhuys - - * GNUmakefile.in: reinstate old web tar/copying. - -2006-06-03 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * 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 - - * make/mutopia-rules.make: remove duplicate recipe. - -2006-06-02 Werner Lemberg - - * tex/texinfo.cnf: Fix typo (\euro -> \minus). - Add support for U+0132 (IJ) and U+0133 (ij). - -2006-06-02 Han-Wen Nienhuys - - * 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 - - * tex/texinfo.tex: partial fix for @funindex. - - * Documentation/user/macros.tely: uncomment @funindex (doesn't - break anything). - -2006-06-02 Han-Wen Nienhuys - - * 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 - - * tex/texinfo.cnf: added UTF-8 support for texinfo; patch - from Werner Lemberg. - -2006-06-02 Paco (Francisco Vila) - - * Documentation/user/music-glossary.tely: additional spanish - updates and a lyrics fix in an example. - -2006-06-02 Jürgen Reuter - - * 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 - - * 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 - - * 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 - - * GNUmakefile.in (tree-lib-prefix-current): - (tree-share-prefix-current): Use version number in tree, add - `current' symlinks. - -2006-06-01 Han-Wen Nienhuys - - * 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 - - * 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 - - * 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 - - * config.make.in (datadir): Add datarootdir to silence autoconf. - - * stepmake/aclocal.m4: Update for autoconf-2.59d. - 2006-05-31 Erlend Aasland * 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 + * 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 * lily/relocate.cc (read_relocation_dir): Do not blindly @@ -2407,7 +57,7 @@ * ly/Welcome-to-LilyPond-MacOS.ly: include in LilyPond, so version number stays up to date. Backportme. -2006-05-30 Mats Bengtsson +2006-05-30 Mats Bengtsson * Documentation/user/basic-notation.itely (Bar lines): Document the "||:" bar type. @@ -2742,7 +392,7 @@ * Documentation/topdocs/NEWS.tely (Top): add hairpinToBarline feature. -2006-05-16 Mats Bengtsson +2006-05-16 Mats Bengtsson * Documentation/user/advanced-notation.itely (Instrument names): Modified obsolete instruction on how to move instrument names away @@ -2843,7 +493,7 @@ * Documentation/user/ various: small fixes. -2006-05-12 Mats Bengtsson +2006-05-12 Mats Bengtsson * Documentation/user/programming-interface.itely (Markup programmer interface): Remove duplicate text. @@ -3156,7 +806,7 @@ * lily/relocate.cc (framework_relocation): remove old relocation stuff. -2006-05-01 Mats Bengtsson +2006-05-01 Mats Bengtsson * scm/define-grob-properties.scm (all-user-grob-properties): Correct typo, thanks to Eduardo. @@ -3198,7 +848,7 @@ * python/convertrules.py (conv): indent 4 for python files. -2006-04-29 Mats Bengtsson +2006-04-29 Mats Bengtsson * Documentation/user/changing-defaults.itely (Creating contexts): Clarify \new semantics. @@ -3403,7 +1053,7 @@ * scm/define-context-properties.scm (all-user-translation-properties): * Documentation/user/global.itely (Page formatting): Compile fix. -2006-04-09 Mats Bengtsson +2006-04-09 Mats Bengtsson * Documentation/user/advanced-notation.itely (Polymetric notation): Update the example to use the "+" symbol and add link @@ -3566,7 +1216,7 @@ * lily/pango-font.cc (pango_item_string_stencil): only use uXXX glyphnames if we have a ttf font. -2006-03-30 Mats Bengtsson +2006-03-30 Mats Bengtsson * Documentation/user/advanced-notation.itely (Font selection): Corrected reference to the font-family-override.ly example. @@ -3902,7 +1552,7 @@ * Documentation/user/global.itely: small fix from mailist. -2006-03-14 Mats Bengtsson +2006-03-14 Mats Bengtsson * scripts/lilypond-book.py (LATEX_INSPECTION_DOCUMENT): Use the file descriptor returned by tempfile.mkstemp() when writing @@ -3943,7 +1593,7 @@ * ly/engraver-init.ly: init rehearsalMarkAlignSymbol to staff-bar. -2006-03-12 Mats Bengtsson +2006-03-12 Mats Bengtsson * Documentation/user/instrument-notation.itely (Setting simple songs): Added \book{...} around the full example, so the separate @@ -5619,7 +3269,7 @@ * lily/main.cc: * configure.in: Cosmetic fixes. -2006-01-04 Mats Bengtsson +2006-01-04 Mats Bengtsson * Documentation/user/music-glossary.tely (Pitch names): Added Spanish pitch names and durations, thanks to Ernesto Gancedo @@ -6302,7 +3952,7 @@ * lily/all-font-metrics.cc (kpathsea_find_file): use (scm kpathsea) module. -2005-11-29 Mats Bengtsson +2005-11-29 Mats Bengtsson * Documentation/user/advanced-notation.itely (Setting automatic beam behavior): Correct a few typos. Thanks to David Bobroff. @@ -6401,7 +4051,7 @@ * python/midi.c: doc module. -2005-11-22 Mats Bengtsson +2005-11-22 Mats Bengtsson * Documentation/user/global.itely (Creating MIDI files): Fix compilation problem. @@ -6497,7 +4147,7 @@ * lily/clef-engraver.cc (inspect_clef_properties): reset localKeySignature for clef changes. -2005-11-17 Mats Bengtsson +2005-11-17 Mats Bengtsson * python/midi.c: PyMIDINIT_FUNC isn't defined in Python < 2.3 add dummy definition that works in Linux and add information in @@ -6509,7 +4159,7 @@ * Documentation/user/music-glossary.tely (dal segno): Updated example to version >=2.6. -2005-11-16 Mats Bengtsson +2005-11-16 Mats Bengtsson * Documentation/user/instrument-notation.itely (Printing chord names): Reorder \chordmode and \repeat in one example. @@ -6669,7 +4319,7 @@ * scripts/lilypond-book.py (main): use commands.mkarg () to quote shell arguments. -2005-11-10 Mats Bengtsson +2005-11-10 Mats Bengtsson * Documentation/user/examples.itely (Piano templates): Minor modification to the Piano centered lyrics example. @@ -6857,7 +4507,7 @@ * scm/define-grob-properties.scm (all-user-grob-properties): remove [XY]-offset-callbacks add [YX]-offset -2005-11-02 Mats Bengtsson +2005-11-02 Mats Bengtsson * scm/define-grobs.scm (all-grob-descriptions): Added space-alist entry for time signatures after breathing signs. Bug report by @@ -7541,7 +5191,7 @@ * lily/include/horizontal-bracket.hh (struct Horizontal_bracket): new file. -2005-10-04 Mats Bengtsson +2005-10-04 Mats Bengtsson * scripts/lilypond-book.py: Bug fix, put the quote around the actual score for LaTeX documents. @@ -7724,7 +5374,7 @@ * scm/define-music-types.scm (music-descriptions): set length and start-callback for QuoteMusic -2005-09-15 Mats Bengtsson +2005-09-15 Mats Bengtsson * lily/tie.cc (get_configuration): Replace fabs -> abs for integer arguments. Fixes compilation error with gcc 3.3. @@ -7897,7 +5547,7 @@ * Documentation/user/advanced-notation.itely, basic-notation.itely: minor changes. -2005-08-31 Mats Bengtsson +2005-08-31 Mats Bengtsson * scm/framework-eps.scm (dump-stencils-as-EPSes): Insert a \linebreak between each .eps file if \betweenLilyPondSystem is @@ -8033,7 +5683,7 @@ * scm/define-markup-commands.scm (null): add null markup. -2005-08-25 Mats Bengtsson +2005-08-25 Mats Bengtsson * lily/item.cc: Add documentation of center-invisible @@ -8136,7 +5786,7 @@ * lily/skyline.cc: fix ASCII art. -2005-08-22 Mats Bengtsson +2005-08-22 Mats Bengtsson * python/convertrules.py (string_or_scheme): Fix spelling error @@ -8249,7 +5899,7 @@ * lily/include/performer-group.hh: rename. -2005-08-18 Mats Bengtsson +2005-08-18 Mats Bengtsson * input/test/script-abbreviations.ly: Removed some old LaTeX left overs. @@ -8391,7 +6041,7 @@ 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 +2005-08-16 Mats Bengtsson * scripts/lilypond-book.py (option_definitions): Don't localize the empty string. Fixes bug when --psfonts was used with @@ -8448,7 +6098,7 @@ * tex/GNUmakefile (INSTALLATION_FILES): Remove enc symlink setup, encoding files are already removed. -2005-08-15 Mats Bengtsson +2005-08-15 Mats Bengtsson * Documentation/user/advanced-notation.itely (Instrument names): Document a workaround for instrument names that collide with @@ -8500,7 +6150,7 @@ * Documentation/user/advanced-notation.itely: add markup example to Text spanners. -2005-08-12 Mats Bengtsson +2005-08-12 Mats Bengtsson * Documentation/user/basic-notation.itely (Ties): Add example of tying a tremolo to a chord. Thanks to Steve Doonan. @@ -8557,7 +6207,7 @@ do_shift if script inside slur, even if slur not contained in script y-extent. Increment k in loop. -2005-08-11 Mats Bengtsson +2005-08-11 Mats Bengtsson * scm/define-markup-commands.scm: Improved regexp to search for EPS bounding boxes and corrected call to ly:warning. @@ -8568,7 +6218,7 @@ expressions): doc for \displayLilyMusic. Also some precisions in "Markup construction in Scheme" -2005-08-10 Mats Bengtsson +2005-08-10 Mats Bengtsson * scm/define-markup-commands.scm (normal-text): Added 2 new markup commands, \normal-text and \medium (the latter thanks to @@ -8599,7 +6249,7 @@ * Documentation/user/basic-notation.itely: reword multi-measure rest discussion in Rests. -2005-08-08 Mats Bengtsson +2005-08-08 Mats Bengtsson * Documentation/user/programming-interface.itely (Markup construction in Scheme): Corrected example and tried to clarify @@ -8808,7 +6458,7 @@ * mf/feta-generic.mf: add feta-arrow. -2005-08-03 Mats Bengtsson +2005-08-03 Mats Bengtsson * Documentation/user/lilypond-book.itely (An example of a musicological document): Added flag -o to dvips for people who use @@ -8847,7 +6497,7 @@ * ly/declarations-init.ly (center): escape to Scheme. Fixes spurious # errors. Backportme. -2005-08-03 Mats Bengtsson +2005-08-03 Mats Bengtsson * Documentation/user/programming-interface.itely (Markup construction in Scheme): Corrected markup syntax in the @@ -9561,7 +7211,7 @@ * Documentation/user/lilypond.itely: change encoding to utf-8. -2005-07-01 Mats Bengtsson +2005-07-01 Mats Bengtsson * Documentation/user/advanced-notation.itely (Setting automatic beam behavior): Correct the documentation of @@ -9641,7 +7291,7 @@ * scm/midi.scm: compile fix. -2005-06-28 Mats Bengtsson +2005-06-28 Mats Bengtsson * scripts/lilypond-book.py : Fix embarrassing bug in my previous patch. Now, the tempfile module is loaded too, not only used. @@ -9741,7 +7391,7 @@ * buildscripts/gen-emmentaler-scripts.py (notice): add GPL notice to fonts. -2005-06-23 Mats Bengtsson +2005-06-23 Mats Bengtsson * scripts/lilypond-book.py (LATEX_DOCUMENT): More or less ugly workaround since /dev/stdin doesn't work on Cygwin. Using a @@ -9903,7 +7553,7 @@ * scm/backend-library.scm (postprocess-output): remove debugging gobs. -2005-06-14 Mats Bengtsson +2005-06-14 Mats Bengtsson * Documentation/topdocs/NEWS.tely (Top): Corrected name of \musicDisplay @@ -10285,7 +7935,7 @@ * lily/main.cc (prepend_env_path, set_env_file): Use them. -2005-06-02 Mats Bengtsson +2005-06-02 Mats Bengtsson * lily/easy-notation.cc: Added include cctype to correct compilation error. @@ -10765,7 +8415,7 @@ * lily/main.cc (setup_paths)[ARGV0_RELOCATION]: Remove GS_*. -2005-05-16 Mats Bengtsson +2005-05-16 Mats Bengtsson * lily/horizontal-bracket.cc (print): Take care of the direction property so brackets above the stave point downwards. @@ -10965,7 +8615,7 @@ Documentation/user/tutorial.itely: begin pruning unused (duplicated) cindex entries and misc cleanup. -2005-05-12 Mats Bengtsson +2005-05-12 Mats Bengtsson * input/test/volta-chord-names.ly: Bring the explanation up to date. @@ -11056,7 +8706,7 @@ * configure.in (gui_b): Add mbrtowc checking. Resurrect [utf8/]wchar.h checking. -2005-05-09 Mats Bengtsson +2005-05-09 Mats Bengtsson * Documentation/user/advanced-notation.itely (Metronome marks): Add link to the program reference for MetronomeMark @@ -11078,7 +8728,7 @@ * lily/general-scheme.cc (LY_DEFINE): hand-convert utf8 to 32 bits. Patch by Matthias Neeracher. -2005-05-09 Mats Bengtsson +2005-05-09 Mats Bengtsson * scripts/convert-ly.py: In the conversion to version 1.9.0, keep Scheme expressions and strings unmodified when doing the @@ -11199,7 +8849,7 @@ * Documentation/user/programming-interface.itely (How markups work internally ): remove \encoding reference. -2005-05-04 Mats Bengtsson +2005-05-04 Mats Bengtsson * scripts/convert-ly.py: Attempt to do a smarter update of text markups from versions < 1.9.0 with arbitrary nesting. @@ -11362,7 +9012,7 @@ * configure.in: Search for mingw wcrtomb library. -2005-05-02 Mats Bengtsson +2005-05-02 Mats Bengtsson * scripts/convert-ly.py: Bug fix @@ -11397,7 +9047,7 @@ * Documentation/user/advanced-notation.itely: corrected docs concerning remove-first. -2005-04-29 Mats Bengtsson +2005-04-29 Mats Bengtsson * lily/part-combine-engraver.cc: make sure that the relevant properties are included in the documentation. @@ -12562,7 +10212,7 @@ lilypond-book filter example and warned about not doing --filter and --process at the same time. -2005-03-23 Mats Bengtsson +2005-03-23 Mats Bengtsson * lily/parser.yy (bass_number), Documentation/user/instrument-notation.itely (Figured bass): @@ -14344,7 +11994,7 @@ * mf/feta-test-generic.mf: Include all files as in feta-generic.mf. -2005-01-13 Mats Bengtsson +2005-01-13 Mats Bengtsson * Documentation/user/notation.itely (Ancient rests): Fix typo (thanks Anthony) @@ -14572,7 +12222,7 @@ dump systems as separate .eps files (without fonts) and write a single collecting .tex file. -2005-01-05 Mats Bengtsson +2005-01-05 Mats Bengtsson * Documentation/user/notation.itely (Setting simple songs): Correct several errors in the equivalent formulation of @@ -15151,7 +12801,7 @@ * scm/output-svg.scm (svg-font): Add weight to font selection. -2004-12-14 Mats Bengtsson +2004-12-14 Mats Bengtsson * Documentation/topdocs/INSTALL.texi (Top): Point to buildscripts/out/clean-fonts instead of @@ -15408,7 +13058,7 @@ * lily/vaticana-ligature.cc: Fix for MacOS X: use instead of beacause isinf/isnan is undefined in -2004-12-03 Mats Bengtsson +2004-12-03 Mats Bengtsson * cygwin/lily-wins.py (stat): remove old flag -p when calling lilypond. @@ -16029,7 +13679,7 @@ * buildscripts/guile-gnome.sh: Update. -2004-11-10 Mats Bengtsson +2004-11-10 Mats Bengtsson * scm/define-grobs.scm (all-grob-descriptions): Added line-interface to the LigatureBracket object. @@ -16286,7 +13936,7 @@ * tex/texinfo.tex: Updated from texinfo CVS -- this version provides better output for multicolumn tables. -2004-11-01 Mats Bengtsson +2004-11-01 Mats Bengtsson * lily/main.cc (dir_info): Fixed typo in the printouts. diff --git a/DEDICATION b/DEDICATION index 264945471c..f7bbafa0a4 100644 --- a/DEDICATION +++ b/DEDICATION @@ -8,8 +8,8 @@ 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 diff --git a/Documentation/GNUmakefile b/Documentation/GNUmakefile index a56d00d9f2..2b57b008f9 100644 --- a/Documentation/GNUmakefile +++ b/Documentation/GNUmakefile @@ -1,7 +1,7 @@ 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)"' diff --git a/Documentation/misc/GNUmakefile b/Documentation/misc/GNUmakefile index b84aa786b8..2e22c03997 100644 --- a/Documentation/misc/GNUmakefile +++ b/Documentation/misc/GNUmakefile @@ -4,7 +4,7 @@ NAME = documentation 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 diff --git a/Documentation/pictures/GNUmakefile b/Documentation/pictures/GNUmakefile index 6665721085..44ec78bdca 100644 --- a/Documentation/pictures/GNUmakefile +++ b/Documentation/pictures/GNUmakefile @@ -1,7 +1,7 @@ depth = ../.. STEPMAKE_TEMPLATES=documentation -XPM_FILES=$(call src-wildcard,*.xpm) +XPM_FILES=$(wildcard *.xpm) EXTRA_DIST_FILES= $(XPM_FILES) lilypond-icon = $(outdir)/lilypond.ico diff --git a/Documentation/topdocs/GNUmakefile b/Documentation/topdocs/GNUmakefile index d1ff875651..2659703f4f 100644 --- a/Documentation/topdocs/GNUmakefile +++ b/Documentation/topdocs/GNUmakefile @@ -13,4 +13,3 @@ endif $(outdir)/NEWS.nexi: NEWS.tely - diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 44ab684aca..8a3ee81466 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -66,165 +66,6 @@ which scares away people. @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] - -@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 @@ -234,7 +75,7 @@ View @uref{../../test-results.html,test results}. @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] << @@ -337,13 +178,10 @@ support for feathered beaming, \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 diff --git a/Documentation/user/GNUmakefile b/Documentation/user/GNUmakefile index d58ce5c1bc..71e82b75c3 100644 --- a/Documentation/user/GNUmakefile +++ b/Documentation/user/GNUmakefile @@ -2,24 +2,26 @@ depth=../.. 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) @@ -36,6 +38,10 @@ export TEXINPUTS include $(depth)/make/stepmake.make +dvi: $(DVI_FILES) + +ps: $(PS_FILES) + info: $(INFO_FILES) pathsettings: @@ -189,7 +195,7 @@ $(outdir)/lilypond-internals/lilypond-internals.xml: $(outdir)/lilypond-internal 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% $< $@ @@ -203,13 +209,6 @@ $(outdir)/%.eps: %.png $(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\ diff --git a/Documentation/user/README.txt b/Documentation/user/README.txt index ba2f98793a..48e01fa560 100644 --- a/Documentation/user/README.txt +++ b/Documentation/user/README.txt @@ -1,7 +1,7 @@ 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 @@ -41,10 +41,10 @@ is writtin in formal technical writing style. 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. diff --git a/Documentation/user/SConscript b/Documentation/user/SConscript index 5ef1efdd3d..bbdf7aec77 100644 --- a/Documentation/user/SConscript +++ b/Documentation/user/SConscript @@ -3,9 +3,9 @@ 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']) @@ -13,16 +13,13 @@ env.Depends ('music-glossary.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'], diff --git a/Documentation/user/advanced-notation.itely b/Documentation/user/advanced-notation.itely index c5a868393d..8d3186dc1b 100644 --- a/Documentation/user/advanced-notation.itely +++ b/Documentation/user/advanced-notation.itely @@ -75,9 +75,9 @@ The @code{\markup} is described in more detail in @refcommands -@funindex \fatText +@findex \fatText @code{\fatText}, -@funindex \emptyText +@findex \emptyText @code{\emptyText}. @@ -157,14 +157,13 @@ Examples: @inputfileref{input/@/regression,text@/-spanner@/.ly}. @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" } @@ -291,7 +290,7 @@ but it can also be used anywhere text is called in lilypond #'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 @@ -305,7 +304,7 @@ but it can also be used anywhere text is called in lilypond 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. } @@ -451,7 +450,7 @@ The following commands can all be used inside @code{\markup @{ @}}. @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 @@ -505,12 +504,6 @@ then set the @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 @@ -620,7 +613,7 @@ individual parts. @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 @@ -742,7 +735,7 @@ Metronome settings can be entered as follows 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 @@ -792,7 +785,7 @@ further away from the staff. @subsection Rehearsal marks @cindex Rehearsal marks -@funindex \mark +@findex \mark To print a rehearsal mark, use the @code{\mark} command @@ -843,24 +836,6 @@ You may use @code{format-mark-barnumbers}, @code{format-mark-box-barnumbers}, 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} @@ -905,7 +880,7 @@ Examples: @inputfileref{input/@/regression,rehearsal@/-mark@/-letter@/.ly}, @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 @@ -976,15 +951,13 @@ In an orchestral score, instrument names are printed at the left side 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'' @@ -994,7 +967,7 @@ You can also use markup texts to construct more complicated instrument 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 @@ -1005,13 +978,13 @@ If you wish to center the instrument names, you must center all of them @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 } >> @@ -1027,30 +1000,18 @@ To center instrument names while leaving extra space to the right, \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 @@ -1175,7 +1136,7 @@ during an octavation bracket. @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 @@ -1639,6 +1600,15 @@ that fits into traditional notation categories, such as 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:: @@ -1647,7 +1617,6 @@ see those sections of the documentation. * Special noteheads:: * Feathered beams:: * Improvisation:: -* Selecting notation font size:: @end menu @@ -1909,8 +1878,6 @@ accurately. Use @code{8 8} instead. @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, @@ -1938,22 +1905,26 @@ Program reference: @internalsref{NoteHead}. @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 @@ -1987,62 +1958,6 @@ the following example @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 @@ -2127,8 +2042,8 @@ emptymusic = { @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. @@ -2144,8 +2059,6 @@ g4 a @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. @@ -2163,10 +2076,10 @@ Shape note heads can be produced by setting @code{\aikenHeads} or 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 @@ -2182,8 +2095,6 @@ combinations are possible, e.g. @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 @@ -2202,7 +2113,7 @@ to be printed in a large font size. To print with a larger font, see @refcommands -@funindex \setEasyHeads +@findex \setEasyHeads @code{\setEasyHeads} @@ -2256,7 +2167,7 @@ e @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 @@ -2288,7 +2199,7 @@ deliberate nonsense. @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 diff --git a/Documentation/user/basic-notation.itely b/Documentation/user/basic-notation.itely index 6115449cdf..0e7086d869 100644 --- a/Documentation/user/basic-notation.itely +++ b/Documentation/user/basic-notation.itely @@ -64,8 +64,8 @@ c1 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 @@ -92,21 +92,20 @@ octave specifications (@code{'} and @code{,}). See @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. @@ -117,18 +116,6 @@ suffix; a natural pitch is shown as a simple note name 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 @@ -157,10 +144,10 @@ Program reference: @internalsref{LedgerLineSpanner}, @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 @@ -215,7 +202,7 @@ file. The available language files 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 @@ -237,7 +224,7 @@ espanol.ly do re mi fa sol la sib si -s -b @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 @@ -283,7 +270,6 @@ Here is the relative mode shown in action @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'' @@ -301,7 +287,7 @@ to determine the first note of the next chord } @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 @@ -335,13 +321,11 @@ There is also an octave check that produces no visible output. The syntax @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 @@ -376,7 +360,7 @@ the output of the piece. @cindex Transpose @cindex Transposition of pitches -@funindex \transpose +@findex \transpose A music expression can be transposed with @code{\transpose}. The syntax is @@ -430,7 +414,7 @@ begins on concert D, one would write \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} @@ -443,14 +427,12 @@ 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}. @@ -458,8 +440,8 @@ you must put @code{\transpose} outside of @code{\relative}, since @subsection Rests @cindex Rests -@funindex \rest -@funindex r +@findex \rest +@findex r Rests are entered like notes with the note name @code{r} @@ -496,8 +478,8 @@ Program reference: @internalsref{Rest}. @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}} @@ -556,16 +538,16 @@ This section discusses rhythms, durations, and bars. @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 @@ -586,11 +568,6 @@ r1 r2 r4 r8 r16 r32 r64 r64 } \layout { ragged-right = ##t - indent=0\mm - \context { - \Score - \remove "Bar_number_engraver" - } \context { \Staff \remove "Clef_engraver" @@ -614,7 +591,7 @@ duration. The default for the first note is a quarter note. @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. @@ -629,11 +606,11 @@ Dots are normally moved up to avoid staff lines, except in polyphonic 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 @@ -646,7 +623,7 @@ Program reference: @internalsref{Dots}, and @internalsref{DotColumn}. @cindex tuplets @cindex triplets -@funindex \times +@findex \times Tuplets are made out of a music expression by multiplying all durations with a fraction @@ -669,7 +646,7 @@ g'4 \times 2/3 {c'4 c' c'} d'4 d'4 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 } @@ -678,17 +655,17 @@ Tuplets may be nested, for example, @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 @@ -706,10 +683,11 @@ used once 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 @@ -719,26 +697,6 @@ 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 @@ -775,8 +733,8 @@ This manual: @ref{Tuplets} @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 @@ -801,8 +759,8 @@ durations. Incorrect durations often completely garble up the score, 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}, @@ -894,8 +852,8 @@ one voice on the same staff. @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] @@ -914,11 +872,11 @@ made invisible. @refcommands -@funindex \stemUp +@findex \stemUp @code{\stemUp}, -@funindex \stemDown +@findex \stemDown @code{\stemDown}, -@funindex \stemNeutral +@findex \stemNeutral @code{\stemNeutral}. @@ -944,7 +902,7 @@ The easiest way to enter fragments with more than one voice on a staff 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' { @@ -977,8 +935,6 @@ second 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 @@ -1146,24 +1102,24 @@ for example @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) @@ -1230,14 +1186,13 @@ such as key signatures, clefs and time signatures. * 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 @@ -1333,8 +1288,6 @@ possibilities when setting properties manually. @seealso -Manual: @ref{Grace notes}. - Program reference: @internalsref{Clef}. @@ -1342,7 +1295,7 @@ 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 @@ -1355,16 +1308,16 @@ command @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 @@ -1379,13 +1332,7 @@ can be specified by setting this property directly. 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 @@ -1418,7 +1365,7 @@ Program reference: @internalsref{KeyCancellation}, @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 @@ -1503,7 +1450,7 @@ Automatic beaming does not use the measure grouping specified with @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 @@ -1517,9 +1464,6 @@ The syntax for this command is \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 @@ -1527,9 +1471,7 @@ This is internally translated into @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 @@ -1550,7 +1492,7 @@ a2 g2 @subsection Bar lines @cindex Bar lines -@funindex \bar +@findex \bar @cindex measure lines @cindex repeat bars @@ -1581,12 +1523,11 @@ To allow a line break where there is no visible bar line, use @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] << @@ -1605,9 +1546,9 @@ connected between different staves of a @code{StaffGroup}, @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} @@ -1637,8 +1578,8 @@ Examples: @inputfileref{input/@/test,bar@/-lines@/.ly}, @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 @@ -1657,9 +1598,8 @@ d4 e d c @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 @@ -1667,7 +1607,7 @@ invisible bar lines @end example @noindent -to indicate where breaks can occur. +to indicate where line breaks can occur. @node System start delimiters @@ -1737,7 +1677,7 @@ The bar lines at the start of each system are @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 @@ -1748,7 +1688,7 @@ in every context, and that type is determined by the property 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 @@ -1791,28 +1731,6 @@ Examples: @inputfileref{input/@/test,staff@/-lines@/.ly}, @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 @@ -1834,7 +1752,7 @@ This section deals with notation that affects groups of 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 @@ -1846,12 +1764,7 @@ e' ~ e' ~ @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] - -@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 @@ -1877,8 +1790,6 @@ automatic note splitting (see @ref{Automatic note splitting}). This 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}, @@ -1900,24 +1811,23 @@ for example, to tie a tremolo to a chord. For example, \set tieWaitForNote = ##t \grace { c16[~ e~ g]~ } 2 \repeat "tremolo" 8 { c32~ c'~ } 1 -e8~ 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}. @@ -1938,9 +1848,6 @@ Examples: 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 @@ -1985,17 +1892,17 @@ be achieved in LilyPond by setting @code{doubleSlurs}, @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 @@ -2028,11 +1935,11 @@ You cannot have simultaneous phrasing slurs. @refcommands -@funindex \phrasingSlurUp +@findex \phrasingSlurUp @code{\phrasingSlurUp}, -@funindex \phrasingSlurDown +@findex \phrasingSlurDown @code{\phrasingSlurDown}, -@funindex \phrasingSlurNeutral +@findex \phrasingSlurNeutral @code{\phrasingSlurNeutral}. @@ -2095,8 +2002,8 @@ Program reference: @internalsref{Beam}. @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 @@ -2112,8 +2019,8 @@ and end point with @code{[} and @code{]} @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 @@ -2142,7 +2049,7 @@ c16[ c c c c c c c] \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 @@ -2151,7 +2058,7 @@ 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 @@ -2173,7 +2080,7 @@ texts and accidentals. @node Grace notes @subsection Grace notes -@funindex \grace +@findex \grace @cindex ornaments @cindex grace notes @cindex appoggiatura @@ -2241,7 +2148,7 @@ every eighth grace note \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 @@ -2280,7 +2187,6 @@ A @code{\grace} section will introduce special typesetting settings, 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 { @@ -2297,8 +2203,8 @@ The overrides should also be reverted inside the grace section. 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 @{ @@ -2318,30 +2224,6 @@ Another option is to change the variables @code{startGraceMusic}, 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}. @@ -2390,7 +2272,6 @@ notes and rhythms. * Trills:: * Glissando:: * Arpeggio:: -* Falls and doits:: @end menu @@ -2556,23 +2437,23 @@ Examples: @inputfileref{input/@/regression,finger@/-chords@/.ly}. @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}, @@ -2586,9 +2467,9 @@ c\ppp c\pp c \p c\mp c\mf c\f c\ff c\fff 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 @@ -2604,13 +2485,7 @@ c\< c\! d\> e\! @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, @@ -2624,27 +2499,14 @@ in @internalsref{Voice}.@internalsref{Hairpin} to lengthen them, for 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 @@ -2689,8 +2551,7 @@ new line are not printed. To change this behavior, use \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 @@ -2700,11 +2561,11 @@ dashed line showing their extent. To surpress printing this line, use @refcommands -@funindex \dynamicUp +@findex \dynamicUp @code{\dynamicUp}, -@funindex \dynamicDown +@findex \dynamicDown @code{\dynamicDown}, -@funindex \dynamicNeutral +@findex \dynamicNeutral @code{\dynamicNeutral}. @@ -2765,7 +2626,7 @@ Long running trills are made with @code{\startTrillSpan} and 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 @@ -2777,9 +2638,9 @@ is printed as a stemless note head in parentheses. @refcommands @code{\startTrillSpan}, -@funindex \startTrillSpan +@findex \startTrillSpan @code{\stopTrillSpan}. -@funindex \stopTrillSpan +@findex \stopTrillSpan @seealso @@ -2791,7 +2652,7 @@ Program reference: @internalsref{TrillSpanner}. @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 @@ -2821,7 +2682,7 @@ Printing text over the line (such as @emph{gliss.}) is not supported. @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 @@ -2869,13 +2730,13 @@ in both staves and set @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}. @@ -2892,17 +2753,7 @@ It is not possible to mix connected arpeggios and unconnected 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 @@ -2926,7 +2777,7 @@ for repetitions. @subsection Repeat types @cindex repeats -@funindex \repeat +@findex \repeat The following types of repetition are supported @@ -2955,7 +2806,7 @@ Make tremolo beams. These are not played in MIDI output by default. @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 @@ -2971,7 +2822,7 @@ repeats. The syntax is @end example If you have alternative endings, you may add -@funindex \alternative +@findex \alternative @example \alternative @{ @var{alternative1} @@ -3000,8 +2851,8 @@ c1 \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 @@ -3015,16 +2866,6 @@ beginning of the example. } @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. @@ -3069,8 +2910,8 @@ having the @code{\alternative} belong to the inner @code{\repeat}. 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. @@ -3078,11 +2919,11 @@ example, by setting @code{Score.measurePosition} or entering @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] @@ -3098,8 +2939,8 @@ repeats to unfold repeats. \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, @@ -3118,7 +2959,7 @@ 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. @@ -3197,7 +3038,7 @@ Example files: @inputfileref{input/@/regression,chord@/-tremolo@/.ly}, @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 @@ -3254,10 +3095,10 @@ on the @code{countPercentRepeats} property, -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 diff --git a/Documentation/user/changing-defaults.itely b/Documentation/user/changing-defaults.itely index 97525e0c46..c38bd2a245 100644 --- a/Documentation/user/changing-defaults.itely +++ b/Documentation/user/changing-defaults.itely @@ -46,9 +46,9 @@ Context: changing aspects of the translation from music events to 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 @@ -84,7 +84,7 @@ beams are automatically displayed. 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 @@ -132,7 +132,7 @@ used by one musician (e.g., a conductor) then 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, @@ -145,7 +145,7 @@ cis' c'' cis'2 | c'' c' @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 @@ -154,14 +154,14 @@ 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 @@ -170,19 +170,19 @@ as cautionaries. Even though all accidentals typeset by 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] @@ -224,9 +224,9 @@ problematic notes. @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 @@ -355,31 +355,9 @@ In 4/4 time signature, this means that automatic beams could end only on 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 @@ -388,23 +366,11 @@ beaming should be switched off with @code{\autoBeamOff}. @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 @@ -507,7 +473,7 @@ create them by hand. There are three commands that do this. 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 @@ -540,7 +506,7 @@ However, this user specified name is only used if there is no other context already earlier with the same name. -@funindex \context +@findex \context @item Like @code{\new}, the @code{\context} command also directs a music @@ -637,7 +603,7 @@ these forms @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 @@ -689,7 +655,7 @@ example @context{Staff}, then the change would also apply to all `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 @@ -788,7 +754,7 @@ It can be useful to shuffle around these plug-ins. This is done by starting a new context with @code{\new} or @code{\context}, and modifying it, -@funindex \with +@findex \with @example \new @var{context} \with @{ @@ -1159,7 +1125,7 @@ Put together, we get @} @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} @@ -1172,7 +1138,7 @@ command, @} @end example -@funindex \denies +@findex \denies The opposite of @code{\accepts} is @code{\denies}, which is sometimes needed when reusing existing context definitions. @@ -1258,7 +1224,7 @@ properties. To tweak those, use commands in the form @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 @@ -1541,7 +1507,7 @@ Fingering_engraver is part of contexts: @dots{} @internalsref{Voice} @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, @@ -1625,7 +1591,7 @@ is more or less equivalent to 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. diff --git a/Documentation/user/convert-ly.txt b/Documentation/user/convert-ly.txt deleted file mode 100644 index 3f55cba429..0000000000 --- a/Documentation/user/convert-ly.txt +++ /dev/null @@ -1,47 +0,0 @@ -%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. diff --git a/Documentation/user/converters.itely b/Documentation/user/converters.itely index 451e59f9ce..f9b2392405 100644 --- a/Documentation/user/converters.itely +++ b/Documentation/user/converters.itely @@ -14,10 +14,7 @@ on 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 +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. diff --git a/Documentation/user/examples.itely b/Documentation/user/examples.itely index 015df0e8c4..9bb3dede2a 100644 --- a/Documentation/user/examples.itely +++ b/Documentation/user/examples.itely @@ -27,7 +27,7 @@ instrument or a melodic fragment. Cut and paste this into a file, 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 @@ -39,7 +39,7 @@ melody = \relative c' { \score { \new Staff \melody \layout { } - \midi {} + \midi { \tempo 4=60 } } @end lilypond @@ -52,7 +52,7 @@ automatic beaming, you'll have to change or comment out the relevant line. @lilypond[quote,verbatim,ragged-right] -\version "2.9.13" +\version "2.7.39" melody = \relative c' { \clef treble \key c \major @@ -74,7 +74,7 @@ text = \lyricmode { \new Lyrics \lyricsto "one" \text >> \layout { } - \midi { } + \midi { \tempo 4=60 } } @end lilypond @@ -83,7 +83,7 @@ text = \lyricmode { 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 @@ -107,7 +107,7 @@ harmonies = \chordmode { >> \layout{ } - \midi { } + \midi { \tempo 4=60} } @end lilypond @@ -116,7 +116,7 @@ harmonies = \chordmode { 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 @@ -146,7 +146,7 @@ harmonies = \chordmode { \new Lyrics \lyricsto "one" \text >> \layout { } - \midi { } + \midi { \tempo 4=60 } } @end lilypond @@ -157,7 +157,7 @@ harmonies = \chordmode { 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 @@ -176,12 +176,12 @@ lower = \relative c { \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 @@ -191,7 +191,7 @@ Here is a typical song format: one staff with the melody and lyrics, with piano accompaniment underneath. @lilypond[quote,verbatim,ragged-right] -\version "2.9.13" +\version "2.7.39" melody = \relative c'' { \clef treble \key c \major @@ -236,7 +236,7 @@ lower = \relative c { \layout { \context { \RemoveEmptyStaffContext } } - \midi { } + \midi { \tempo 4=60 } } @end lilypond @@ -247,7 +247,7 @@ Instead of having a full staff for the melody and lyrics, you can place 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 @@ -281,7 +281,7 @@ text = \lyricmode { \context { \GrandStaff \accepts "Lyrics" } \context { \Lyrics \consists "Bar_engraver" } } - \midi { } + \midi { \tempo 4=60 } } @end lilypond @@ -294,7 +294,7 @@ since the template is right here, you don't have to do the tweaking yourself. @lilypond[quote,verbatim,ragged-right] -\version "2.9.13" +\version "2.7.39" upper = \relative c'' { \clef treble \key c \major @@ -391,7 +391,7 @@ This template demonstrates a string quartet. It also uses a @code{\global} section for time and key signatures. @lilypond[quote,verbatim,ragged-right] -\version "2.9.13" +\version "2.7.39" global= { \time 4/4 @@ -399,26 +399,26 @@ global= { } 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 @@ -433,7 +433,7 @@ cello = \new Voice { \relative c' { \new Staff << \global \cello >> >> \layout { } - \midi { } + \midi { \tempo 4=60} } @end lilypond @@ -451,7 +451,7 @@ contains all the music definitions. The other files -- @code{score.ly}, @verbatim %%%%% piece.ly -\version "2.9.13" +\version "2.7.39" global= { \time 4/4 @@ -459,26 +459,26 @@ global= { } 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 @@ -497,18 +497,18 @@ music = { %%%%% 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 @@ -517,7 +517,7 @@ music = { %%%%% vn2.ly -\version "2.9.13" +\version "2.7.39" \include "piece.ly" \score { \keepWithTag #'vn2 \music @@ -526,7 +526,7 @@ music = { %%%%% vla.ly -\version "2.9.13" +\version "2.7.39" \include "piece.ly" \score { \keepWithTag #'vla \music @@ -535,7 +535,7 @@ music = { %%%%% vlc.ly -\version "2.9.13" +\version "2.7.39" \include "piece.ly" \score { \keepWithTag #'vlc \music @@ -555,7 +555,7 @@ parts. For example, the time signature and key signatures are almost 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 @@ -636,7 +636,7 @@ to the vocal notes (say, tenorMusic), then the changes will also 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 @@ -739,7 +739,7 @@ notes. As a compromise, bar lines are often printed between the 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 @@ -789,7 +789,7 @@ global = { discantusNotes = { \transpose c' c'' { - \set Staff.instrumentName = "Discantus " + \set Staff.instrument = "Discantus " % incipit \clef "neomensural-c1" @@ -825,7 +825,7 @@ discantusLyrics = \lyricmode { altusNotes = { \transpose c' c'' { - \set Staff.instrumentName = "Altus " + \set Staff.instrument = "Altus " % incipit \clef "neomensural-c3" @@ -859,7 +859,7 @@ altusLyrics = \lyricmode { tenorNotes = { \transpose c' c' { - \set Staff.instrumentName = "Tenor " + \set Staff.instrument = "Tenor " % incipit \clef "neomensural-c4" @@ -893,7 +893,7 @@ tenorLyrics = \lyricmode { bassusNotes = { \transpose c' c' { - \set Staff.instrumentName = "Bassus " + \set Staff.instrument = "Bassus " % incipit \clef "bass" @@ -965,7 +965,7 @@ quarter noteheads, and special marks, indicating rests of different length. @lilypond[quote,verbatim,ragged-right] \include "gregorian-init.ly" -\version "2.9.13" +\version "2.8.0" chant = \relative c' { \set Score.timing = ##f @@ -1025,7 +1025,7 @@ is within a @code{\transpose} section. @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)" @@ -1083,7 +1083,7 @@ trpharmony = \transpose c' d { } trumpet = { \global - \set Staff.instrumentName = #"Trumpet" + \set Staff.instrument = #"Trumpet" \clef treble << \trpt @@ -1100,7 +1100,7 @@ altoharmony = \transpose c' a { } altosax = { \global - \set Staff.instrumentName = #"Alto Sax" + \set Staff.instrument = #"Alto Sax" \clef treble << \alto @@ -1117,7 +1117,7 @@ bariharmony = \transpose c' a \chordmode { } barisax = { \global - \set Staff.instrumentName = #"Bari Sax" + \set Staff.instrument = #"Bari Sax" \clef treble << \bari @@ -1134,7 +1134,7 @@ tboneharmony = \chordmode { } trombone = { \global - \set Staff.instrumentName = #"Trombone" + \set Staff.instrument = #"Trombone" \clef bass << \tbone @@ -1154,7 +1154,7 @@ gtrharmony = \chordmode { } guitar = { \global - \set Staff.instrumentName = #"Guitar" + \set Staff.instrument = #"Guitar" \clef treble << \gtr @@ -1205,7 +1205,7 @@ PianoLH = { piano = { << - \set PianoStaff.instrumentName = #"Piano" + \set PianoStaff.instrument = #"Piano" \new Staff = "upper" \PianoRH \new Staff = "lower" \PianoLH >> @@ -1218,7 +1218,7 @@ Bass = \relative c { } bass = { \global - \set Staff.instrumentName = #"Bass" + \set Staff.instrument = #"Bass" \clef bass << \Bass @@ -1240,7 +1240,7 @@ down = \drummode { drumContents = { \global << - \set DrumStaff.instrumentName = #"Drums" + \set DrumStaff.instrument = #"Drums" \new DrumVoice { \voiceOne \up } \new DrumVoice { \voiceTwo \down } >> @@ -1277,7 +1277,7 @@ drumContents = { } } - \midi { } + \midi { \tempo 4 = 75 } } @end lilypond @@ -1301,7 +1301,7 @@ violin concerto as TchaikovskyPI, whereas perhaps you wish to print @ 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" diff --git a/Documentation/user/global.itely b/Documentation/user/global.itely index 4449a54187..a37e83877a 100644 --- a/Documentation/user/global.itely +++ b/Documentation/user/global.itely @@ -5,18 +5,22 @@ @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 @@ -28,9 +32,7 @@ these files end with ``@code{.ly}''. @menu * File structure (introduction):: -* Multiple scores in a book:: * File structure:: -* A single music expression:: * Including LilyPond files:: * Text encoding:: @end menu @@ -42,7 +44,7 @@ these files end with ``@code{.ly}''. 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. @@ -71,81 +73,6 @@ expressions are called toplevel expressions. The next section enumerates 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 @@ -272,54 +199,10 @@ be entered: @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 @@ -413,6 +296,50 @@ To use a Unicode escape sequence, use +@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 @@ -433,65 +360,49 @@ Titles are created for each @code{\score} block, and over a 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. @@ -579,7 +490,7 @@ Note that the music expression must come before the @code{\header}. } @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 @@ -590,25 +501,6 @@ You may change this behavior (and print all the headers when defining @} @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 @@ -618,22 +510,22 @@ variables in the @code{\paper} block. The init file @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. @@ -641,11 +533,11 @@ field). 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. @@ -684,111 +576,1189 @@ header as well. It may be used as a normal header, or left blank -@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 @@ -812,8 +1782,21 @@ will. 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 @@ -827,7 +1810,7 @@ The contexts for MIDI output are defined in @file{ly/@/performer@/-init@/.ly}. @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 @@ -850,7 +1833,7 @@ instrument is used. @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, @@ -876,12 +1859,21 @@ lilypond file.ly >display.txt @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 @@ -921,4 +1913,24 @@ In polyphonic music, @code{Score.skipTypesetting} will affect all 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 + diff --git a/Documentation/user/instrument-notation.itely b/Documentation/user/instrument-notation.itely index 900b5f551a..30f112dcc4 100644 --- a/Documentation/user/instrument-notation.itely +++ b/Documentation/user/instrument-notation.itely @@ -229,7 +229,7 @@ In this manual: @ref{Laissez vibrer ties} @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 @@ -253,9 +253,9 @@ Program reference: @internalsref{VoiceFollower}. @refcommands -@funindex \showStaffSwitch +@findex \showStaffSwitch @code{\showStaffSwitch}, -@funindex \hideStaffSwitch +@findex \hideStaffSwitch @code{\hideStaffSwitch}. @@ -413,11 +413,11 @@ Modifiers can be mixed with additions @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 @@ -426,7 +426,7 @@ explicitly) \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 @@ -434,7 +434,7 @@ 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}. @@ -512,8 +512,8 @@ for showing repeats. \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 } @@ -526,7 +526,7 @@ Klaus Ignatzek (see @ref{Literature list}). It can be tuned through the following properties @table @code -@funindex chordNameExceptions +@findex chordNameExceptions @item chordNameExceptions This is a list that contains the chords that have special formatting. @@ -555,14 +555,14 @@ For an example of tuning this property, see also @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 @@ -576,21 +576,21 @@ separators, e.g., } @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 @@ -619,13 +619,13 @@ chart}. Turning on these styles is described in the input file @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}. @@ -746,7 +746,7 @@ cases you should use @code{\lyricsto} and @code{\lyricmode}. @subsection Entering lyrics @cindex lyrics -@funindex \lyricmode +@findex \lyricmode @cindex punctuation Lyrics are entered in a special input mode. This mode is introduced @@ -777,7 +777,7 @@ opening brace is not balanced \lyricmode @{ twinkle@} @end example -@funindex \property in \lyricmode +@findex \property in \lyricmode @noindent Similarly, a period which follows an alphabetic sequence is included in @@ -787,7 +787,7 @@ property commands \override Score . LyricText #'font-shape = #'italic @end example -@funindex _ +@findex _ @cindex spaces, in lyrics @cindex quotes, in lyrics @@ -884,7 +884,7 @@ Program reference: @internalsref{LyricHyphen}, @internalsref{LyricExtender}. @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 @@ -892,7 +892,7 @@ Lyrics are printed by interpreting them in the context called @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 @@ -1021,8 +1021,8 @@ A complete example of a SATB score setup is in section @refcommands @code{\melisma}, @code{\melismaEnd} -@funindex \melismaEnd -@funindex \melisma +@findex \melismaEnd +@findex \melisma @seealso @@ -1444,7 +1444,7 @@ its fleece was white as snow. 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] @@ -1951,7 +1951,7 @@ are printed as tablature, by using @internalsref{TabStaff} and } @end lilypond -@funindex minimumFret +@findex minimumFret @cindex fret When no string is specified, the first string that does not give a @@ -2358,7 +2358,8 @@ Here are all suptopics at a glance: @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} @@ -2908,6 +2909,8 @@ Editio Vaticana 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 @@ -3033,17 +3036,17 @@ Therefore, @file{gregorian@/-init@/.ly} also defines @code{\virgula} and @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 @@ -4103,35 +4106,35 @@ ligatures can be created. 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. @@ -4156,13 +4159,17 @@ the following excerpt demonstrates \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 @@ -4218,7 +4225,7 @@ usually printed over the note. 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 @@ -4371,30 +4378,6 @@ Internally, the code produces markup texts. You can use any of the 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}, diff --git a/Documentation/user/introduction.itely b/Documentation/user/introduction.itely index 6eeaca9a76..5716982774 100644 --- a/Documentation/user/introduction.itely +++ b/Documentation/user/introduction.itely @@ -724,14 +724,9 @@ details about complicated or unusual notation. 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 diff --git a/Documentation/user/invoking.itely b/Documentation/user/invoking.itely index dc87e00d1d..c36f494a97 100644 --- a/Documentation/user/invoking.itely +++ b/Documentation/user/invoking.itely @@ -6,18 +6,6 @@ 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:: @@ -211,6 +199,10 @@ When LilyPond formatting is available through a web server, either the @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 /") @@ -342,19 +334,14 @@ uses more CPU time. The default value is @code{70}. @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 @@ -372,7 +359,7 @@ Note that @var{path/to} will generally be @code{/Applications/}. @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 @@ -446,9 +433,7 @@ Print usage help. @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 @@ -460,10 +445,6 @@ Aug 18, 2005 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 @@ -502,7 +483,7 @@ stanzas. 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" > @@ -518,9 +499,7 @@ converted. 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 @@ -570,7 +549,7 @@ following example, the accidental touches the note head. 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 diff --git a/Documentation/user/lilypond-book.itely b/Documentation/user/lilypond-book.itely index 89a7af3af0..d4e93f9081 100644 --- a/Documentation/user/lilypond-book.itely +++ b/Documentation/user/lilypond-book.itely @@ -38,7 +38,6 @@ This procedure may be applied to La@TeX{}, HTML or Texinfo documents. * Music fragment options:: * Invoking lilypond-book:: * Filename extensions:: -* Inserting LilyPond output into other programs:: @end menu @@ -152,7 +151,7 @@ Larger examples can be put into a separate file, and introduced with @cindex texinfo @cindex latex @cindex texinfo -@funindex texi +@findex texi @cindex html @cindex documents, adding music to @@ -234,7 +233,7 @@ heuristic algorithm can fail easily; in such cases it is necessary 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: @@ -304,66 +303,6 @@ be ignored. @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 @@ -627,10 +566,12 @@ output format. Both @file{.tex} and @file{.texi} files need further 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 @@ -643,14 +584,6 @@ The @file{.dvi} file created by this process will not contain 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 @@ -763,37 +696,3 @@ output format based on the input filename's extension. @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 - diff --git a/Documentation/user/lilypond.tely b/Documentation/user/lilypond.tely index 32a875500d..6bd484d72d 100644 --- a/Documentation/user/lilypond.tely +++ b/Documentation/user/lilypond.tely @@ -22,11 +22,7 @@ Distributions will want to install lilypond.info in postinstall, doing: @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. @@ -37,6 +33,7 @@ Distributions will want to install lilypond.info in postinstall, doing: * 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 @@ -54,7 +51,7 @@ This document is also available as a @c This produces the unified index -@syncodeindex fn cp +@syncodeindex ky cp @syncodeindex vr cp @documentlanguage en @@ -72,14 +69,12 @@ This document is also available as a 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 @@ -100,34 +95,22 @@ Free Documentation License''. @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 @@ -163,8 +146,7 @@ Notation Reference * 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 @@ -202,7 +184,6 @@ Appendices @include advanced-notation.itely @include changing-defaults.itely @include global.itely -@include page.itely @include programming-interface.itely @include invoking.itely @@ -220,7 +201,7 @@ Appendices @node LilyPond command index @appendix LilyPond command index -@printindex ky +@printindex fn @node LilyPond index @appendix LilyPond index diff --git a/Documentation/user/macros.itexi b/Documentation/user/macros.itexi index 68b52bb513..d19182bc26 100644 --- a/Documentation/user/macros.itexi +++ b/Documentation/user/macros.itexi @@ -196,9 +196,9 @@ user manual, @internalsref{\NAME\} @end macro -@macro funindex {WORD} -@findex \WORD\ -@kindex \WORD\ -@end macro +@c @macro funindex {WORD} +@c @end macro +@c @findex \WORD\ +@c @kindex \WORD\ diff --git a/Documentation/user/music-glossary.tely b/Documentation/user/music-glossary.tely index 55e07d2b2a..5a809089dd 100644 --- a/Documentation/user/music-glossary.tely +++ b/Documentation/user/music-glossary.tely @@ -5,8 +5,7 @@ @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 @@ -25,7 +24,7 @@ and as @uref{source/Documentation/user/music-glossary.html,one big page}. @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 @@ -59,11 +58,9 @@ Copyright @copyright{} 1999--2006 by the authors @top Music glossary @end ifnottex - -@ifnottex - This glossary was brought you by +@ifnottex @table @code @item Adrian Mariano Italian glossary, @@ -71,7 +68,7 @@ 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, @@ -438,7 +435,7 @@ The stress of one tone over others. @node accidental @section accidental -ES: alteración accidental, +ES: alteración accidentelle, I: accidento, F: altération accidentelle, D: Vorzeichen, Versetzungszeichen, Akzidenz, @@ -563,7 +560,7 @@ C clef setting middle C on the middle line of the staff @node ambit @section ambit -ES: ámbito, +ES: ámbito, I: ambitus, F: ambitus, D: ambitus, @@ -579,7 +576,7 @@ the pitch range that a musical instrument is capable of playing. @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, @@ -767,12 +764,12 @@ FI: H, h. @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ínea divisoria, I: stanghetta, barra (di divisione), F: barre (de mesure), D: Taktstrich, @@ -873,7 +870,7 @@ The number of beams determines the note value of the connected notes. @node beat @section beat -ES: tiempo, parte (de compás) +ES: tiempo, parte (de compás) I: tempi, F: temps, D: Takt, Taktschlag, Zeit (im Takt), @@ -947,7 +944,7 @@ trumpet, trombone, french horn, and tube. @node breath mark @section breath mark -ES: respiración, +ES: respiración, I: respiro, F: respiration, D: Atemzeichen, Trennungszeichen, @@ -1200,8 +1197,6 @@ FI: avain, nuottiavain. @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 @@ -1231,7 +1226,7 @@ pitch contained in the cluster would be notated as an ordinary note. @node comma @section comma -ES: coma, comma, +ES: coma, comma I: comma, F: comma, D: Komma, @@ -1267,7 +1262,7 @@ Intervals larger than an octave. @node complement @section complement -ES: intervalo invertido, +ES: intervalo invertido I: rivolto, F: intervalle complémentaire, D: Komplementärintervall, @@ -1429,7 +1424,7 @@ abbreviation ``cresc.''. @node cue-notes @section cue-notes -ES: notas guía, +ES: notas guía, I: notine, F: petites notes précédent l'entrée d'in instrument, réplique, D: Stichnoten, @@ -1738,7 +1733,7 @@ harmonic minor scale type an augmented second (A) occurs between the 6th and @node diminished interval @section diminished interval -ES: intervalo disminuido, +ES: intervalo disminuído, I: intervallo diminuito, F: intervalle diminué, D: vermindertes Intervall, @@ -1766,7 +1761,7 @@ FI: diminuendo, hiljentyen. @node disjunct movement @section disjunct movement -ES: movimiento disjunto, +ES: movimiendo disjunto, I: moto disgiunto, F: mouvement disjoint, D: sprunghafte Bewegung, @@ -2097,7 +2092,7 @@ plate of metal. Now also the term for the art of music typesetting. @node enharmonic @section enharmonic -ES: enarmónico, +ES: enharmónico, I: enarmonico, F: enharmonique, D: enharmonisch, @@ -2140,7 +2135,7 @@ Tuning system dividing the octave into 12 equal @aref{semitone}s @node expression mark @section expression mark -ES: expresión, +ES: expresión, I: segno d'espressione, F: signe d'expression, indication de nuance, D: Vortragszeichen, @@ -2215,7 +2210,7 @@ symbol indicates playing an octave lower (for example on double bass @node fermata @section fermata -ES: calderón, +ES: Calderón, I: corona, F: point d'orgue, point d'arr@^et, D: Fermate, @@ -2250,7 +2245,7 @@ FI: kvintti. @node figured bass @section figured bass -@aref{thorough bass}. +ES: bajo cifrado, @aref{thorough bass}. @node fingering @section fingering @@ -2457,7 +2452,7 @@ Letting the pitch slide fluently from one note to the other. @node grace notes @section grace notes -ES: notas de adorno, +ES: mordente, I: abbellimenti, F: fioriture, D: Verzierungen, Vorschläge, Vor@-schlags@-noten, @@ -2565,7 +2560,7 @@ section. @aref{functional harmony}. \bar "|." } \lyrics { - T4 S D T + T S D T } >> >> @@ -2599,7 +2594,7 @@ Consonances: _"fifth " s _"sixth " s _"octave " s - _"tenth" s s + _"decime" s s } @end lilypond @@ -2706,7 +2701,7 @@ of such two intervals forms an octave. } \context Lyrics \lyrics { "seventh " "seventh " "seventh " "octave " - "ninth " "ninth " "tenth " "tenth" + "none " "none " "decime " "decime" } >> @end lilypond @@ -2738,7 +2733,7 @@ The difference between an interval and an octave. @node just intonation @section just intonation -ES: entonación justa, +ES: entonación justa, I: intonazione giusta, F: intonation juste, D: reine Stimmung, @@ -2815,7 +2810,7 @@ upwards) to the tonic scale degree. @node ledger line @section ledger line -ES: línea adicional, +ES: líneas adicionales, I: tagli addizionali, F: ligne supplémentaire, D: Hilfslinie, @@ -2857,7 +2852,7 @@ unlike (b) @emph{leggiero} or @emph{non-legato}, (c) @emph{portato}, and c4-. d-. e-. \bar "||" } \lyrics { - a2. + a1 b c d @@ -2878,7 +2873,7 @@ unlike (b) @emph{leggiero} or @emph{non-legato}, (c) @emph{portato}, and @node lilypond @section lilypond -ES: estanque de nenúfares, +ES: estanque de nenúfares, I: stagno del giglio, F: étang de lis, UK: lily pond, @@ -2958,7 +2953,7 @@ Note value: double length of @aref{breve}. @node lyrics @section lyrics -ES: letra (de la canción), +ES: letra (de la canción), I: ., F: ., D: Liedtext, @@ -2998,7 +2993,7 @@ FI: duuri. @node meantone temperament @section meantone temperament -ES: afinación mesotónica, +ES: afinación mesotónica, I: accordatura mesotonica, F: tempérament mésotonique, D: mitteltönige Stimmung, @@ -3139,7 +3134,7 @@ M.M.@: (Mälzels Metronom). @node mezzo-soprano @section mezzo-soprano -ES: mezzosoprano, +ES: mezzo soprano, I: mezzo-soprano, F: mezzo-soprano, D: Mezzosopran, @@ -3192,7 +3187,7 @@ FI: molli. @node minor interval @section minor interval -ES: intervalo menor, +ES: intervalo mayor, I: intervallo minore, F: intervalle mineur, D: kleines Intervall, @@ -3255,7 +3250,7 @@ FI: mordent, korukuvio. @node motive @section motive -ES: motivo, +ES: tema, I: inciso, F: incise, D: Motiv, @@ -3267,22 +3262,16 @@ FI: teema, sävelaihe. 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 @@ -3404,7 +3393,7 @@ instrument. @node note value @section note value -ES: valor (duración), +ES: valor (duración), I: valore, durata, F: durée, valeur (d'une note), D: Notenwert, @@ -3728,7 +3717,7 @@ denotes the highest possible degree of speed. @node Pythagorean comma @section Pythagorean comma -ES: coma pitagórica, +ES: coma pitagórico, I: comma pitagorico, F: comma pythagoricien, D: Pythagoräisches Komma, @@ -3818,7 +3807,7 @@ Abbreviation "rall.". @aref{ritardando}. @node relative key @section relative key -ES: relativo, +ES: relativa, I: tonalità relativa, F: tonalité relative, D: Paralleltonart, @@ -3852,7 +3841,7 @@ with the same @aref{key signature}. @node repeat @section repeat -ES: repetición, +ES: barra de repetición, I: ritornello, F: barre de reprise, D: Wiederholung, @@ -3952,7 +3941,7 @@ FI: asteikko, sävelasteikko. @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, @@ -4170,7 +4159,7 @@ FI: kuudeskymmenesneljäsosatauko. @node slur @section slur -ES: ligadura (de expresión), +ES: ligadura (de expresión), I: legatura (di portamento or espressiva), F: liaison, coulé, D: Bogen, Legatobogen, Phrasierungsbogen, @@ -4186,7 +4175,7 @@ breath in singing. @node solmization @section solmization -ES: solmisación, +ES: solmisación, I: solmisazione, F: solmisation, D: Solmisation, @@ -4263,7 +4252,7 @@ The highest female voice. @node staccato @section staccato -ES: picado, +ES: picado (staccato), I: staccato, F: staccato, piqué, détaché, D: Staccato, @@ -4395,7 +4384,7 @@ The sixth @aref{scale degree}. @node subtonic @section subtonic -ES: subtónica, +ES: sensible, I: sottotonica, F: sous-tonique, D: Subtonika, @@ -4451,7 +4440,7 @@ A symphony may be defined as a @aref{sonata} for orchestra. @node syncopation @section syncopation -ES: síncopa, +ES: síncopa, I: sincope, F: syncope, D: Synkope, @@ -4479,7 +4468,7 @@ the underlaying (normal) pulse and the actual (abnormal) rhythm. @node syntonic comma @section syntonic comma -ES: coma sintónica, +ES: coma sintónica, I: comma sintonico (o didimico), F: comma syntonique, D: syntonisches Komma, @@ -4570,7 +4559,7 @@ FI: desimi. @node tenuto @section tenuto -ES: subrayado (tenuto), +ES: tenuto, I: tenuto, F: tenue, tenuto, D: gehalten, tenuo, @@ -4696,7 +4685,7 @@ uniting them into a single sound (tone) equal to the combined durations. @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, @@ -4726,7 +4715,7 @@ Music from the 20th century may be based on atonal sounds. @node tonic @section tonic -ES: tónica, +ES: tónica, I: tonica, F: tonique, D: Tonika, @@ -4741,7 +4730,7 @@ The first @aref{scale degree}. @node transposition @section transposition -ES: transporte, +ES: transposición, I: trasposizione, F: transposition, D: Transposition, @@ -4790,7 +4779,7 @@ FI: diskanttiavain. @node tremolo @section tremolo -ES: trémolo, +ES: trémolo, I: tremolo, F: trémolo, D: Tremolo, @@ -4846,7 +4835,7 @@ FI: trilli. @node triple meter @section triple meter -ES: compás ternario, +ES: compás compuesto, I: tempo ternario, F: mesure ternaire, D: in drei, @@ -4874,7 +4863,7 @@ FI: trioli. @node tritone @section tritone -ES: tritono, +ES: trítono, I: tritono, F: triton, D: Tritonus, @@ -4934,7 +4923,7 @@ different octave. @node upbeat @section upbeat -ES: anacrusa, +ES: entrada anacrúsica, I: anacrusi, F: anacrouse, levée, D: Auftakt, @@ -5017,7 +5006,7 @@ FI: kokotauko. @node whole tone @section whole tone -ES: tono (entero), +ES: tono, I: tono intero, F: ton entier, D: Ganzton, @@ -5225,13 +5214,13 @@ symphony orchestra are flute, oboe, clarinet, saxophone, and bassoon. @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 diff --git a/Documentation/user/page.itely b/Documentation/user/page.itely deleted file mode 100644 index ceaee2adef..0000000000 --- a/Documentation/user/page.itely +++ /dev/null @@ -1,1159 +0,0 @@ -@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 .ly -lilypond .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. - - diff --git a/Documentation/user/programming-interface.itely b/Documentation/user/programming-interface.itely index 38dbbc0ae5..e282f754f1 100644 --- a/Documentation/user/programming-interface.itely +++ b/Documentation/user/programming-interface.itely @@ -12,7 +12,6 @@ not familiar with Scheme, you may wish to read our * Building complicated functions:: * Markup programmer interface:: * Contexts for programmers:: -* Scheme procedures as properties:: @end menu @@ -24,7 +23,7 @@ This section discusses how to create music functions within LilyPond. @menu * Overview of music functions:: * Simple substitution functions:: -* Paired substitution functions:: +* Paired substition functions:: * Mathematics in functions:: * Void functions:: @end menu @@ -32,7 +31,7 @@ This section discusses how to create music functions within LilyPond. @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 @@ -134,8 +133,8 @@ g c @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 @@ -211,6 +210,7 @@ withAlt = #(define-music-function (parser location mag music) (number? ly:music? \withAlt #1.5 {c' c'} c'2 } @end lilypond + @node Void functions @subsection Void functions @@ -315,7 +315,7 @@ written as @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 @@ -356,7 +356,7 @@ available is in the Program reference manual, under 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 @@ -400,8 +400,8 @@ to create complicated music functions. @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 @@ -487,7 +487,7 @@ someNote = c' @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 @@ -501,7 +501,7 @@ expression. (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 @@ -593,7 +593,7 @@ have two notes to build the sequence), add @code{SlurEvents} to the @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))) @@ -717,7 +717,7 @@ function). Recall that our purpose is to add a marcato to an 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 @@ -826,7 +826,7 @@ LilyPond markup syntax and Scheme markup syntax. @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 @@ -892,7 +892,7 @@ of this section, and in @file{scm/@/define@/-markup@/-commands@/.scm}. @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} ...) @@ -1066,7 +1066,7 @@ be used to set text in small caps. See @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 @@ -1092,7 +1092,7 @@ current bar number on the standard output during the compile: @cindex calling code on layout objects -@funindex \applyOutput +@findex \applyOutput The most versatile way of tuning an object is @code{\applyOutput}. Its @@ -1131,39 +1131,3 @@ note-heads on the center-line: (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 - - diff --git a/Documentation/user/putting.itely b/Documentation/user/putting.itely index 0cc5ecd908..8b79c45c1e 100644 --- a/Documentation/user/putting.itely +++ b/Documentation/user/putting.itely @@ -26,7 +26,7 @@ cello. In this case, we would start with ``Notes and lyrics'' (for the soprano part). @example -\version "2.9.13" +\version "2.7.39" melody = \relative c' @{ \clef treble \key c \major @@ -48,14 +48,14 @@ text = \lyricmode @{ \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 @@ -67,7 +67,7 @@ melody = \relative c' @{ \score @{ \new Staff \melody \layout @{ @} -\midi @{ @} +\midi @{ \tempo 4=60 @} @} @end example @@ -91,7 +91,7 @@ normally use bass clef. We'll also give the cello some different notes. @example -\version "2.9.13" +\version "2.7.39" sopranoMusic = \relative c' @{ \clef treble \key c \major @@ -121,7 +121,7 @@ celloMusic = \relative c @{ \new Lyrics \lyricsto "one" \sopranoLyrics >> \layout @{ @} - \midi @{ @} + \midi @{ \tempo 4=60 @} @} @end example @@ -152,7 +152,7 @@ more than one thing (in this case, @code{Staff}) happening at once. The \new Staff \celloMusic >> \layout @{ @} - \midi @{ @} + \midi @{ \tempo 4=60 @} @} @end example @@ -161,7 +161,7 @@ This looks a bit messy; the indentation is messed up now. That is 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 @@ -194,7 +194,7 @@ celloMusic = \relative c { \new Staff \celloMusic >> \layout { } - \midi { } + \midi { \tempo 4=60 } } @end lilypond @@ -272,6 +272,7 @@ The @code{\score} can contain other things, such as \score @{ @{ c'4 a b c' @} \layout @{ @} + \paper @{ @} \midi @{ @} \header @{ @} @} diff --git a/Documentation/user/scheme-tutorial.itely b/Documentation/user/scheme-tutorial.itely index f44860df56..032fce0cf8 100644 --- a/Documentation/user/scheme-tutorial.itely +++ b/Documentation/user/scheme-tutorial.itely @@ -3,7 +3,7 @@ @node Scheme tutorial @appendix Scheme tutorial -@funindex # +@findex # @cindex Scheme @cindex GUILE @cindex Scheme, in-line code @@ -25,8 +25,8 @@ LilyPond input. @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, @@ -124,7 +124,7 @@ number or a string. It is entered as #'twentyFour @end example -@funindex #'symbol +@findex #'symbol @cindex quoting in Scheme The quote mark @code{'} prevents the Scheme interpreter from substituting @@ -199,6 +199,3 @@ respectively, #'(staff clef key-signature) #'((1) (2)) @end example - - - diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 796705ec51..3a7c593cfe 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -37,8 +37,8 @@ you will probably want to print out or bookmark @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:: @@ -298,8 +298,8 @@ available package for viewing and printing PDF and PostScript files.} @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, @@ -489,7 +489,7 @@ This makes the input less readable, and it is a source of errors. The 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. @@ -928,7 +928,7 @@ statement marks for which version of LilyPond the file was written. To mark a file for version 2.6.0, use @example -\version "2.9.13" +\version "2.6.0" @end example @noindent @@ -999,17 +999,16 @@ Similarly, hyphens between words can be entered as two dashes, 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 diff --git a/Documentation/user/tweaks.itely b/Documentation/user/tweaks.itely index ea839d1113..8224f4eef2 100644 --- a/Documentation/user/tweaks.itely +++ b/Documentation/user/tweaks.itely @@ -11,7 +11,6 @@ configurable; virtually every fragment of output may be changed. * Fixing overlapping notation:: * Common tweaks:: * Default files:: -* Fitting music onto fewer pages:: * Advanced tweaks with Scheme:: @end menu @@ -61,7 +60,7 @@ c4^"piu mosso" d e f \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 @@ -153,7 +152,7 @@ Vertical positioning of these symbols is handled by @end quotation @noindent -So to move dynamics around vertically, we use +So to move dynamics around, we use @example \override DynamicLineSpanner #'padding = #2.0 @@ -164,8 +163,7 @@ common objects. @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} @@ -305,7 +303,7 @@ outside the scope of this manual; users should be warned that 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/} @@ -324,93 +322,6 @@ particular interest. Files such as @file{ly/property-init.ly} and @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 diff --git a/Documentation/user/working.itely b/Documentation/user/working.itely index 2872272a9f..bbdb2c3386 100644 --- a/Documentation/user/working.itely +++ b/Documentation/user/working.itely @@ -10,10 +10,11 @@ this chapter. @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 @@ -24,44 +25,19 @@ Now you're ready to begin writing larger LilyPond files -- not just the 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 @@ -95,20 +71,11 @@ you didn't comment the file. 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), @@ -132,50 +99,84 @@ best. @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 @@ -525,7 +526,7 @@ file with @code{\include "../global.ly"}, which contains @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" @@ -534,83 +535,3 @@ file with @code{\include "../global.ly"}, which contains @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. - - diff --git a/GNUmakefile.in b/GNUmakefile.in index 8cb53003b6..3a7d3a80e8 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -16,15 +16,14 @@ SUBDIRS = buildscripts python scripts \ ## 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 @@ -33,13 +32,6 @@ 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 @@ -80,19 +72,15 @@ local-WWW-post: echo 'Redirecting to the documentation index...' >> $(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 \ @@ -108,10 +96,8 @@ tree-prefix = $(outdir) 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: @@ -136,9 +122,7 @@ $(tree-share-prefix)/lilypond-force link-tree: GNUmakefile 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 @@ -193,16 +177,11 @@ $(tree-share-prefix)/mf-link-tree link-mf-tree: $(tree-share-prefix)/lilypond-fo -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 diff --git a/HACKING b/HACKING index 081bb2a24c..65ee857573 100644 --- a/HACKING +++ b/HACKING @@ -4,9 +4,47 @@ If you want to contribute and can build LilyPond yourself, there's no 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 "$@" diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000000..2a431f3a5c --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,415 @@ + + +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 +. 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 and +. Please consult the faq before mailing +your problems. + + If you find bugs, please send bug reports to . + + 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 + + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000000..c22267cdb8 --- /dev/null +++ b/README.txt @@ -0,0 +1,99 @@ + + +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 . For help and questions +use and . 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. + diff --git a/SConstruct b/SConstruct index 3700c74e23..3f6f15007b 100644 --- a/SConstruct +++ b/SConstruct @@ -158,7 +158,7 @@ opts.AddOptions ( 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', @@ -269,92 +269,8 @@ def list_sort (lst): 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 () @@ -362,10 +278,7 @@ def configure (target, source, env): 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, '.') @@ -441,15 +354,15 @@ def configure (target, source, env): 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', @@ -471,8 +384,45 @@ def configure (target, source, env): 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 + 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, @@ -491,8 +441,8 @@ def configure (target, source, env): 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)) @@ -504,9 +454,8 @@ def configure (target, source, env): 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)) @@ -515,9 +464,21 @@ def configure (target, source, env): 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'): @@ -538,6 +499,7 @@ def configure (target, source, env): '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'): @@ -547,7 +509,12 @@ def configure (target, source, env): 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 rather than CPPPATH = [ # ] speeds up SCons @@ -665,14 +632,12 @@ env.PrependENVPath ('PATH', 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] + '}', }) @@ -719,6 +684,7 @@ if env['debugging']: 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']) @@ -763,27 +729,15 @@ if 'realclean' in COMMAND_LINE_TARGETS: 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', @@ -806,7 +760,8 @@ env.Append ( 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', @@ -824,6 +779,95 @@ env.Append ( '$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 @@ -876,10 +920,11 @@ if env['fast']\ 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 ()): diff --git a/THANKS b/THANKS index f7b33a3ba1..a2b576dc8b 100644 --- a/THANKS +++ b/THANKS @@ -1,40 +1,31 @@ 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 @@ -50,50 +41,26 @@ Juergen Reuter 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 @@ -191,7 +158,7 @@ Patrick K Welton Paul Scott Ralph Little Richard Schoeller -Robert Vlasaty +Robert Vlatasy Roman Kurakin Russell Lang Scott Russell @@ -425,7 +392,7 @@ Pawel D Pedro Kroger Ray McKinney Reuben Thomas -Robert Vlasaty +Robert Vlatasy Stef Epardaud Thomas Willhalm Thomas Scharkowski diff --git a/VERSION b/VERSION index 0d42f4b514..404fb35970 100644 --- a/VERSION +++ b/VERSION @@ -1,6 +1,6 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=9 -PATCH_LEVEL=22 +PATCH_LEVEL=7 MY_PATCH_LEVEL= diff --git a/buildscripts/builder.py b/buildscripts/builder.py index cf3493fa72..3caea45830 100644 --- a/buildscripts/builder.py +++ b/buildscripts/builder.py @@ -65,22 +65,29 @@ env.Append (BUILDERS = {'HH' : HH}) # 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,)} $)', ) @@ -113,7 +120,7 @@ env.Append (BUILDERS = {'TEXI': TEXI}) 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}) @@ -137,10 +144,18 @@ PNG2EPS =\ 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] @@ -198,18 +213,13 @@ env.Append (BUILDERS = {'GTABLE': gtable}) 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}' @@ -227,7 +237,6 @@ otf = Builder (action = a, suffix = '.otf', src_suffix = '.pe', # emitter = add_cff_cffps_svg - emitter = add_svg ) env.Append (BUILDERS = {'OTF': otf}) @@ -265,6 +274,7 @@ atvars = [ 'step-bindir', ] +# naming def at_copy (target, source, env): n = str (source[0]) s = open (n).read () @@ -280,6 +290,7 @@ def at_copy (target, source, env): 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 () @@ -299,6 +310,7 @@ MO = Builder (action = 'msgfmt -o $TARGET $SOURCE', 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 \ @@ -314,6 +326,7 @@ a = 'msgmerge ${SOURCE} ${SOURCE.dir}/lilypond.pot -o ${TARGET}' + ugh 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}) @@ -324,31 +337,48 @@ LYS2TELY = Builder (action = a, suffix = '.tely', src_suffix = '.ly') 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) diff --git a/buildscripts/mutopia-index.py b/buildscripts/mutopia-index.py index f63240cec8..82f5bf007f 100644 --- a/buildscripts/mutopia-index.py +++ b/buildscripts/mutopia-index.py @@ -36,7 +36,7 @@ For a good impression of the quality print out the PDF file. """ headertext_nopics= r""" -

No examples were found in this directory. +

Nothing to be seen here, move along. """ # @@ -196,9 +196,7 @@ if not dirs: 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) diff --git a/buildscripts/output-distance.py b/buildscripts/output-distance.py index 7c7a914d56..a19380f1f2 100644 --- a/buildscripts/output-distance.py +++ b/buildscripts/output-distance.py @@ -1,12 +1,6 @@ #!@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 @@ -15,9 +9,8 @@ X_AXIS = 0 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 @@ -31,9 +24,6 @@ def max_distance (x1, x2): 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) @@ -45,10 +35,6 @@ def interval_intersect (i1, i2): 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])) @@ -78,10 +64,10 @@ class GrobSignature: 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 @@ -100,13 +86,15 @@ class GrobSignature: 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 = {} @@ -142,9 +130,6 @@ class SystemSignature: 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 @@ -153,301 +138,48 @@ class SystemLink: 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 = '%s' % name - - return ''' - - - -
-(%(name)s) - - -''' % 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 = ''' - - -%f
-(details) - - -%s -%s - -''' % (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 = '%d' % c - for d in link.distance (): - e += '%f' % d - - e = '%s' % e - - html += e - - e = '%d' % c - for s in (link.output_expression_details_string (), - link.orphan_details_string (), - link.geo_details_string ()): - e += "%s" % s - - - e = '%s' % e - html += e - - original = self.original_name - html = ''' - -comparison details for %(original)s - - - - - - - - - - -%(html)s -
systemoutputorphangeo
- - - -''' % 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) @@ -481,160 +213,138 @@ class ComparisonData: 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 ''' + + + +
+(source) + + +''' % locals () + + html_entry = ''' + + +%f + + +%s +%s + +''' % (score, img_cell (ly_1, img_1), img_cell (ly_2, img_2)) + + + html += html_entry html = ''' - +
- - + + %(html)s
distance%(dir1)s%(dir2)soldnew
''' % locals() - - html += ('

') - below_count =len ([1 for s,l in results - if threshold >= s > 0.0]) - - if below_count: - html += ('

%d below threshold

' % below_count) - - html += ('

%d unchanged

' - % 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 @@ -650,30 +360,17 @@ def test_paired_files (): 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 (): @@ -684,17 +381,11 @@ 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' : '', @@ -711,10 +402,8 @@ def test_basic_compare (): '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) @@ -722,63 +411,42 @@ def test_basic_compare (): 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 () ################################################################ @@ -788,25 +456,10 @@ def main (): 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 () @@ -818,11 +471,7 @@ def main (): 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() diff --git a/buildscripts/readlink.py b/buildscripts/readlink.py deleted file mode 100644 index 41be20b56c..0000000000 --- a/buildscripts/readlink.py +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/python -import os -import sys - -for i in sys.argv[1:]: - print os.path.realpath(i) diff --git a/config.make.in b/config.make.in index 7a7c8d5aee..55dfaefda3 100644 --- a/config.make.in +++ b/config.make.in @@ -50,7 +50,6 @@ configure-srcdir = @srcdir@ 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 @@ -126,6 +125,7 @@ LINK_GXX_STATICALLY = @LINK_GXX_STATICALLY@ LN = @LN@ LN_S = @LN_S@ MAKEINFO_PROGRAM = @MAKEINFO@ +MAKEINFO_VERSION = @MAKEINFO_VERSION@ METAFONT = @METAFONT@ -progname=mf MFMODE = @MFMODE@ MFTRACE = @MFTRACE@ @@ -144,3 +144,6 @@ TAR = @TAR@ WINDRES = @WINDRES@ YACC = @YACC@ ZIP = @ZIP@ + + + diff --git a/configure.in b/configure.in index 489457146a..ce169f0d66 100644 --- a/configure.in +++ b/configure.in @@ -53,8 +53,6 @@ AC_SUBST(LINK_GXX_STATICALLY) # 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) @@ -73,7 +71,7 @@ else 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 diff --git a/cygwin/postinstall-lilypond.sh b/cygwin/postinstall-lilypond.sh index 257100cf7f..fbffab2c3e 100644 --- a/cygwin/postinstall-lilypond.sh +++ b/cygwin/postinstall-lilypond.sh @@ -26,5 +26,4 @@ regtool set '/root/LilyPond/shell/generate/' '&Generate PDF ...' 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 .) diff --git a/elisp/lilypond-mode.el b/elisp/lilypond-mode.el index d27487c6ed..db3c8caf4e 100644 --- a/elisp/lilypond-mode.el +++ b/elisp/lilypond-mode.el @@ -446,9 +446,9 @@ in LilyPond-include-path." ;; 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. diff --git a/flower/file-name.cc b/flower/file-name.cc index fd69d379d5..66b1aaa114 100644 --- a/flower/file-name.cc +++ b/flower/file-name.cc @@ -73,11 +73,7 @@ dir_name (string const file_name) 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; } @@ -92,46 +88,23 @@ get_working_directory () /* 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__ diff --git a/flower/include/GNUmakefile b/flower/include/GNUmakefile deleted file mode 100644 index 1d726fc78a..0000000000 --- a/flower/include/GNUmakefile +++ /dev/null @@ -1,9 +0,0 @@ -# flower/lib/include/Makefile - -depth = ../.. - -STEPMAKE_TEMPLATES=c++ - -include $(depth)/make/stepmake.make - - diff --git a/flower/include/file-name.hh b/flower/include/file-name.hh index 3d1a2d0fb2..edfa72c23f 100644 --- a/flower/include/file-name.hh +++ b/flower/include/file-name.hh @@ -27,9 +27,6 @@ public: bool is_absolute () const; string to_string () const; - - string dir_part () const; - string file_part () const; }; #endif /* FILE_NAME */ diff --git a/flower/include/flower-proto.hh b/flower/include/flower-proto.hh index 384d8b89c8..0d82d8bbc7 100644 --- a/flower/include/flower-proto.hh +++ b/flower/include/flower-proto.hh @@ -19,7 +19,7 @@ using namespace std; template struct Interval_t; template struct PQueue; -template class Matrix; + typedef Interval_t Interval; diff --git a/flower/include/international.hh b/flower/include/international.hh index b515af64c4..d1c71ed08b 100644 --- a/flower/include/international.hh +++ b/flower/include/international.hh @@ -9,8 +9,6 @@ #ifndef INTERNATIONAL_HH #define INTERNATIONAL_HH -#include - #include "std-string.hh" /** @@ -33,10 +31,6 @@ string _ (char const *ch); 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 diff --git a/flower/include/interval.hh b/flower/include/interval.hh index 7b7d4f54e5..1b095dedc3 100644 --- a/flower/include/interval.hh +++ b/flower/include/interval.hh @@ -128,9 +128,9 @@ struct Interval_t : public Drul_array at (RIGHT) = t; } - static bool left_less (Interval_t const &a, Interval_t const &b) + static int left_comparison (Interval_t const &a, Interval_t const &b) { - return a[LEFT] < b[RIGHT]; + return sign (a[LEFT] - b[RIGHT]); } }; diff --git a/flower/include/matrix.hh b/flower/include/matrix.hh deleted file mode 100644 index 4429ccc46d..0000000000 --- a/flower/include/matrix.hh +++ /dev/null @@ -1,66 +0,0 @@ -/* - matrix.hh -- declare and implement 2d arrays - - source file of the Flower Library - - (c) 2006 Joe Neeman -*/ - -#ifndef MATRIX_HH -#define MATRIX_HH - -#include "std-vector.hh" - -template > -class Matrix -{ -public: - Matrix () - { - rank_ = 0; - } - - Matrix (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 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 data_; - vsize rank_; -}; - -#endif /* MATRIX_HH */ diff --git a/flower/include/std-string.hh b/flower/include/std-string.hh index d0fdd9c978..bc2fd61ee5 100644 --- a/flower/include/std-string.hh +++ b/flower/include/std-string.hh @@ -11,15 +11,6 @@ #include "compare.hh" -#if 0 -/* - leads to dubious crashes - libstdc++ bug? - */ -#ifndef NDEBUG -#define _GLIBCXX_DEBUG 1 -#endif -#endif - #include using namespace std; diff --git a/flower/include/std-vector.hh b/flower/include/std-vector.hh index 10641dc5a0..83e58d299c 100644 --- a/flower/include/std-vector.hh +++ b/flower/include/std-vector.hh @@ -9,16 +9,6 @@ #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 /* find, reverse, sort */ #include /* unary_function */ #include @@ -142,66 +132,146 @@ concat (vector &v, vector const& w) v.insert (v.end (), w.begin (), w.end ()); } -template -vsize -lower_bound (vector const &v, - T const &key, - Compare less, - vsize b=0, vsize e=VPOS) +template +void +binary_search_bounds (vector const &table, + T const &key, int (*compare) (T const &, T const &), + vsize *lo, + vsize *hi) { - if (e == VPOS) - e = v.size (); - typename vector::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 -vsize -upper_bound (vector const &v, - T const &key, - Compare less, - vsize b=0, vsize e=VPOS) +template +void +binary_search_bounds (vector 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::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 +#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 vsize binary_search (vector const &v, - T const &key, - Compare less=less (), + 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::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 +vsize +binary_search (vector 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 + +#endif + + +#if 0 +/* FIXME: the COMPARE functionality is broken? */ +template void -vector_sort (vector &v, - Compare less, - vsize b=0, vsize e=VPOS) +vector_sort (vector &v, int (*compare) (T const &, T const &), + vsize lower=VPOS, vsize upper=VPOS) { - if (e == VPOS) - e = v.size (); + typename vector::iterator b = v.begin (); + typename vector::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 void +vector_sort (vector &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 void diff --git a/flower/international.cc b/flower/international.cc index ef1ebfbc89..7bb4130856 100644 --- a/flower/international.cc +++ b/flower/international.cc @@ -32,17 +32,11 @@ _f (char const *format, ...) { 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) { diff --git a/flower/std-string.cc b/flower/std-string.cc index 6d8ebd52f5..304ddf33cf 100644 --- a/flower/std-string.cc +++ b/flower/std-string.cc @@ -89,9 +89,8 @@ string_copy (string s) { 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; } @@ -106,9 +105,8 @@ string_compare (string const &a, string const &b) vector string_split (string str, char c) { - ssize i = str.find (c); - vector a; + ssize i = str.find (c); while (i != NPOS) { string s = str.substr (0, i); diff --git a/input/GNUmakefile b/input/GNUmakefile index da9987de40..8fa23d8275 100644 --- a/input/GNUmakefile +++ b/input/GNUmakefile @@ -1,6 +1,6 @@ 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 diff --git a/input/les-nereides.ly b/input/les-nereides.ly index ea0943c700..c987b46d5a 100644 --- a/input/les-nereides.ly +++ b/input/les-nereides.ly @@ -1,4 +1,4 @@ -\version "2.9.16" +\version "2.7.39" \header { composer = "ARTHUR GRAY" diff --git a/input/manual/GNUmakefile b/input/manual/GNUmakefile deleted file mode 100644 index 558863f1f2..0000000000 --- a/input/manual/GNUmakefile +++ /dev/null @@ -1,16 +0,0 @@ - -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 diff --git a/input/manual/README b/input/manual/README deleted file mode 100644 index f6e3131efb..0000000000 --- a/input/manual/README +++ /dev/null @@ -1,5 +0,0 @@ -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. - diff --git a/input/manual/SConscript b/input/manual/SConscript deleted file mode 100644 index ece0a25f0c..0000000000 --- a/input/manual/SConscript +++ /dev/null @@ -1,4 +0,0 @@ -# -*-python-*- - -Import ('env', 'collate') -collate (title = 'LilyPond Examples from the Manual') diff --git a/input/mutopia/E.Satie/petite-ouverture-a-danser.ly b/input/mutopia/E.Satie/petite-ouverture-a-danser.ly index e6e641a8d5..2981559188 100644 --- a/input/mutopia/E.Satie/petite-ouverture-a-danser.ly +++ b/input/mutopia/E.Satie/petite-ouverture-a-danser.ly @@ -7,7 +7,7 @@ copyright = "Public Domain" } -\version "2.9.16" +\version "2.7.39" global = { \key a \minor @@ -141,15 +141,9 @@ lower = \context Staff \relative c \new Voice{ \override SpacingSpanner #'spacing-increment = #3 } } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 4) - } + \midi { + \tempo 4 = 60 } - - } %% Local Variables: diff --git a/input/mutopia/F.Schubert/morgenlied.ly b/input/mutopia/F.Schubert/morgenlied.ly index d34939a15d..18cd30924a 100644 --- a/input/mutopia/F.Schubert/morgenlied.ly +++ b/input/mutopia/F.Schubert/morgenlied.ly @@ -160,7 +160,7 @@ pianoLH = \relative c'' \repeat volta 2 { \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 @@ -186,10 +186,7 @@ pianoLH = \relative c'' \repeat volta 2 { } } \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 70 4) - } + \tempo 4 = 70 } } } diff --git a/input/mutopia/F.Schubert/standchen.ly b/input/mutopia/F.Schubert/standchen.ly index eb952ee2f2..05a483da48 100644 --- a/input/mutopia/F.Schubert/standchen.ly +++ b/input/mutopia/F.Schubert/standchen.ly @@ -40,7 +40,7 @@ instrument = "Piano" footer = "Mutopia-2001/04/27-xx" } -\version "2.9.16" +\version "2.7.39" #(set-global-staff-size 16) @@ -448,14 +448,8 @@ bassStaff = \new Staff = "bass"<< \context { \RemoveEmptyStaffContext } } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 54 4) - } + \midi{ + \tempo 4 = 54 } - - } diff --git a/input/mutopia/J.S.Bach/baerenreiter-sarabande.ly b/input/mutopia/J.S.Bach/baerenreiter-sarabande.ly index a61a1ff8a6..38faffd006 100644 --- a/input/mutopia/J.S.Bach/baerenreiter-sarabande.ly +++ b/input/mutopia/J.S.Bach/baerenreiter-sarabande.ly @@ -1,4 +1,4 @@ -\version "2.9.16" +\version "2.7.39" forcedLastBreak = { \break } @@ -126,7 +126,7 @@ sarabandeA = \context Voice \relative c { d'[ cis] | %% d4 d,,2 | d4 -% #(assert-system-count-override 6) + #(assert-system-count-override 6) d,,2 | } @@ -173,7 +173,6 @@ smallerPaper = \layout { line-width =183.5 \mm between-system-space = 25\mm between-system-padding = 0\mm - system-count = 6 %% annotatespacing = ##t } @@ -182,15 +181,7 @@ smallerPaper = \layout { \score{ \sarabandeCelloStaff \layout { } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 40 4) - } - } - - + \midi{ \tempo 4 = 40 } \header{ opus= "" piece ="Sarabande" } diff --git a/input/mutopia/J.S.Bach/bwv940.ly b/input/mutopia/J.S.Bach/bwv940.ly index b8f1391e95..7f8a687218 100644 --- a/input/mutopia/J.S.Bach/bwv940.ly +++ b/input/mutopia/J.S.Bach/bwv940.ly @@ -1,5 +1,5 @@ #(ly:set-option 'old-relative) -\version "2.9.16" +\version "2.7.39" %{ Header for Petites Preludes. @@ -158,15 +158,7 @@ global = { \override SpacingSpanner #'spacing-increment = #2.0 } } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 40 4) - } - } - - + \midi{ \tempo 4 = 40 } } diff --git a/input/mutopia/J.S.Bach/wtk1-fugue2.ly b/input/mutopia/J.S.Bach/wtk1-fugue2.ly index 38ee277e1b..22406fd1e6 100644 --- a/input/mutopia/J.S.Bach/wtk1-fugue2.ly +++ b/input/mutopia/J.S.Bach/wtk1-fugue2.ly @@ -219,10 +219,7 @@ bassdux = \context Voice = "three" \relative c' { } \layout {} \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 84 4) - } + \tempo 4 =84 } } \paper { diff --git a/input/mutopia/R.Schumann/romanze-op28-2.ly b/input/mutopia/R.Schumann/romanze-op28-2.ly index 18cd54a72d..9244f3a7ac 100644 --- a/input/mutopia/R.Schumann/romanze-op28-2.ly +++ b/input/mutopia/R.Schumann/romanze-op28-2.ly @@ -4,7 +4,7 @@ #(set-global-staff-size 16) -\version "2.9.16" +\version "2.7.39" \header { title = "Romanzen" @@ -255,7 +255,7 @@ leftb = \transpose c cis { \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 >> @@ -265,8 +265,8 @@ leftb = \transpose c cis { \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" { @@ -288,15 +288,7 @@ leftb = \transpose c cis { \override VerticalAlignment #'forced-distance = #13.0 } } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 100 8) - } - } - - + \midi { \tempo 8=100 } } diff --git a/input/mutopia/W.A.Mozart/mozart-hrn-3.ly b/input/mutopia/W.A.Mozart/mozart-hrn-3.ly index faa48451c6..b572c07802 100644 --- a/input/mutopia/W.A.Mozart/mozart-hrn-3.ly +++ b/input/mutopia/W.A.Mozart/mozart-hrn-3.ly @@ -12,9 +12,9 @@ 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" @@ -23,7 +23,7 @@ \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 ".")) } @@ -41,7 +41,7 @@ virtuoso that taught in Geneva. %} -\version "2.9.16" +\version "2.7.39" \include "mozart-hrn3-defs.ily" \include "mozart-hrn3-allegro.ily" @@ -59,29 +59,13 @@ virtuoso that taught in Geneva. { \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 {} } @@ -89,15 +73,7 @@ virtuoso that taught in Geneva. { { \transpose c' bes \rondo } \header { piece = "Rondo" opus = "" } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 100 4) - } - } - - + \midi { \tempo 4 = 100 } \layout { } } } diff --git a/input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily b/input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily index 3a10112524..c383c429de 100644 --- a/input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily +++ b/input/mutopia/W.A.Mozart/mozart-hrn3-defs.ily @@ -45,7 +45,6 @@ cresc = { indent = 10. \mm line-width = 189. \mm - ragged-last-bottom = ##f } diff --git a/input/no-notation/display-lily-tests.ly b/input/no-notation/display-lily-tests.ly index 5b931ad495..8c99abf835 100644 --- a/input/no-notation/display-lily-tests.ly +++ b/input/no-notation/display-lily-tests.ly @@ -1,4 +1,4 @@ -\version "2.9.16" +\version "2.9.5" #(use-modules (srfi srfi-13) (ice-9 format)) diff --git a/input/no-notation/dynamic-absolute-volume.ly b/input/no-notation/dynamic-absolute-volume.ly index c91d8a02bf..6a6397c54c 100644 --- a/input/no-notation/dynamic-absolute-volume.ly +++ b/input/no-notation/dynamic-absolute-volume.ly @@ -1,5 +1,5 @@ -\version "2.9.16" +\version "2.7.39" \header { texidoc = "@cindex Dynamic Absolute Volume Absolute dynamics have an effect on MIDI files. @@ -21,14 +21,8 @@ a\fff a\sf } \layout{ ragged-right = ##t } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 1) - } - } - - +\midi{ +\tempo 1 = 60 +} } diff --git a/input/no-notation/midi-volume-equaliser.ly b/input/no-notation/midi-volume-equaliser.ly index d577ebd256..a8dbfa7451 100644 --- a/input/no-notation/midi-volume-equaliser.ly +++ b/input/no-notation/midi-volume-equaliser.ly @@ -1,5 +1,5 @@ #(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 @@ -23,32 +23,32 @@ Override, see scm/midi.scm: 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 @@ -56,16 +56,16 @@ fagotti = \relative c' { 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 @@ -73,32 +73,32 @@ trombe = \relative c' { 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 @@ -107,8 +107,8 @@ viola = \relative c' { 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 @@ -153,15 +153,9 @@ violoncello = \relative c' { \RemoveEmptyStaffContext } } - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 1) - } - } - - + \tempo 1 = 60 + } } diff --git a/input/proportional.ly b/input/proportional.ly index ce7545b368..0738aa10bb 100644 --- a/input/proportional.ly +++ b/input/proportional.ly @@ -1,4 +1,4 @@ -\version "2.9.11" +\version "2.7.39" \header { @@ -12,7 +12,7 @@ \context { \Voice \remove "Forbid_line_break_engraver" - \override TupletNumber #'text = #tuplet-number::calc-fraction-text + tupletNumberFormatFunction = #fraction-tuplet-formatter tupletFullLength = ##t allowBeamBreak = ##t } diff --git a/input/puer-fragment.ly b/input/puer-fragment.ly index 0ffed32d83..3f3c5aae27 100644 --- a/input/puer-fragment.ly +++ b/input/puer-fragment.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header { title = "Puer natus est nobis" subtitle = "Antiphona ad introitum VII" @@ -24,7 +24,7 @@ ligature (not demonstrated in this example)." %%% global search/replace operations in emacs). cantus = \new VaticanaVoice = "cantus" { - \set Staff.instrumentName = \markup { + \set Staff.instrument = \markup { \column { " " " " " " " " "VII" " " { diff --git a/input/regression/+.ly b/input/regression/+.ly index 58b91aef45..990ef8a1fb 100644 --- a/input/regression/+.ly +++ b/input/regression/+.ly @@ -15,9 +15,6 @@ text corresponds with the shown notation, we consider LilyPond Officially 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. ") diff --git a/input/regression/accidental-forced-tie.ly b/input/regression/accidental-forced-tie.ly deleted file mode 100644 index 6c5b605ccb..0000000000 --- a/input/regression/accidental-forced-tie.ly +++ /dev/null @@ -1,13 +0,0 @@ -\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? - } diff --git a/input/regression/alignment-vertical-spacing.ly b/input/regression/alignment-vertical-spacing.ly index 5d04f58203..f108d43e40 100644 --- a/input/regression/alignment-vertical-spacing.ly +++ b/input/regression/alignment-vertical-spacing.ly @@ -16,7 +16,7 @@ setting properties on individual object. @code{\override} in a } -\version "2.9.13" +\version "2.7.39" #(set-global-staff-size 13) @@ -29,8 +29,8 @@ setting properties on individual object. @code{\override} in a \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 diff --git a/input/regression/bar-line-dashed.ly b/input/regression/bar-line-dashed.ly deleted file mode 100644 index 11138d2640..0000000000 --- a/input/regression/bar-line-dashed.ly +++ /dev/null @@ -1,17 +0,0 @@ - -\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 - } ->> - diff --git a/input/regression/bar-scripts.ly b/input/regression/bar-scripts.ly index 353aa8bb53..37fcf6ddd2 100644 --- a/input/regression/bar-scripts.ly +++ b/input/regression/bar-scripts.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header{ texidoc=" @@ -9,8 +9,8 @@ Markings can be attached to (invisible) barlines. \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 } @@ -18,7 +18,7 @@ grstaff = \relative c'' \context GrandStaff << \new Staff { - \set Staff.shortInstrumentName = instr + \set Staff.instr = instr \mark "B" \break c1 \mark "A" c2 } \new Staff { c1 c2 } diff --git a/input/regression/beaming-ternary-metrum.ly b/input/regression/beaming-ternary-metrum.ly index b79f75d42d..0bc3df702d 100644 --- a/input/regression/beaming-ternary-metrum.ly +++ b/input/regression/beaming-ternary-metrum.ly @@ -1,21 +1,12 @@ -\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] } diff --git a/input/regression/beaming.ly b/input/regression/beaming.ly index b2507a433f..09dc8938f1 100644 --- a/input/regression/beaming.ly +++ b/input/regression/beaming.ly @@ -4,15 +4,12 @@ \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.] | @@ -25,7 +22,7 @@ case, line breaks are forbidden. 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 ? diff --git a/input/regression/bend-after.ly b/input/regression/bend-after.ly deleted file mode 100644 index 3572bf58ec..0000000000 --- a/input/regression/bend-after.ly +++ /dev/null @@ -1,25 +0,0 @@ -\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 -} diff --git a/input/regression/breathing-sign-ancient.ly b/input/regression/breathing-sign-ancient.ly index 7c9d1961fb..5e4de07dfc 100644 --- a/input/regression/breathing-sign-ancient.ly +++ b/input/regression/breathing-sign-ancient.ly @@ -11,29 +11,38 @@ finalis, the latter three looking similar to bar glyphs. \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 } } diff --git a/input/regression/drums.ly b/input/regression/drums.ly index 908514a56d..df8f856451 100644 --- a/input/regression/drums.ly +++ b/input/regression/drums.ly @@ -7,7 +7,7 @@ } -\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 } @@ -21,11 +21,11 @@ timb = \drummode { \repeat "unfold" 2 {timh4 ssh timl8 ssh r timh r4 ssh8 timl r \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 } >> @@ -34,15 +34,7 @@ timb = \drummode { \repeat "unfold" 2 {timh4 ssh timl8 ssh r timh r4 ssh8 timl r \layout {} %% broken: - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 120 4) - } - } - - + \midi{ \tempo 4=120 } } diff --git a/input/regression/figured-bass-staff.ly b/input/regression/figured-bass-staff.ly index ce55332901..fc49f90780 100644 --- a/input/regression/figured-bass-staff.ly +++ b/input/regression/figured-bass-staff.ly @@ -1,22 +1,17 @@ \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. - -" - -} + } << diff --git a/input/regression/instrument-name-hara-kiri.ly b/input/regression/instrument-name-hara-kiri.ly index b7dd39dafa..ffe99e696e 100644 --- a/input/regression/instrument-name-hara-kiri.ly +++ b/input/regression/instrument-name-hara-kiri.ly @@ -9,13 +9,13 @@ as does the instrument name. " } -\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 } >> diff --git a/input/regression/instrument-name-markup.ly b/input/regression/instrument-name-markup.ly index f85066b599..f75de91267 100644 --- a/input/regression/instrument-name-markup.ly +++ b/input/regression/instrument-name-markup.ly @@ -9,13 +9,13 @@ including alterations. " \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'' } } diff --git a/input/regression/instrument-name-partial.ly b/input/regression/instrument-name-partial.ly index d6f2f70b04..9a122d3d43 100644 --- a/input/regression/instrument-name-partial.ly +++ b/input/regression/instrument-name-partial.ly @@ -1,5 +1,5 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc = "Instrument names are also printed on partial starting measures." } @@ -8,7 +8,7 @@ -\relative c'' { \set Staff.instrumentName = "foo" \partial 4 c4 c1 } +\relative c'' { \set Staff.instrument = "foo" \partial 4 c4 c1 } diff --git a/input/regression/instrument-name.ly b/input/regression/instrument-name.ly index f5db7f49de..6d7b540a56 100644 --- a/input/regression/instrument-name.ly +++ b/input/regression/instrument-name.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header{ texidoc=" Staff margins are also markings attached to barlines. They should be @@ -20,10 +20,10 @@ PianoStaff. \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 } >> diff --git a/input/regression/instrument-switch.ly b/input/regression/instrument-switch.ly deleted file mode 100644 index 73f6dff473..0000000000 --- a/input/regression/instrument-switch.ly +++ /dev/null @@ -1,31 +0,0 @@ - -\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 -} diff --git a/input/regression/metronome-marking.ly b/input/regression/metronome-marking.ly index e6b9efd2f8..e8bf64e0cb 100644 --- a/input/regression/metronome-marking.ly +++ b/input/regression/metronome-marking.ly @@ -14,7 +14,7 @@ The marking is left aligned with the time signature, if there is one. \layout { ragged-right = ##t } -\version "2.9.16" +\version "2.7.39" \relative c'' { \tempo \breve = 100 c1 c1 \tempo 8.. = 50 c1 diff --git a/input/regression/multi-measure-rest-instr-name.ly b/input/regression/multi-measure-rest-instr-name.ly index 66c9e1fc6b..49c37b1bfa 100644 --- a/input/regression/multi-measure-rest-instr-name.ly +++ b/input/regression/multi-measure-rest-instr-name.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc = "There are both long and short instrument names. @@ -18,7 +18,7 @@ multimeasure rests. " \context Staff << - \set Staff.instrumentName = "instrument" - \set Staff.shortInstrumentName = "instr" + \set Staff.instrument = "instrument" + \set Staff.instr = "instr" {c''1 \break R1 } >> diff --git a/input/regression/note-head-solfa.ly b/input/regression/note-head-solfa.ly index 4e92c3e10e..a7a78b8eba 100644 --- a/input/regression/note-head-solfa.ly +++ b/input/regression/note-head-solfa.ly @@ -11,9 +11,7 @@ to the @code{tonic} property." 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 } diff --git a/input/regression/optimal-page-breaking-hstretch.ly b/input/regression/optimal-page-breaking-hstretch.ly deleted file mode 100644 index bf8bf1fed6..0000000000 --- a/input/regression/optimal-page-breaking-hstretch.ly +++ /dev/null @@ -1,24 +0,0 @@ -\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} -} - - diff --git a/input/regression/page-layout-manual-position.ly b/input/regression/page-layout-manual-position.ly index 8da7f73701..704061ca9c 100644 --- a/input/regression/page-layout-manual-position.ly +++ b/input/regression/page-layout-manual-position.ly @@ -16,9 +16,9 @@ systems may be placed absolutely on the printable area of the page." 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 { diff --git a/input/regression/page-layout.ly b/input/regression/page-layout.ly index 5d2ecdff2a..f999a0750a 100644 --- a/input/regression/page-layout.ly +++ b/input/regression/page-layout.ly @@ -37,12 +37,7 @@ This file is best viewed outside the collated files document. line-width = 15\cm %rigthmargin = 3\cm interscoreline = 3\cm - - annotate-spacing = ##t - - - - } +} \book { diff --git a/input/regression/page-spacing.ly b/input/regression/page-spacing.ly index 0fa638031c..4081ba6d8c 100644 --- a/input/regression/page-spacing.ly +++ b/input/regression/page-spacing.ly @@ -8,7 +8,7 @@ For technical reasons, @code{overrideProperty} has to be used for 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. " } diff --git a/input/regression/page-turn-page-breaking-badturns.ly b/input/regression/page-turn-page-breaking-badturns.ly deleted file mode 100644 index ff872ae212..0000000000 --- a/input/regression/page-turn-page-breaking-badturns.ly +++ /dev/null @@ -1,22 +0,0 @@ -\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 -} - - diff --git a/input/regression/page-turn-page-breaking.ly b/input/regression/page-turn-page-breaking.ly deleted file mode 100644 index fee9a83a93..0000000000 --- a/input/regression/page-turn-page-breaking.ly +++ /dev/null @@ -1,32 +0,0 @@ -\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} -} - diff --git a/input/regression/prefatory-spacing-matter.ly b/input/regression/prefatory-spacing-matter.ly index 6020f0dbb6..983107b3b0 100644 --- a/input/regression/prefatory-spacing-matter.ly +++ b/input/regression/prefatory-spacing-matter.ly @@ -1,5 +1,5 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc = "Distances between prefatory items (e.g. clef, bar, @@ -15,7 +15,7 @@ bar-line is different from the start of line. } \relative c'' { - \set Staff.instrumentName = "fobar" + \set Staff.instrument = "fobar" \bar "||:" \key cis \major cis4 cis4 cis4 cis4 \clef bass cis,1 diff --git a/input/regression/quote-cue-during.ly b/input/regression/quote-cue-during.ly index 7c6cd4230b..0d14d06af9 100644 --- a/input/regression/quote-cue-during.ly +++ b/input/regression/quote-cue-during.ly @@ -11,7 +11,7 @@ last note." } -\version "2.9.13" +\version "2.7.39" \layout { ragged-right = ##t } @@ -34,15 +34,15 @@ cueStaff = \relative c'' << << \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 } >> diff --git a/input/regression/quote-during.ly b/input/regression/quote-during.ly index 6803c3771e..43e855dad9 100644 --- a/input/regression/quote-during.ly +++ b/input/regression/quote-during.ly @@ -8,7 +8,7 @@ quoted. In this example, a 16th rests is not quoted, since @code{rest-event} is not in @code{quotedEventTypes}." } -\version "2.9.13" +\version "2.7.39" \layout { ragged-right = ##t } @@ -21,16 +21,16 @@ original = \relative c'' { c8 d s2 es8 gis8 } << \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. } } diff --git a/input/regression/quote-grace.ly b/input/regression/quote-grace.ly index 6e434702e4..b0e426c53b 100644 --- a/input/regression/quote-grace.ly +++ b/input/regression/quote-grace.ly @@ -7,7 +7,7 @@ } \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 @@ -18,11 +18,11 @@ quoted = \relative c'' { << \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" diff --git a/input/regression/quote-tie.ly b/input/regression/quote-tie.ly deleted file mode 100644 index 5f7a07525e..0000000000 --- a/input/regression/quote-tie.ly +++ /dev/null @@ -1,29 +0,0 @@ -\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 } | -} diff --git a/input/regression/quote.ly b/input/regression/quote.ly index 4c56a0a30e..8c4732520d 100644 --- a/input/regression/quote.ly +++ b/input/regression/quote.ly @@ -7,7 +7,7 @@ things are quoted. In this example, a 16th rests is not quoted, since @code{rest-event} is not in @code{quotedEventTypes}." } -\version "2.9.13" +\version "2.7.39" \layout { ragged-right = ##t } @@ -20,15 +20,15 @@ original = \relative c'' { c8 d s2 es8 gis8 } << \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 { diff --git a/input/regression/repeat-percent-grace.ly b/input/regression/repeat-percent-grace.ly deleted file mode 100644 index 920e21f423..0000000000 --- a/input/regression/repeat-percent-grace.ly +++ /dev/null @@ -1,14 +0,0 @@ -\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 } ->> diff --git a/input/regression/rest-note-collision.ly b/input/regression/rest-note-collision.ly deleted file mode 100644 index 9b8f1a8028..0000000000 --- a/input/regression/rest-note-collision.ly +++ /dev/null @@ -1,31 +0,0 @@ - -\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 - } - >> -} diff --git a/input/regression/spacing-grace.ly b/input/regression/spacing-grace.ly index c4a1c466f8..aedc10df7d 100644 --- a/input/regression/spacing-grace.ly +++ b/input/regression/spacing-grace.ly @@ -1,27 +1,14 @@ -\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 } + + + + diff --git a/input/regression/spacing-loose-grace.ly b/input/regression/spacing-loose-grace.ly deleted file mode 100644 index 2d3d2432c0..0000000000 --- a/input/regression/spacing-loose-grace.ly +++ /dev/null @@ -1,30 +0,0 @@ - -\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 - } ->> diff --git a/input/regression/spacing-no-note.ly b/input/regression/spacing-no-note.ly deleted file mode 100644 index 7d65c9e238..0000000000 --- a/input/regression/spacing-no-note.ly +++ /dev/null @@ -1,13 +0,0 @@ -\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 } -} diff --git a/input/regression/spacing-section.ly b/input/regression/spacing-section.ly deleted file mode 100644 index 1b6f5d72ab..0000000000 --- a/input/regression/spacing-section.ly +++ /dev/null @@ -1,26 +0,0 @@ -\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] -} - - diff --git a/input/regression/stencil-color-rotation.ly b/input/regression/stencil-color-rotation.ly deleted file mode 100644 index e67486c5d7..0000000000 --- a/input/regression/stencil-color-rotation.ly +++ /dev/null @@ -1,10 +0,0 @@ -\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'\! -} diff --git a/input/regression/tag-filter.ly b/input/regression/tag-filter.ly index 5e96e9ec87..9aa03a8dc6 100644 --- a/input/regression/tag-filter.ly +++ b/input/regression/tag-filter.ly @@ -1,5 +1,5 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc = "The @code{\\tag} command marks music expressions with a @@ -33,15 +33,15 @@ common = \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 } } diff --git a/input/regression/tie-busy-grobs.ly b/input/regression/tie-busy-grobs.ly new file mode 100644 index 0000000000..89acd070a9 --- /dev/null +++ b/input/regression/tie-busy-grobs.ly @@ -0,0 +1,27 @@ +\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 }} +>> + + + + diff --git a/input/regression/tie-chord-partial.ly b/input/regression/tie-chord-partial.ly deleted file mode 100644 index 596e66e56f..0000000000 --- a/input/regression/tie-chord-partial.ly +++ /dev/null @@ -1,15 +0,0 @@ -\header -{ - texidoc = "Individual chord notes can also be tied" -} -\version "2.9.15" - -\paper { - ragged-right = ##t -} - -\relative { - -} - - diff --git a/input/regression/tie-whole.ly b/input/regression/tie-whole.ly deleted file mode 100644 index dadba2be22..0000000000 --- a/input/regression/tie-whole.ly +++ /dev/null @@ -1,16 +0,0 @@ -\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 -{ - 1~ - 1~ - 1~ -} diff --git a/input/regression/tuplet-beam.ly b/input/regression/tuplet-beam.ly index 8e2c87b42c..20a2d12498 100644 --- a/input/regression/tuplet-beam.ly +++ b/input/regression/tuplet-beam.ly @@ -1,5 +1,5 @@ -\version "2.9.11" +\version "2.7.39" \header { texidoc = "In combination with a beam, the bracket of the tuplet diff --git a/input/regression/tuplet-broken.ly b/input/regression/tuplet-broken.ly index da605d14bf..c518496f86 100644 --- a/input/regression/tuplet-broken.ly +++ b/input/regression/tuplet-broken.ly @@ -8,7 +8,7 @@ } -\version "2.9.11" +\version "2.7.39" \paper { ragged-right = ##t @@ -17,7 +17,7 @@ \relative c'' { - \override TupletNumber #'text = #tuplet-number::calc-fraction-text + \set tupletNumberFormatFunction = #fraction-tuplet-formatter \override TupletBracket #'edge-text = #(cons (markup #:fontsize 6 diff --git a/input/regression/tuplet-full-length-note.ly b/input/regression/tuplet-full-length-note.ly deleted file mode 100644 index ac001bf60c..0000000000 --- a/input/regression/tuplet-full-length-note.ly +++ /dev/null @@ -1,24 +0,0 @@ -\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 -} diff --git a/input/regression/tuplet-gap.ly b/input/regression/tuplet-gap.ly index 526ae17dc0..b9ca1f5891 100644 --- a/input/regression/tuplet-gap.ly +++ b/input/regression/tuplet-gap.ly @@ -5,7 +5,7 @@ } -\version "2.9.11" +\version "2.7.39" \layout { indent = 0.0\mm @@ -14,7 +14,7 @@ \relative c'' { - \override TupletNumber #'text = #tuplet-number::calc-fraction-text + \set tupletNumberFormatFunction = #fraction-tuplet-formatter \times 17/12 { c8 c4 c8 c8} } diff --git a/input/regression/tuplet-nest.ly b/input/regression/tuplet-nest.ly index a314952c13..7bbe8e817a 100644 --- a/input/regression/tuplet-nest.ly +++ b/input/regression/tuplet-nest.ly @@ -1,5 +1,5 @@ -\version "2.9.11" +\version "2.7.39" \header { texidoc=" Tuplets may be nested." @@ -11,7 +11,7 @@ } \relative c'' { - \override TupletNumber #'text = #tuplet-number::calc-fraction-text + \set tupletNumberFormatFunction = #fraction-tuplet-formatter \times 4/6 { \times 2/3 { a a a diff --git a/input/regression/utf-8-mixed-text.ly b/input/regression/utf-8-mixed-text.ly deleted file mode 100644 index 60687d4d81..0000000000 --- a/input/regression/utf-8-mixed-text.ly +++ /dev/null @@ -1,10 +0,0 @@ -\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" } diff --git a/input/regression/volta-broken-left-edge.ly b/input/regression/volta-broken-left-edge.ly index 01229f3893..944bad6fdb 100644 --- a/input/regression/volta-broken-left-edge.ly +++ b/input/regression/volta-broken-left-edge.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc ="Broken volta spanners behave correctly at their left edge in all cases." @@ -43,8 +43,8 @@ Bar 23 Perfect 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 diff --git a/input/sakura-sakura.ly b/input/sakura-sakura.ly index d178f2241e..4a617fce5f 100644 --- a/input/sakura-sakura.ly +++ b/input/sakura-sakura.ly @@ -1,6 +1,6 @@ %% sakura-sakura.ly -\version "2.9.16" +\version "2.7.39" \header { @@ -50,15 +50,7 @@ } >> \layout { } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 120 4) - } - } - - + \midi { \tempo 4=120 } } %%% Local Variables: diff --git a/input/manual/screech-boink.ly b/input/screech-boink.ly similarity index 90% rename from input/manual/screech-boink.ly rename to input/screech-boink.ly index 7b11aa079f..7528ce7e51 100644 --- a/input/manual/screech-boink.ly +++ b/input/screech-boink.ly @@ -1,4 +1,4 @@ -\version "2.9.16" +\version "2.7.39" \header { title = "Screech and boink" subtitle = "Random complex notation" @@ -51,15 +51,7 @@ >> } >> - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 60 8) - } - } - - + \midi { \tempo 8 = 60 } \layout { ragged-right = ##t diff --git a/input/test/+.ly b/input/test/+.ly index 7e597f1452..6f3f1ebd64 100644 --- a/input/test/+.ly +++ b/input/test/+.ly @@ -11,10 +11,6 @@ This document shows all kinds of tips and tricks, from simple to 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) ".") } diff --git a/input/test/add-staccato.ly b/input/test/add-staccato.ly index 45d61d4db1..3a8668c5b8 100644 --- a/input/test/add-staccato.ly +++ b/input/test/add-staccato.ly @@ -1,7 +1,8 @@ -\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." @@ -10,7 +11,7 @@ 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) @@ -22,15 +23,11 @@ example staccato dots are added to the notes." #(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 } } + diff --git a/input/test/add-text-script.ly b/input/test/add-text-script.ly index 6d66b21fe7..12a0604cb3 100644 --- a/input/test/add-text-script.ly +++ b/input/test/add-text-script.ly @@ -1,10 +1,12 @@ -\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. " } @@ -12,7 +14,7 @@ In this example, an extra fingering is attached to a note. (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) @@ -25,14 +27,9 @@ In this example, an extra fingering is attached to a note. (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 } } + diff --git a/input/manual/bar-lines.ly b/input/test/bar-lines.ly similarity index 70% rename from input/manual/bar-lines.ly rename to input/test/bar-lines.ly index 87eaeaa4f4..52c7cd9020 100644 --- a/input/manual/bar-lines.ly +++ b/input/test/bar-lines.ly @@ -3,7 +3,7 @@ \header { - texidoc = "There are many types of bar lines available." + texidoc = "There a many types of bar lines available." } @@ -21,13 +21,5 @@ 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 } diff --git a/input/manual/bar-number-regular-interval.ly b/input/test/bar-number-regular-interval.ly similarity index 100% rename from input/manual/bar-number-regular-interval.ly rename to input/test/bar-number-regular-interval.ly diff --git a/input/manual/chord-names-jazz.ly b/input/test/chord-names-jazz.ly similarity index 92% rename from input/manual/chord-names-jazz.ly rename to input/test/chord-names-jazz.ly index 55d51c4d4f..babe35ec65 100644 --- a/input/manual/chord-names-jazz.ly +++ b/input/test/chord-names-jazz.ly @@ -1,4 +1,4 @@ -\version "2.9.13" +\version "2.7.39" \header { texidoc = " Chord names are generated from a list pitches. The @@ -109,15 +109,15 @@ banterProperties = \sequential { \score{ << \new ChordNames { - \set instrumentName = #"Ignatzek (default)" - \set shortInstrumentName = #"Def" + \set instrument = #"Ignatzek (default)" + \set instr = #"Def" \chs } \new ChordNames { \jazzAltProperties - \set instrumentName = #"Alternative" - \set shortInstrumentName = #"Alt" + \set instrument = #"Alternative" + \set instr = #"Alt" \chs } @@ -133,8 +133,8 @@ banterProperties = \sequential { \new ChordNames { \banterProperties - \set instrumentName = #"Banter" - \set shortInstrumentName = #"Ban" + \set instrument = #"Banter" + \set instr = #"Ban" \chs } %} diff --git a/input/manual/chord-names-languages.ly b/input/test/chord-names-languages.ly similarity index 84% rename from input/manual/chord-names-languages.ly rename to input/test/chord-names-languages.ly index 4af777d565..3a22642e1a 100644 --- a/input/manual/chord-names-languages.ly +++ b/input/test/chord-names-languages.ly @@ -27,20 +27,20 @@ scm = \chordmode { << \new ChordNames { - \set instrumentName = #"default" + \set instrument = #"default" \scm } \new ChordNames { - \set instrumentName = #"german" + \set instrument = #"german" \germanChords \scm } \new ChordNames { - \set instrumentName = #"semi-german" + \set instrument = #"semi-german" \semiGermanChords \scm } \new ChordNames { - \set instrumentName = #"italian" + \set instrument = #"italian" \italianChords \scm } \new ChordNames { - \set instrumentName = #"french" + \set instrument = #"french" \frenchChords \scm } \context Voice { \scm } diff --git a/input/test/coriolan-margin.ly b/input/test/coriolan-margin.ly index a950c3a3f6..8bfd8ce3aa 100644 --- a/input/test/coriolan-margin.ly +++ b/input/test/coriolan-margin.ly @@ -1,5 +1,5 @@ -\version "2.9.13" +\version "2.7.39" % Ugh, we need to override some LaTeX titling stuff @@ -25,8 +25,8 @@ raisedFlat = \markup { \raise #0.4 \smaller \smaller \flat } 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 @@ -36,67 +36,67 @@ flauti = \relative 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 } diff --git a/input/manual/divisiones.ly b/input/test/divisiones.ly similarity index 94% rename from input/manual/divisiones.ly rename to input/test/divisiones.ly index d3054f99b6..b98091432e 100644 --- a/input/manual/divisiones.ly +++ b/input/test/divisiones.ly @@ -16,6 +16,7 @@ Choices are @code{divisioMinima}, @code{divisioMaior}, \score { << \context VaticanaVoice { + \override Staff.StaffSymbol #'color = #red \override TextScript #'padding = #3 g a g s^\markup { "divisio minima" } diff --git a/input/manual/engraver-example.ily b/input/test/engraver-example.ily similarity index 100% rename from input/manual/engraver-example.ily rename to input/test/engraver-example.ily diff --git a/input/test/engraver-one-by-one.ly b/input/test/engraver-one-by-one.ly index af0f289f25..ed79c1a589 100644 --- a/input/test/engraver-one-by-one.ly +++ b/input/test/engraver-one-by-one.ly @@ -65,8 +65,8 @@ MyStaff =\context { % weird effects when doing instrument names for % piano staves - instrumentName = #'() - shortInstrumentName = #'() + instrument = #'() + instr = #'() \accepts "Voice" } diff --git a/input/test/extra-staff.ly b/input/test/extra-staff.ly index 0cba000abd..71a54da3f2 100644 --- a/input/test/extra-staff.ly +++ b/input/test/extra-staff.ly @@ -1,5 +1,5 @@ -\version "2.9.16" +\version "2.7.39" % definitely wil be renamed to something. %{ diff --git a/input/manual/font-table.ly b/input/test/font-table.ly similarity index 97% rename from input/manual/font-table.ly rename to input/test/font-table.ly index b665ed3d21..01ce2abc3d 100644 --- a/input/manual/font-table.ly +++ b/input/test/font-table.ly @@ -1,5 +1,4 @@ -#(set-global-staff-size 16) \paper { %% ugh. text on toplevel is a bit broken... . diff --git a/input/test/instrument-name-align.ly b/input/test/instrument-name-align.ly index 3d982c68c0..cad9544e3f 100644 --- a/input/test/instrument-name-align.ly +++ b/input/test/instrument-name-align.ly @@ -8,7 +8,7 @@ names in padded boxes with @code{\markup}." } -\version "2.9.13" +\version "2.7.39" \paper { line-width = 15\cm @@ -18,11 +18,13 @@ names in padded boxes with @code{\markup}." \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 } diff --git a/input/test/instrument-name-grandstaff.ly b/input/test/instrument-name-grandstaff.ly index 004d79c844..e875d99ae6 100644 --- a/input/test/instrument-name-grandstaff.ly +++ b/input/test/instrument-name-grandstaff.ly @@ -1,4 +1,4 @@ -\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. " } @@ -7,9 +7,9 @@ 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 { diff --git a/input/test/music-box.ly b/input/test/music-box.ly index af8efd382b..4d11043f62 100644 --- a/input/test/music-box.ly +++ b/input/test/music-box.ly @@ -1,6 +1,4 @@ -\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 @@ -23,7 +21,7 @@ using Scheme functions to avoid typing work. " } (recurse (cdr elts)) ))))) music - )) + )) #(define ((trans pitches) music) (let* ((es (ly:music-property music 'elements)) @@ -52,6 +50,11 @@ using Scheme functions to avoid typing work. " } 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" << @@ -68,21 +71,15 @@ enda = { r8 f,16 a, c f c a, \stemUp c \change 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. @@ -124,7 +121,7 @@ prelude = %} } >> - + \layout { \context { \PianoStaff @@ -132,15 +129,9 @@ prelude = } line-width = 18.0 \cm } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 80 4) - } - } - - + \midi { + \tempo 4 = 80 + } } diff --git a/input/manual/ossia.ly b/input/test/ossia.ly similarity index 100% rename from input/manual/ossia.ly rename to input/test/ossia.ly diff --git a/input/test/reverse-music.ly b/input/test/reverse-music.ly index 985b471aef..828afcd59b 100644 --- a/input/test/reverse-music.ly +++ b/input/test/reverse-music.ly @@ -1,6 +1,5 @@ -\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 @@ -9,6 +8,8 @@ function to reverse the syntax. " } +music = \relative c'' { c4 d4( e4 f4 } + #(define (reverse-music music) (let* ((elements (ly:music-property music 'elements)) (reversed (reverse elements)) @@ -29,18 +30,12 @@ function to reverse the syntax. 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} } + diff --git a/input/manual/script-abbreviations.ly b/input/test/script-abbreviations.ly similarity index 100% rename from input/manual/script-abbreviations.ly rename to input/test/script-abbreviations.ly diff --git a/input/manual/script-chart.ly b/input/test/script-chart.ly similarity index 100% rename from input/manual/script-chart.ly rename to input/test/script-chart.ly diff --git a/input/test/smart-transpose.ly b/input/test/smart-transpose.ly index d97359157c..b1296b3948 100644 --- a/input/test/smart-transpose.ly +++ b/input/test/smart-transpose.ly @@ -1,5 +1,5 @@ -\version "2.9.7" -\sourcefilename "smart-transpose.ly" + +\version "2.7.39" \header { texidoc="@cindex Smart Transpose @@ -9,6 +9,7 @@ to have the minimum number of accidentals. In that case, ``Double 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. + " } % @@ -65,18 +66,14 @@ 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} } + diff --git a/input/test/staff-container.ly b/input/test/staff-container.ly index 5a3e3419e1..31495ac7c3 100644 --- a/input/test/staff-container.ly +++ b/input/test/staff-container.ly @@ -1,4 +1,4 @@ -\version "2.9.16" +\version "2.7.39" \header { diff --git a/input/test/temporary-stave.ly b/input/test/temporary-stave.ly index 5dd7d1bf58..8283c03860 100644 --- a/input/test/temporary-stave.ly +++ b/input/test/temporary-stave.ly @@ -1,5 +1,5 @@ -\version "2.9.16" +\version "2.7.39" \header { diff --git a/input/test/time-signature-staff.ly b/input/test/time-signature-staff.ly index 089b36e355..f9aa6baab2 100644 --- a/input/test/time-signature-staff.ly +++ b/input/test/time-signature-staff.ly @@ -6,7 +6,7 @@ used contemporary pieces with many time signature changes. " } -\version "2.9.16" +\version "2.7.39" \layout { ragged-right = ##T } diff --git a/input/test/unfold-all-repeats.ly b/input/test/unfold-all-repeats.ly new file mode 100644 index 0000000000..522bb38ade --- /dev/null +++ b/input/test/unfold-all-repeats.ly @@ -0,0 +1,27 @@ +\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 + } +} + + + + diff --git a/input/typography-demo.ly b/input/typography-demo.ly index 0683bced63..8dfc39302c 100644 --- a/input/typography-demo.ly +++ b/input/typography-demo.ly @@ -8,7 +8,7 @@ heavily mutilated Edition Peters Morgenlied by Schubert" } -\version "2.9.16" +\version "2.7.39" ignoreMelisma = \set ignoreMelismata = ##t ignoreMelismaOff = \unset ignoreMelismata @@ -129,7 +129,7 @@ pianoLH = \relative c'' \repeat volta 2\new Voice { \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 @@ -162,15 +162,9 @@ pianoLH = \relative c'' \repeat volta 2\new Voice { \override VerticalAlignment #'forced-distance = #10 } } - - \midi { - \context { - \Score - tempoWholesPerMinute = #(ly:make-moment 70 4) + \midi { + \tempo 4 = 70 } } - - - } } diff --git a/lily/SConscript b/lily/SConscript index ebd623fee9..d12e237fd1 100644 --- a/lily/SConscript +++ b/lily/SConscript @@ -14,6 +14,7 @@ e.Append ( CPPPATH = [ '#/lily/include', '#/flower/include', + '#/kpath-guile/include', outdir], LEXFLAGS = ['-Cfe', '-p', '-p'], LIBS = ['flower'], diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index 3bd03fb697..05990a6853 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -12,11 +12,11 @@ #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" @@ -26,7 +26,7 @@ class Accidental_entry { public: bool done_; - Stream_event *melodic_; + Music *melodic_; Grob *accidental_; Context *origin_; Engraver *origin_engraver_; @@ -51,8 +51,8 @@ class Accidental_engraver : public 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); @@ -289,7 +289,7 @@ number_accidentals (bool *different, 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); @@ -316,7 +316,7 @@ Accidental_engraver::process_acknowledged () 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")); @@ -333,8 +333,8 @@ Accidental_engraver::process_acknowledged () pitch, origin, cautionaries, barnum); - bool cautionary = to_boolean (note->get_property ("cautionary")); + if (num_caut > num) { num = num_caut; @@ -342,19 +342,13 @@ Accidental_engraver::process_acknowledged () 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); } } } @@ -364,7 +358,7 @@ Accidental_engraver::create_accidental (Accidental_entry *entry, 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")); @@ -392,7 +386,7 @@ Accidental_engraver::create_accidental (Accidental_entry *entry, } Grob * -Accidental_engraver::make_standard_accidental (Stream_event *note, +Accidental_engraver::make_standard_accidental (Music *note, Grob *note_head, Engraver *trans) { @@ -403,7 +397,11 @@ Accidental_engraver::make_standard_accidental (Stream_event *note, 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, @@ -434,12 +432,16 @@ Accidental_engraver::make_standard_accidental (Stream_event *note, } 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"))) @@ -478,7 +480,7 @@ Accidental_engraver::stop_translation_timestep () { 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")); @@ -534,10 +536,10 @@ Accidental_engraver::stop_translation_timestep () 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. @@ -603,7 +605,6 @@ ADD_TRANSLATOR (Accidental_engraver, "autoAccidentals " "autoCautionaries " - "internalBarNumber " "extraNatural " "harmonicAccidentals " "localKeySignature", diff --git a/lily/accidental-placement.cc b/lily/accidental-placement.cc index 199ff98c93..d8702520e1 100644 --- a/lily/accidental-placement.cc +++ b/lily/accidental-placement.cc @@ -7,18 +7,16 @@ */ -#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 @@ -28,10 +26,10 @@ Accidental_placement::add_accidental (Grob *me, Grob *a) 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; } @@ -136,12 +134,6 @@ int ape_compare (Accidental_placement_entry *const &a, 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) { @@ -161,7 +153,7 @@ stagger_apes (vector *apes) { vector asc = *apes; - vector_sort (asc, &ape_less); + vector_sort (asc, &ape_compare); apes->clear (); @@ -300,7 +292,7 @@ Accidental_placement::calc_positioning_done (SCM smob) for (vsize i = note_cols.size (); i--;) concat (heads, extract_grob_array (note_cols[i], "note-heads")); - vector_sort (heads, less ()); + vector_sort (heads, default_compare); uniq (heads); common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS); @@ -341,7 +333,6 @@ Accidental_placement::calc_positioning_done (SCM smob) Accidental_placement_entry *head_ape = new Accidental_placement_entry; common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS); vector head_skyline (empty_skyline (LEFT)); - vector head_extents; for (vsize i = heads.size (); i--;) { @@ -351,25 +342,6 @@ Accidental_placement::calc_positioning_done (SCM smob) insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT); } - vector 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 ()); - 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; diff --git a/lily/accidental.cc b/lily/accidental.cc index 0557883267..d79c17a9e9 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -47,12 +47,8 @@ Accidental_interface::after_line_breaking (SCM smob) 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; } @@ -260,7 +256,6 @@ ADD_INTERFACE (Accidental_interface, "accidental-interface", "avoid-slur " "cautionary " "cautionary-style " - "forced " "style " "tie " ); diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 736ecb9096..c315e4ec32 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -14,7 +14,6 @@ #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 @@ -93,7 +92,7 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a) vector elems (elem_source); // writable.. - Real where = 0; + Real where_f = 0; Interval v; v.set_empty (); @@ -118,9 +117,9 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a) 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)); } /* @@ -146,11 +145,8 @@ Align_interface::align_to_fixed_distance (Grob *me, Axis a) align_to_fixed_distance (). */ -vector -Align_interface::get_extents_aligned_translates (Grob *me, - vector 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 (me); @@ -160,7 +156,7 @@ Align_interface::get_extents_aligned_translates (Grob *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.")); @@ -175,9 +171,10 @@ Align_interface::get_extents_aligned_translates (Grob *me, vector dims; vector 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 (all_grobs[i]); @@ -206,9 +203,7 @@ Align_interface::get_extents_aligned_translates (Grob *me, ? scm_cdr (extra_space_handle) : SCM_EOL, extra_space); - - Real padding = robust_scm2double (me->get_property ("padding"), - 0.0); + vector translates; for (vsize j = 0; j < elems.size (); j++) { @@ -223,20 +218,17 @@ Align_interface::get_extents_aligned_translates (Grob *me, 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)); @@ -253,68 +245,24 @@ Align_interface::get_extents_aligned_translates (Grob *me, 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 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 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) { @@ -328,7 +276,7 @@ Align_interface::add_element (Grob *me, Grob *element) 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); } @@ -380,15 +328,12 @@ ADD_INTERFACE (Align_interface, /* properties */ - "align-dir " - "axes " - "elements " "forced-distance " - "padding " - "positioning-done " "stacking-dir " + "align-dir " "threshold " - ); + "positioning-done " + "elements axes"); struct Foobar { diff --git a/lily/all-font-metrics.cc b/lily/all-font-metrics.cc index 4159cd5a32..f7334849b8 100644 --- a/lily/all-font-metrics.cc +++ b/lily/all-font-metrics.cc @@ -13,12 +13,14 @@ #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 @@ -40,6 +42,7 @@ All_font_metrics::All_font_metrics (string path) All_font_metrics::~All_font_metrics () { + tfm_dict_->unprotect (); otf_dict_->unprotect (); #if HAVE_PANGO_FT2 @@ -153,11 +156,57 @@ All_font_metrics::find_otf (string name) return dynamic_cast (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 (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) { @@ -167,6 +216,9 @@ All_font_metrics::find_font (string name) 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 ())); diff --git a/lily/ambitus-engraver.cc b/lily/ambitus-engraver.cc index 6590b0a1cb..f71c33b49c 100644 --- a/lily/ambitus-engraver.cc +++ b/lily/ambitus-engraver.cc @@ -17,7 +17,6 @@ #include "protected-scm.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" -#include "stream-event.hh" #include "translator.icc" @@ -118,8 +117,8 @@ Ambitus_engraver::stop_translation_timestep () 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); @@ -184,12 +183,7 @@ Ambitus_engraver::finalize () ADD_ACKNOWLEDGER (Ambitus_engraver, note_head); ADD_TRANSLATOR (Ambitus_engraver, /* doc */ "", - /* create */ - "Ambitus " - "AmbitusLine " - "AmbitusNoteHead " - "AmbitusAccidental", - + /* create */ "Ambitus AmbitusLine AmbitusNoteHead AmbitusAccidental", /* accept */ "", /* read */ "", /* write */ ""); diff --git a/lily/apply-context-iterator.cc b/lily/apply-context-iterator.cc index adf708da35..0f6e6daff8 100644 --- a/lily/apply-context-iterator.cc +++ b/lily/apply-context-iterator.cc @@ -12,6 +12,9 @@ #include "music.hh" #include "simple-music-iterator.hh" +/** + Iterate a property. +*/ class Apply_context_iterator : public Simple_music_iterator { public: diff --git a/lily/arpeggio-engraver.cc b/lily/arpeggio-engraver.cc index 633d924e5a..fd28a41e1f 100644 --- a/lily/arpeggio-engraver.cc +++ b/lily/arpeggio-engraver.cc @@ -13,7 +13,6 @@ #include "stem.hh" #include "rhythmic-head.hh" #include "side-position-interface.hh" -#include "stream-event.hh" #include "note-column.hh" #include "translator.icc" @@ -29,10 +28,10 @@ public: 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 () @@ -41,10 +40,12 @@ 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 @@ -83,9 +84,7 @@ 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 @@ -95,13 +94,13 @@ Arpeggio_engraver::stop_translation_timestep () 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 */ ""); diff --git a/lily/audio-element-info.cc b/lily/audio-element-info.cc index 877828bb94..f6dd6b471f 100644 --- a/lily/audio-element-info.cc +++ b/lily/audio-element-info.cc @@ -11,7 +11,7 @@ #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; diff --git a/lily/audio-item.cc b/lily/audio-item.cc index fe8c5539e1..0e4ded6386 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -21,13 +21,12 @@ Audio_item::Audio_item () 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 diff --git a/lily/audio-staff.cc b/lily/audio-staff.cc index 5d402febf5..a715cbc1de 100644 --- a/lily/audio-staff.cc +++ b/lily/audio-staff.cc @@ -19,14 +19,14 @@ Audio_staff::add_audio_item (Audio_item *l) } 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; } diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 0472c4cdec..5ced1d2cfe 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -6,18 +6,17 @@ (c) 1999--2006 Jan Nieuwenhuizen */ -#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" @@ -29,6 +28,7 @@ protected: void stop_translation_timestep (); void start_translation_timestep (); void process_music (); + virtual bool try_music (Music *); virtual void finalize (); virtual void derived_mark () const; @@ -36,7 +36,6 @@ protected: DECLARE_ACKNOWLEDGER (beam); DECLARE_ACKNOWLEDGER (bar_line); DECLARE_ACKNOWLEDGER (stem); - DECLARE_TRANSLATOR_LISTENER (beam_forbid); void process_acknowledged (); @@ -51,7 +50,7 @@ private: bool is_same_grace_state (Grob *e); void typeset_beam (); - Stream_event *forbid_; + Music *forbid_; /* shortest_mom is the shortest note in the beam. */ @@ -129,11 +128,16 @@ Auto_beam_engraver::Auto_beam_engraver () 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 @@ -331,8 +335,8 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) { check_bar_property (); Item *stem = dynamic_cast (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; @@ -355,7 +359,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) return; } - int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log (); + int durlog = unsmob_duration (m->get_property ("duration"))->duration_log (); if (durlog <= 2) { @@ -371,7 +375,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) 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); @@ -386,7 +390,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) 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 diff --git a/lily/auto-change-iterator.cc b/lily/auto-change-iterator.cc index ade8303e0d..f5c54f224c 100644 --- a/lily/auto-change-iterator.cc +++ b/lily/auto-change-iterator.cc @@ -68,9 +68,8 @@ Auto_change_iterator::change_to (Music_iterator *it, SCM to_type_sym, { 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 { @@ -91,8 +90,6 @@ Auto_change_iterator::process (Moment m) 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_)) { diff --git a/lily/axis-group-engraver.cc b/lily/axis-group-engraver.cc index 7efe7b4874..fc4cc7b9a4 100644 --- a/lily/axis-group-engraver.cc +++ b/lily/axis-group-engraver.cc @@ -105,6 +105,8 @@ ADD_TRANSLATOR (Axis_group_engraver, /* create */ "VerticalAxisGroup", /* accept */ "", /* read */ - "currentCommandColumn ", + "verticalExtent " + "minimumVerticalExtent " + "extraVerticalExtent ", /* write */ ""); diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 02e900164b..d590813abf 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -8,16 +8,9 @@ #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 @@ -27,17 +20,17 @@ Axis_group_interface::add_element (Grob *me, Grob *e) 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 @@ -68,89 +61,6 @@ Axis_group_interface::relative_group_extent (vector const &elts, return r; } -Interval -Axis_group_interface::cached_pure_height (Grob *me, - vector const &elts, - Grob *common, - int start, int end) -{ - Paper_score *ps = get_root_system (me)->paper_score (); - vector breaks = ps->get_break_indices (); - vector 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 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 rank_span = elts[i]->spanned_rank_iv (); - Item *it = dynamic_cast (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) @@ -166,17 +76,6 @@ Axis_group_interface::height (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) @@ -190,51 +89,6 @@ 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 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 (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 *found) { @@ -257,8 +111,4 @@ ADD_INTERFACE (Axis_group_interface, "axis-group-interface", /* properties */ "axes " - "elements " - "common-refpoint-of-elements " - "pure-relevant-elements " - "cached-pure-extents " - ); + "elements "); diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index 16792eac58..2915165009 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -9,6 +9,7 @@ #include "bar-line.hh" #include "context.hh" +#include "score-context.hh" #include "score-engraver.hh" #include "warn.hh" #include "item.hh" diff --git a/lily/bar-line.cc b/lily/bar-line.cc index 0a1c0d9fea..4922a84d37 100644 --- a/lily/bar-line.cc +++ b/lily/bar-line.cc @@ -14,7 +14,6 @@ #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 @@ -125,17 +124,13 @@ Bar_line::compound_barline (Grob *me, string str, Real h, 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; @@ -172,72 +167,6 @@ Bar_line::calc_bar_size (SCM smob) } -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", @@ -253,20 +182,11 @@ ADD_INTERFACE (Bar_line, "\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 " @@ -275,5 +195,3 @@ ADD_INTERFACE (Bar_line, "glyph-name " "bar-size " ); - - diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 46d932e2f7..c8104d0bd0 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -15,8 +15,8 @@ #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" @@ -28,13 +28,13 @@ public: 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_; @@ -56,12 +56,12 @@ protected: 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); }; @@ -95,16 +95,24 @@ Beam_engraver::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 @@ -231,18 +239,23 @@ Beam_engraver::acknowledge_stem (Grob_info info) - 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 @@ -284,8 +297,6 @@ class Grace_beam_engraver : public Beam_engraver public: TRANSLATOR_DECLARATIONS (Grace_beam_engraver); - DECLARE_TRANSLATOR_LISTENER (beam); - protected: virtual bool valid_start_point (); virtual bool valid_end_point (); @@ -309,22 +320,6 @@ Grace_beam_engraver::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); diff --git a/lily/beam-performer.cc b/lily/beam-performer.cc index ba0135f1d0..0998ef3220 100644 --- a/lily/beam-performer.cc +++ b/lily/beam-performer.cc @@ -10,8 +10,8 @@ #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" @@ -21,13 +21,13 @@ public: 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_; }; @@ -69,16 +69,20 @@ Beam_performer::start_translation_timestep () 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, "", "", diff --git a/lily/beam.cc b/lily/beam.cc index d114c69fc3..9dd66cef9a 100644 --- a/lily/beam.cc +++ b/lily/beam.cc @@ -368,7 +368,7 @@ Beam::get_beam_segments (Grob *me_grob, Grob **common) i != stem_segments.end (); i++) { vector segs = (*i).second; - vector_sort (segs, less ()); + vector_sort (segs, default_compare); Beam_segment current; @@ -1169,6 +1169,8 @@ Beam::set_stem_lengths (SCM smob) 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, @@ -1179,14 +1181,9 @@ Beam::set_stem_lengths (SCM smob) 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); } @@ -1304,7 +1301,7 @@ Beam::last_visible_stem (Grob *me) 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) { diff --git a/lily/beaming-pattern.cc b/lily/beaming-pattern.cc index 8966657e48..f48faadc56 100644 --- a/lily/beaming-pattern.cc +++ b/lily/beaming-pattern.cc @@ -24,31 +24,6 @@ Beam_rhythmic_element::Beam_rhythmic_element (Moment m, int i) 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 { @@ -67,27 +42,16 @@ 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; } } @@ -107,27 +71,15 @@ Beaming_pattern::beam_extend_count (Direction d) const 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++) @@ -160,13 +112,13 @@ Beaming_pattern::beamify (Context *context) 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++; diff --git a/lily/binary-source-file.cc b/lily/binary-source-file.cc new file mode 100644 index 0000000000..90d4a4ac02 --- /dev/null +++ b/lily/binary-source-file.cc @@ -0,0 +1,94 @@ +/* + binary-source-file.cc -- implement Binary_source_file + + source file of the LilyPond music typesetter + + (c) 1997--2006 Jan Nieuwenhuizen +*/ + +#include // 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; +} + diff --git a/lily/book.cc b/lily/book.cc index f307bcf3c3..87df4efe84 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -12,7 +12,9 @@ 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" @@ -21,53 +23,25 @@ using namespace std; #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 () @@ -90,8 +64,7 @@ Book::mark_smob (SCM s) if (book->paper_) scm_gc_mark (book->paper_->self_scm ()); scm_gc_mark (book->scores_); - scm_gc_mark (book->input_location_); - + return book->header_; } @@ -115,7 +88,7 @@ Paper_book * 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; @@ -137,7 +110,7 @@ Book::process (Output_def *default_paper, 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))) { diff --git a/lily/box.cc b/lily/box.cc index 93356ac482..5201ca125c 100644 --- a/lily/box.cc +++ b/lily/box.cc @@ -6,7 +6,10 @@ (c) 1996--2006 Han-Wen Nienhuys */ +#include "ly-smobs.icc" + #include "box.hh" +#include "std-vector.hh" void Box::translate (Offset o) @@ -22,6 +25,9 @@ Box::unite (Box b) interval_a_[i].unite (b[i]); } +/** + Initialize to empty. +*/ Box::Box () { } @@ -79,10 +85,6 @@ Box::widen (Real x, Real y) 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); diff --git a/lily/break-algorithm.cc b/lily/break-algorithm.cc new file mode 100644 index 0000000000..d784b594f4 --- /dev/null +++ b/lily/break-algorithm.cc @@ -0,0 +1,40 @@ +/* + break.cc -- implement Break_algorithm + + source file of the GNU LilyPond music typesetter + + (c) 1996--2006 Han-Wen Nienhuys +*/ + +#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 +Break_algorithm::solve () +{ + vector h; + return h; +} + +Break_algorithm::~Break_algorithm () +{ +} diff --git a/lily/break-align-engraver.cc b/lily/break-align-engraver.cc index 461ead59ca..e6a7935c56 100644 --- a/lily/break-align-engraver.cc +++ b/lily/break-align-engraver.cc @@ -82,7 +82,10 @@ Break_align_engraver::acknowledge_break_aligned (Grob_info inf) /* 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_); } diff --git a/lily/break-align-interface.cc b/lily/break-align-interface.cc index f78ea4ef48..e5c0765d4f 100644 --- a/lily/break-align-interface.cc +++ b/lily/break-align-interface.cc @@ -325,7 +325,7 @@ Break_alignment_align_interface::self_align_callback (SCM grob) 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)) diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc index b01f242120..0c1e996580 100644 --- a/lily/break-substitution.cc +++ b/lily/break-substitution.cc @@ -397,7 +397,7 @@ Spanner::fast_substitute_grob_array (SCM sym, 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); @@ -500,14 +500,14 @@ Spanner::substitute_one_mutable_property (SCM sym, 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); } } } diff --git a/lily/breathing-sign-engraver.cc b/lily/breathing-sign-engraver.cc index 126110e07e..d659b64a90 100644 --- a/lily/breathing-sign-engraver.cc +++ b/lily/breathing-sign-engraver.cc @@ -12,12 +12,10 @@ . 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 { @@ -25,12 +23,12 @@ public: 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_; }; @@ -40,19 +38,20 @@ Breathing_sign_engraver::Breathing_sign_engraver () 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; } } @@ -63,6 +62,8 @@ Breathing_sign_engraver::stop_translation_timestep () breathing_sign_event_ = 0; } +#include "translator.icc" + ADD_TRANSLATOR (Breathing_sign_engraver, /* doc */ "", /* create */ "BreathingSign", diff --git a/lily/breathing-sign.cc b/lily/breathing-sign.cc index f8d02996f4..f39e748fb5 100644 --- a/lily/breathing-sign.cc +++ b/lily/breathing-sign.cc @@ -173,14 +173,11 @@ Breathing_sign::offset_callback (SCM smob) 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"); diff --git a/lily/change-iterator.cc b/lily/change-iterator.cc index 55099a855e..aef7567be0 100644 --- a/lily/change-iterator.cc +++ b/lily/change-iterator.cc @@ -74,8 +74,8 @@ Change_iterator::process (Moment m) 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. */ diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 20752ae2f7..963c3033f2 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -6,19 +6,17 @@ (c) 1998--2006 Jan Nieuwenhuizen */ -#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 { @@ -26,12 +24,14 @@ 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 notes_; + vector notes_; SCM last_chord_; }; @@ -53,6 +53,12 @@ Chord_name_engraver::Chord_name_engraver () last_chord_ = SCM_EOL; } +void +Chord_name_engraver::add_note (Music *n) +{ + notes_.push_back (n); +} + void Chord_name_engraver::process_music () { @@ -63,10 +69,10 @@ 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; @@ -119,11 +125,18 @@ Chord_name_engraver::process_music () 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 @@ -137,6 +150,8 @@ Chord_name_engraver::stop_translation_timestep () 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.", diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc index f07e984626..60800064c9 100644 --- a/lily/chord-tremolo-engraver.cc +++ b/lily/chord-tremolo-engraver.cc @@ -7,18 +7,18 @@ Erik Sandberg */ +#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" @@ -41,7 +41,7 @@ class Chord_tremolo_engraver : public Engraver { TRANSLATOR_DECLARATIONS (Chord_tremolo_engraver); protected: - Stream_event *repeat_; + Music *repeat_; int flags_; // number of beams for short tremolos @@ -52,8 +52,8 @@ protected: Spanner *beam_; protected: virtual void finalize (); + virtual bool try_music (Music *); void process_music (); - DECLARE_TRANSLATOR_LISTENER (tremolo_span); DECLARE_ACKNOWLEDGER (stem); }; @@ -66,31 +66,31 @@ Chord_tremolo_engraver::Chord_tremolo_engraver () 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 @@ -127,13 +127,13 @@ Chord_tremolo_engraver::acknowledge_stem (Grob_info info) 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); } diff --git a/lily/cluster-engraver.cc b/lily/cluster-engraver.cc index 33ee746e6b..faac5f79d0 100644 --- a/lily/cluster-engraver.cc +++ b/lily/cluster-engraver.cc @@ -12,22 +12,19 @@ #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 cluster_notes_; + vector cluster_notes_; Item *beacon_; void typeset_grobs (); @@ -58,11 +55,18 @@ Cluster_spanner_engraver::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 @@ -119,11 +123,13 @@ Cluster_spanner_engraver::acknowledge_note_column (Grob_info info) } } +#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 */ ""); diff --git a/lily/coherent-ligature-engraver.cc b/lily/coherent-ligature-engraver.cc index 96ff842d0c..ff1691ef64 100644 --- a/lily/coherent-ligature-engraver.cc +++ b/lily/coherent-ligature-engraver.cc @@ -9,12 +9,11 @@ #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 @@ -72,6 +71,37 @@ * 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? @@ -143,19 +173,19 @@ compute_delta_pitches (vector primitives) for (vsize i = 0; i < primitives.size (); i++) { primitive = dynamic_cast (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 diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc index 9a72b6d5ed..6fe80dc309 100644 --- a/lily/completion-note-heads-engraver.cc +++ b/lily/completion-note-heads-engraver.cc @@ -7,22 +7,20 @@ #include 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. @@ -50,8 +48,8 @@ class Completion_heads_engraver : public Engraver vector ties_; vector dots_; - vector note_events_; - vector scratch_note_events_; + vector note_events_; + vector scratch_note_events_; Moment note_end_mom_; bool is_first_; @@ -67,9 +65,9 @@ public: 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 @@ -78,24 +76,31 @@ Completion_heads_engraver::initialize () 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; } /* @@ -189,14 +194,14 @@ Completion_heads_engraver::process_music () 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]; @@ -216,7 +221,11 @@ Completion_heads_engraver::process_music () 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); @@ -287,19 +296,13 @@ Completion_heads_engraver::Completion_heads_engraver () { } +#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 */ ""); diff --git a/lily/constrained-breaking.cc b/lily/constrained-breaking.cc index b8253ac4e9..3996856cbd 100644 --- a/lily/constrained-breaking.cc +++ b/lily/constrained-breaking.cc @@ -4,7 +4,7 @@ source file of the GNU LilyPond music typesetter - (c) 2006 Joe Neeman + (c) 2006 Han-Wen Nienhuys */ #include "constrained-breaking.hh" @@ -38,7 +38,7 @@ 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 @@ -74,36 +74,37 @@ Constrained_breaking::calc_subproblem (vsize start, vsize sys, vsize brk) bool found_something = false; vsize start_col = starting_breakpoints_[start]; - Matrix &st = state_[start]; + vector &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; @@ -113,7 +114,10 @@ vector 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_); @@ -140,10 +144,66 @@ Constrained_breaking::resize (vsize 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 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++) @@ -158,10 +218,12 @@ Constrained_breaking::resize (vsize systems) vector 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 const &st = state_[start]; + vector const &st = state_[start]; vector ret; /* find the first solution that satisfies constraints */ @@ -169,17 +231,17 @@ Constrained_breaking::get_solution (vsize start, vsize end, vsize sys_count) { 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; @@ -190,72 +252,37 @@ Constrained_breaking::get_solution (vsize start, vsize end, vsize sys_count) } } /* 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 -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 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 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 Constrained_breaking::get_details (vsize start, vsize end, vsize sys_count) { - vsize brk = prepare_solution (start, end, sys_count); - Matrix const &st = state_[start]; + vsize rank; + vsize brk; + prepare_solution (start, end, sys_count, &rank, &brk); + vector const &st = state_[start]; vector 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 const &st = state_[start]; + + prepare_solution (start, end, 1, &rank, &brk); + vector 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++) @@ -264,7 +291,7 @@ Constrained_breaking::get_min_systems (vsize start, vsize end) { 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 */ @@ -278,8 +305,8 @@ Constrained_breaking::get_max_systems (vsize start, vsize end) 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); @@ -288,105 +315,26 @@ Constrained_breaking::prepare_solution (vsize start, vsize end, vsize sys_count) 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 const &start) +Constrained_breaking::Constrained_breaking (vector 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 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); } diff --git a/lily/context-def.cc b/lily/context-def.cc index 0af5fabf4f..fee67b661d 100644 --- a/lily/context-def.cc +++ b/lily/context-def.cc @@ -11,10 +11,14 @@ #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 () @@ -27,21 +31,14 @@ 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; @@ -51,11 +48,10 @@ Context_def::Context_def (Context_def const &s) 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_; @@ -96,7 +92,6 @@ Context_def::mark_smob (SCM smob) 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_; } @@ -148,6 +143,12 @@ Context_def::add_context_mod (SCM mod) 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 { @@ -258,19 +259,107 @@ Context_def::get_translator_names (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 (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 (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 (g)) + g->simple_trans_list_ = filter_performers (g->simple_trans_list_); + else if (dynamic_cast (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 () { diff --git a/lily/context-handle.cc b/lily/context-handle.cc index 80aa6a1a2f..b9c8692ff0 100644 --- a/lily/context-handle.cc +++ b/lily/context-handle.cc @@ -47,6 +47,12 @@ Context_handle::down () outlet_ = 0; } +bool +Context_handle::try_music (Music *m) +{ + return outlet_->try_music (m); +} + void Context_handle::operator = (Context_handle const &s) { diff --git a/lily/context-property.cc b/lily/context-property.cc index 851bbe0a41..502fc92f11 100644 --- a/lily/context-property.cc +++ b/lily/context-property.cc @@ -118,7 +118,7 @@ execute_general_pushpop_property (Context *context, { 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)) @@ -180,7 +180,7 @@ execute_general_pushpop_property (Context *context, 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)); } } @@ -224,7 +224,7 @@ apply_property_operations (Context *tg, SCM pre_init_ops) 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)); } } @@ -274,3 +274,51 @@ updated_grob_properties (Context *tg, SCM sym) 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 (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 (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 (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 (make_grob_from_properties (tr, x, cause, name)); + assert (sp); + return sp; +} diff --git a/lily/context-scheme.cc b/lily/context-scheme.cc index 9827c8bd41..92240a9b1d 100644 --- a/lily/context-scheme.cc +++ b/lily/context-scheme.cc @@ -84,7 +84,7 @@ LY_DEFINE (ly_context_set_property, "ly:context-set-property!", 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; } diff --git a/lily/context.cc b/lily/context.cc index 629dfadc4f..5e97a6171d 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -10,7 +10,6 @@ #include "context-def.hh" #include "dispatcher.hh" -#include "global-context.hh" #include "international.hh" #include "ly-smobs.icc" #include "main.hh" @@ -18,6 +17,7 @@ #include "profile.hh" #include "program-option.hh" #include "scm-hash.hh" +#include "score-context.hh" #include "translator-group.hh" #include "warn.hh" @@ -33,15 +33,15 @@ Context::check_removal () { 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); } } } @@ -59,13 +59,29 @@ Context::properties_dict () const } 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); + } } @@ -73,6 +89,7 @@ Context::Context (Object_key const *key) : key_manager_ (key) { daddy_context_ = 0; + init_ = false; aliases_ = SCM_EOL; iterator_count_ = 0; implementation_ = 0; @@ -81,6 +98,7 @@ Context::Context (Object_key const *key) context_list_ = SCM_EOL; definition_ = SCM_EOL; definition_mods_ = SCM_EOL; + unique_ = -1; event_source_ = 0; events_below_ = 0; @@ -140,8 +158,8 @@ Context::create_unique_context (SCM name, string id, SCM operations) } /* - 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 (daddy_context_)) @@ -202,8 +220,8 @@ Context::find_create_context (SCM n, string id, SCM operations) } /* - 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 (daddy_context_)) @@ -217,142 +235,36 @@ Context::find_create_context (SCM n, string id, SCM operations) 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 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; } /* @@ -439,12 +351,12 @@ properties and corresponding values, interleaved. This method should not 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 (); @@ -469,14 +381,12 @@ Context::add_alias (SCM sym) } 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); } @@ -490,36 +400,19 @@ Context::unset_property (SCM sym) 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. @@ -546,6 +439,25 @@ find_context_below (Context *where, 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 { @@ -565,10 +477,12 @@ Context::context_name () const return ly_symbol2string (context_name_symbol ()); } -Context * +Score_context * Context::get_score_context () const { - if (daddy_context_) + if (Score_context *sc = dynamic_cast ((Context *) this)) + return sc; + else if (daddy_context_) return daddy_context_->get_score_context (); else return 0; @@ -657,6 +571,20 @@ IMPLEMENT_SMOBS (Context); 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 { @@ -725,7 +653,7 @@ measure_position (Context const *context) 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)); diff --git a/lily/control-track-performer.cc b/lily/control-track-performer.cc deleted file mode 100644 index ec4ef83cdd..0000000000 --- a/lily/control-track-performer.cc +++ /dev/null @@ -1,70 +0,0 @@ - - -#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 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 (info.elem_)) - { - control_track_->add_audio_item (tempo); - } - if (Audio_time_signature * sig = dynamic_cast (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, "", "", - "", - "", ""); diff --git a/lily/custos-engraver.cc b/lily/custos-engraver.cc index 82381b764c..3b3f7610e0 100644 --- a/lily/custos-engraver.cc +++ b/lily/custos-engraver.cc @@ -11,10 +11,9 @@ #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" @@ -74,8 +73,8 @@ Custos_engraver::acknowledge_bar (Grob_info info) 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")) { /* @@ -86,7 +85,7 @@ Custos_engraver::acknowledge_note_head (Grob_info info) 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"))); } } diff --git a/lily/dispatcher-scheme.cc b/lily/dispatcher-scheme.cc index 2a2720656c..a8a2b273a1 100644 --- a/lily/dispatcher-scheme.cc +++ b/lily/dispatcher-scheme.cc @@ -38,7 +38,7 @@ LY_DEFINE (ly_add_listener, "ly:add-listener", 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)); diff --git a/lily/dispatcher.cc b/lily/dispatcher.cc index fb3df2a40f..e66f0952cb 100644 --- a/lily/dispatcher.cc +++ b/lily/dispatcher.cc @@ -7,12 +7,15 @@ */ #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); @@ -69,16 +72,11 @@ Dispatcher::dispatch (SCM sev) 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); @@ -173,10 +171,9 @@ inline void 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)); @@ -186,7 +183,7 @@ Dispatcher::internal_add_listener (Listener l, SCM ev_class, int priority) 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); } @@ -216,14 +213,13 @@ Dispatcher::remove_listener (Listener l, SCM ev_class) 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); @@ -248,7 +244,7 @@ Dispatcher::register_as_listener (Dispatcher *disp) 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); } @@ -260,9 +256,9 @@ Dispatcher::unregister_as_listener (Dispatcher *disp) { 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)); } } diff --git a/lily/dot-column.cc b/lily/dot-column.cc index a4b13be79f..3ebddc69a0 100644 --- a/lily/dot-column.cc +++ b/lily/dot-column.cc @@ -51,7 +51,7 @@ Dot_column::side_position (SCM smob) } } - return Side_position_interface::x_aligned_side (smob, SCM_EOL); + return Side_position_interface::x_aligned_side (smob); } struct Dot_position @@ -233,7 +233,7 @@ Dot_column::calc_positioning_done (SCM smob) } } - 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); diff --git a/lily/dots-engraver.cc b/lily/dots-engraver.cc deleted file mode 100644 index 1b34354e43..0000000000 --- a/lily/dots-engraver.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - dots-engraver.cc -- implement Dots_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2006 Han-Wen Nienhuys - -*/ - -#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*/ - ""); diff --git a/lily/drum-note-engraver.cc b/lily/drum-note-engraver.cc index c9dd52b8e6..1d1b8d2331 100644 --- a/lily/drum-note-engraver.cc +++ b/lily/drum-note-engraver.cc @@ -7,32 +7,30 @@ #include 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 notes_; + vector dots_; vector scripts_; - vector events_; + vector 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 (); }; @@ -40,11 +38,18 @@ Drum_notes_engraver::Drum_notes_engraver () { } -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 @@ -56,9 +61,27 @@ Drum_notes_engraver::process_music () 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; @@ -124,20 +147,20 @@ void 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 */ ""); diff --git a/lily/drum-note-performer.cc b/lily/drum-note-performer.cc index a4e0ff2f7f..a29b7a1dee 100644 --- a/lily/drum-note-performer.cc +++ b/lily/drum-note-performer.cc @@ -10,10 +10,9 @@ #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 { @@ -21,11 +20,12 @@ public: 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 note_evs_; + vector note_evs_; vector notes_; }; @@ -40,7 +40,7 @@ Drum_note_performer::process_music () 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; @@ -51,22 +51,7 @@ Drum_note_performer::process_music () 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); @@ -79,17 +64,31 @@ Drum_note_performer::process_music () 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", "", ""); diff --git a/lily/duration-scheme.cc b/lily/duration-scheme.cc index fb4bb10263..6f1ea4ef90 100644 --- a/lily/duration-scheme.cc +++ b/lily/duration-scheme.cc @@ -113,14 +113,6 @@ LY_DEFINE (ly_intlog2, "ly:intlog2", 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.") diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index daba771386..ab242f653c 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -21,7 +21,6 @@ #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" @@ -51,10 +50,10 @@ class Dynamic_engraver : public Engraver 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 accepted_spanevents_drul_; + Drul_array accepted_spanevents_drul_; vector pending_columns_; vector pending_elements_; @@ -67,11 +66,10 @@ class Dynamic_engraver : public Engraver 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 (); }; @@ -90,30 +88,28 @@ Dynamic_engraver::Dynamic_engraver () 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 @@ -123,7 +119,7 @@ Dynamic_engraver::process_music () { 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_; @@ -157,7 +153,7 @@ Dynamic_engraver::process_music () 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_) @@ -193,7 +189,7 @@ Dynamic_engraver::process_music () 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); @@ -209,19 +205,16 @@ Dynamic_engraver::process_music () /* 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 @@ -241,6 +234,9 @@ Dynamic_engraver::process_music () ly_symbol2scm ("adjacent-hairpins"), finished_cresc_); } + cresc_->set_property ("grow-direction", + scm_from_int ((start_type == "crescendo") + ? BIGGER : SMALLER)); } /* diff --git a/lily/dynamic-performer.cc b/lily/dynamic-performer.cc index 1e538800b4..05969cffad 100644 --- a/lily/dynamic-performer.cc +++ b/lily/dynamic-performer.cc @@ -9,7 +9,7 @@ #include "performer.hh" #include "audio-item.hh" -#include "stream-event.hh" +#include "music.hh" #include "translator.icc" /* @@ -24,12 +24,12 @@ class Dynamic_performer : public Performer 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_; }; @@ -77,7 +77,7 @@ Dynamic_performer::process_music () 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"); @@ -105,16 +105,23 @@ Dynamic_performer::stop_translation_timestep () { 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, diff --git a/lily/dynamic-text-spanner.cc b/lily/dynamic-text-spanner.cc index 1ebb70fe8c..a5d76e4bca 100644 --- a/lily/dynamic-text-spanner.cc +++ b/lily/dynamic-text-spanner.cc @@ -79,15 +79,6 @@ Dynamic_text_spanner::print (SCM smob) 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) diff --git a/lily/easy-notation.cc b/lily/easy-notation.cc index 6ddc00e1d3..fde6514345 100644 --- a/lily/easy-notation.cc +++ b/lily/easy-notation.cc @@ -11,15 +11,14 @@ #include 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" /* @@ -34,7 +33,7 @@ Note_head::brew_ez_stencil (SCM smob) 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 ()); diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index 6271d93979..71533cd116 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -6,54 +6,13 @@ (c) 1997--2006 Han-Wen Nienhuys */ -#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) diff --git a/lily/engraver.cc b/lily/engraver.cc index 2453188fff..eebd22e4be 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -8,16 +8,14 @@ #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 @@ -38,18 +36,13 @@ Engraver::announce_end_grob (Grob_info inf) } /* - 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); @@ -67,12 +60,7 @@ Engraver::announce_grob (Grob *e, SCM cause) 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); @@ -88,78 +76,6 @@ Engraver::Engraver () { } -#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 (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 (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 (internal_make_grob (x, cause, name, file, line, fun)); - assert (sp); - return sp; -} - #include "translator.icc" ADD_TRANSLATOR (Engraver, diff --git a/lily/event-chord-iterator.cc b/lily/event-chord-iterator.cc index 89a0f383a9..60e7e3081a 100644 --- a/lily/event-chord-iterator.cc +++ b/lily/event-chord-iterator.cc @@ -9,13 +9,11 @@ #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 () @@ -40,12 +38,6 @@ Event_chord_iterator::process (Moment m) 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); } diff --git a/lily/extender-engraver.cc b/lily/extender-engraver.cc index 53938b24f6..d3b2e90972 100644 --- a/lily/extender-engraver.cc +++ b/lily/extender-engraver.cc @@ -15,16 +15,13 @@ #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_; @@ -32,9 +29,9 @@ public: 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 (); }; @@ -46,11 +43,15 @@ Extender_engraver::Extender_engraver () 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 @@ -141,6 +142,8 @@ Extender_engraver::finalize () } } +#include "translator.icc" + ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable); ADD_TRANSLATOR (Extender_engraver, /* doc */ "Create lyric extenders", diff --git a/lily/fall-engraver.cc b/lily/fall-engraver.cc deleted file mode 100644 index b0751a31d5..0000000000 --- a/lily/fall-engraver.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - 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 */ ""); diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc index cf3e418883..01b352f28d 100644 --- a/lily/figured-bass-engraver.cc +++ b/lily/figured-bass-engraver.cc @@ -9,15 +9,16 @@ #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" @@ -30,7 +31,7 @@ struct Figure_group SCM alteration_; Item *figure_item_; - Stream_event *current_event_; + Music *current_music_; bool force_no_continuation_; Figure_group () @@ -41,17 +42,17 @@ struct 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")); } }; @@ -67,16 +68,14 @@ struct Figured_bass_engraver : public Engraver protected: vector groups_; Spanner *alignment_; - vector new_events_; + vector 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 (); @@ -104,7 +103,7 @@ Figured_bass_engraver::stop_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 (); @@ -115,7 +114,7 @@ Figured_bass_engraver::Figured_bass_engraver () alignment_ = 0; continuation_ = false; rest_event_ = 0; - new_event_found_ = false; + new_music_found_ = false; } void @@ -126,47 +125,43 @@ Figured_bass_engraver::start_translation_timestep () 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 @@ -249,20 +244,20 @@ Figured_bass_engraver::add_brackets () 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, @@ -285,17 +280,17 @@ Figured_bass_engraver::process_music () } 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. @@ -313,10 +308,10 @@ Figured_bass_engraver::process_music () } 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 ()) @@ -325,7 +320,7 @@ Figured_bass_engraver::process_music () groups_.push_back (group); } - groups_[k].current_event_ = new_events_[i]; + groups_[k].current_music_ = new_musics_[i]; groups_[k].figure_item_ = 0; k++; } @@ -413,14 +408,14 @@ Figured_bass_engraver::create_grobs () { 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); @@ -436,13 +431,13 @@ Figured_bass_engraver::create_grobs () } 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 ()); } @@ -480,8 +475,7 @@ ADD_TRANSLATOR (Figured_bass_engraver, "BassFigureLine " , /* accept */ - "bass-figure-event " - "rest-event", + "bass-figure-event rest-event", /* read */ "figuredBassAlterationDirection " @@ -489,7 +483,6 @@ ADD_TRANSLATOR (Figured_bass_engraver, "figuredBassFormatter " "implicitBassFigures " "useBassFigureExtenders " - "ignoreFiguredBassRest " , /* write */ diff --git a/lily/figured-bass-position-engraver.cc b/lily/figured-bass-position-engraver.cc index 2286fe6b52..af0d3be772 100644 --- a/lily/figured-bass-position-engraver.cc +++ b/lily/figured-bass-position-engraver.cc @@ -10,6 +10,7 @@ #include "engraver.hh" #include "context.hh" +#include "music.hh" #include "spanner.hh" #include "side-position-interface.hh" #include "translator.icc" @@ -21,13 +22,10 @@ class Figured_bass_position_engraver : public Engraver Spanner *bass_figure_alignment_; Spanner *positioner_; - vector support_; - vector span_support_; + vector 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); @@ -74,29 +72,7 @@ Figured_bass_position_engraver::finalize () 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::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 @@ -104,13 +80,11 @@ Figured_bass_position_engraver::stop_translation_timestep () { 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 @@ -129,10 +103,6 @@ Figured_bass_position_engraver::acknowledge_bass_figure_alignment (Grob_info inf 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); diff --git a/lily/fingering-engraver.cc b/lily/fingering-engraver.cc index f469df8139..a8c4fcf680 100644 --- a/lily/fingering-engraver.cc +++ b/lily/fingering-engraver.cc @@ -7,38 +7,39 @@ */ #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 events_; + vector events_; vector 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 @@ -71,7 +72,7 @@ Fingering_engraver::process_music () } 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 ()); @@ -111,6 +112,9 @@ Fingering_engraver::make_script (Direction d, Stream_event *r, int i) 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); } @@ -128,6 +132,8 @@ Fingering_engraver::Fingering_engraver () { } +#include "translator.icc" + ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head); ADD_ACKNOWLEDGER (Fingering_engraver, stem); ADD_TRANSLATOR (Fingering_engraver, diff --git a/lily/folded-repeat-iterator.cc b/lily/folded-repeat-iterator.cc index 79bfcb2fc7..1a4de7c369 100644 --- a/lily/folded-repeat-iterator.cc +++ b/lily/folded-repeat-iterator.cc @@ -98,7 +98,7 @@ Folded_repeat_iterator::enter_alternative () */ 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 (); diff --git a/lily/font-config.cc b/lily/font-config.cc index cbf77c7944..b59325f55a 100644 --- a/lily/font-config.cc +++ b/lily/font-config.cc @@ -30,18 +30,12 @@ init_fontconfig () 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 dirs; @@ -52,7 +46,7 @@ init_fontconfig () { 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 ())); } @@ -64,8 +58,7 @@ init_fontconfig () 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"); diff --git a/lily/font-metric-scheme.cc b/lily/font-metric-scheme.cc index 64d6f5c400..bcb034174e 100644 --- a/lily/font-metric-scheme.cc +++ b/lily/font-metric-scheme.cc @@ -6,7 +6,6 @@ (c) 2005--2006 Han-Wen Nienhuys */ -#include "warn.hh" #include "stencil.hh" #include "font-metric.hh" #include "modified-font-metric.hh" @@ -73,8 +72,11 @@ LY_DEFINE (ly_font_glyph_name_to_charcode, "ly:font-glyph-name-to-charcode", 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", @@ -95,10 +97,6 @@ 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), @@ -107,9 +105,7 @@ LY_DEFINE (ly_font_file_name, "ly:font-file-name", { 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", diff --git a/lily/font-metric.cc b/lily/font-metric.cc index 7cfb8d749c..70017df10c 100644 --- a/lily/font-metric.cc +++ b/lily/font-metric.cc @@ -179,12 +179,6 @@ Font_metric::sub_fonts () const return SCM_EOL; } -Stencil -Font_metric::word_stencil (string str) const -{ - return text_stencil (str); -} - Stencil Font_metric::text_stencil (string str) const { diff --git a/lily/forbid-break-engraver.cc b/lily/forbid-break-engraver.cc index 709f5e87d1..14471e8ec6 100644 --- a/lily/forbid-break-engraver.cc +++ b/lily/forbid-break-engraver.cc @@ -5,14 +5,14 @@ (c) 2002--_2005 Han-Wen Nienhuys */ -#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" diff --git a/lily/general-scheme.cc b/lily/general-scheme.cc index 5beda8355e..558d111f86 100644 --- a/lily/general-scheme.cc +++ b/lily/general-scheme.cc @@ -307,19 +307,3 @@ LY_DEFINE (ly_stderr_redirect, "ly:stderr-redirect", 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); -} diff --git a/lily/glissando-engraver.cc b/lily/glissando-engraver.cc index 6368e05a09..f5b0527bd1 100644 --- a/lily/glissando-engraver.cc +++ b/lily/glissando-engraver.cc @@ -10,11 +10,8 @@ #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. @@ -25,16 +22,16 @@ public: 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 () @@ -43,11 +40,15 @@ 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 @@ -100,6 +101,8 @@ Glissando_engraver::finalize () } } +#include "translator.icc" + ADD_ACKNOWLEDGER (Glissando_engraver, rhythmic_head); ADD_TRANSLATOR (Glissando_engraver, /* doc */ "Engrave a glissandi", diff --git a/lily/global-context-scheme.cc b/lily/global-context-scheme.cc index 219dc267c1..7eb5fb224a 100644 --- a/lily/global-context-scheme.cc +++ b/lily/global-context-scheme.cc @@ -5,6 +5,7 @@ (c) 2005--2006 Han-Wen Nienhuys */ + #include "cpu-timer.hh" #include "global-context.hh" #include "international.hh" @@ -14,7 +15,6 @@ #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", @@ -27,63 +27,22 @@ 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 (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 (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 ()) @@ -92,14 +51,25 @@ LY_DEFINE (ly_interpret_music_expression, "ly:interpret-music-expression", 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 ()) @@ -109,31 +79,13 @@ LY_DEFINE (ly_interpret_music_expression, "ly:interpret-music-expression", 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 (); } diff --git a/lily/global-context.cc b/lily/global-context.cc index 858922562f..6e2d26a58a 100644 --- a/lily/global-context.cc +++ b/lily/global-context.cc @@ -12,32 +12,24 @@ 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) @@ -56,6 +48,9 @@ Global_context::get_output_def () const 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"); @@ -79,22 +74,15 @@ Global_context::get_moments_left () const 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 @@ -103,30 +91,40 @@ Global_context::now_mom () const 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 (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 ()) @@ -137,16 +135,9 @@ Global_context::run_iterator_on_me (Music_iterator *iter) 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) { /* @@ -156,15 +147,28 @@ Global_context::run_iterator_on_me (Music_iterator *iter) 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 (c); + sc->prepare (w); + } + + one_time_step (); } } @@ -202,3 +206,9 @@ Global_context::get_default_interpreter () else return Context::get_default_interpreter (); } + +int +Global_context::new_unique () +{ + return ++unique_count_; +} diff --git a/lily/gourlay-breaking.cc b/lily/gourlay-breaking.cc new file mode 100644 index 0000000000..8599a6a57c --- /dev/null +++ b/lily/gourlay-breaking.cc @@ -0,0 +1,264 @@ +/* + gourlay-breaking.cc -- implement Gourlay_breaking + + source file of the GNU LilyPond music typesetter + + (c) 1997--2006 Han-Wen Nienhuys +*/ + +#include "gourlay-breaking.hh" + +#include // rint +#include +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 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 +Gourlay_breaking::solve () +{ + vector optimal_paths; + vector all + = pscore_->root_system ()->columns (); + + vector 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 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 final_breaks; + vector 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; +} + diff --git a/lily/grace-spacing-engraver.cc b/lily/grace-spacing-engraver.cc deleted file mode 100644 index f86b12ef22..0000000000 --- a/lily/grace-spacing-engraver.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - grace-spacing-engraver.cc -- implement Grace_spacing_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2006 Han-Wen - -*/ - -#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 */ ""); diff --git a/lily/gregorian-ligature-engraver.cc b/lily/gregorian-ligature-engraver.cc index e6b3c9b534..31263e9a12 100644 --- a/lily/gregorian-ligature-engraver.cc +++ b/lily/gregorian-ligature-engraver.cc @@ -14,12 +14,8 @@ #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 @@ -36,10 +32,16 @@ Gregorian_ligature_engraver::Gregorian_ligature_engraver () 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, @@ -202,9 +204,9 @@ provide_context_info (vector primitives) 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) diff --git a/lily/grob-array.cc b/lily/grob-array.cc index bf85be414c..dff5102a83 100644 --- a/lily/grob-array.cc +++ b/lily/grob-array.cc @@ -87,7 +87,7 @@ Grob_array::remove_duplicates () { assert (!ordered_); - vector_sort (grobs_, less ()); + vector_sort (grobs_, default_compare); ::uniq (grobs_); } diff --git a/lily/grob-closure.cc b/lily/grob-closure.cc index 5e4035f7e8..81bd393adb 100644 --- a/lily/grob-closure.cc +++ b/lily/grob-closure.cc @@ -37,7 +37,8 @@ add_offset_callback (Grob *g, SCM proc, Axis a) && !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 ; } @@ -52,7 +53,8 @@ add_offset_callback (Grob *g, SCM proc, Axis a) 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)); } @@ -75,18 +77,13 @@ chain_offset_callback (Grob *g, SCM proc, Axis a) 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))); } diff --git a/lily/grob-info.cc b/lily/grob-info.cc index 23ff736d95..a8f3f4c7b1 100644 --- a/lily/grob-info.cc +++ b/lily/grob-info.cc @@ -6,14 +6,13 @@ (c) 1997--2006 Han-Wen Nienhuys */ -#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) { @@ -29,11 +28,11 @@ Grob_info::Grob_info () 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 @@ -69,13 +68,15 @@ Grob_info::item () const return dynamic_cast (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); } + diff --git a/lily/grob-pq-engraver.cc b/lily/grob-pq-engraver.cc index 6f6ee8faab..e4e8b944f9 100644 --- a/lily/grob-pq-engraver.cc +++ b/lily/grob-pq-engraver.cc @@ -15,14 +15,13 @@ struct Grob_pq_entry { 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: @@ -60,13 +59,13 @@ LY_DEFINE (ly_grob_pq_less_p, "ly:grob-pq-less?", 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; @@ -96,7 +95,7 @@ Grob_pq_engraver::stop_translation_timestep () while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) == now) busy = scm_cdr (busy); - vector_sort (started_now_, less ()); + vector_sort (started_now_, Grob_pq_entry::compare); SCM lst = SCM_EOL; SCM *tail = &lst; for (vsize i = 0; i < started_now_.size (); i++) diff --git a/lily/grob-property.cc b/lily/grob-property.cc index 3924f4ece9..c4dce927b4 100644 --- a/lily/grob-property.cc +++ b/lily/grob-property.cc @@ -5,40 +5,18 @@ #include #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 @@ -53,9 +31,9 @@ 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?")); @@ -67,9 +45,6 @@ Grob::internal_set_property (SCM sym, SCM v, char const *file, int line, char co 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. */ @@ -86,16 +61,6 @@ Grob::internal_set_property (SCM sym, SCM v) 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); } @@ -190,7 +155,7 @@ Grob::try_callback (SCM sym, SCM proc) mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, marker); } else - set_property (sym, value); + internal_set_property (sym, value); return value; } @@ -206,7 +171,7 @@ Grob::internal_set_object (SCM s, SCM v) } void -Grob::internal_del_property (SCM sym) +Grob::del_property (SCM sym) { mutable_property_alist_ = scm_assq_remove_x (mutable_property_alist_, sym); } @@ -226,7 +191,7 @@ Grob::internal_get_object (SCM sym) const bool Grob::is_live () const { - return scm_is_pair (immutable_property_alist_); + return immutable_property_alist_ != SCM_EOL; } diff --git a/lily/grob-scheme.cc b/lily/grob-scheme.cc index 0c56e1fd13..c8bdc2c828 100644 --- a/lily/grob-scheme.cc +++ b/lily/grob-scheme.cc @@ -42,7 +42,7 @@ LY_DEFINE (ly_grob_set_property_x, "ly:grob-set-property!", && !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; } @@ -156,28 +156,6 @@ LY_DEFINE (ly_get_extent, "ly:grob-extent", 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), @@ -331,12 +309,6 @@ LY_DEFINE (ly_grob_default_font, "ly:grob-default-font", 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}." diff --git a/lily/grob.cc b/lily/grob.cc index 3e98a5b90a..15eb1f9212 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -10,8 +10,7 @@ #include -#include "align-interface.hh" -#include "input.hh" +#include "input-smob.hh" #include "international.hh" #include "item.hh" #include "main.hh" @@ -20,7 +19,6 @@ #include "output-def.hh" #include "pointer-group-interface.hh" #include "stencil.hh" -#include "stream-event.hh" #include "system.hh" #include "warn.hh" @@ -36,7 +34,6 @@ Grob::Grob (SCM basicprops, Object_key const *key) { key_ = key; - /* FIXME: default should be no callback. */ self_scm_ = SCM_EOL; layout_ = 0; @@ -122,7 +119,6 @@ Grob::get_print_stencil () const retval = Stencil (m->extent_box (), expr); } - SCM rot = get_property ("rotation"); if (scm_is_pair (rot)) { @@ -135,13 +131,14 @@ Grob::get_print_stencil () const /* 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); } } @@ -281,41 +278,6 @@ Grob::relative_coordinate (Grob const *refp, Axis a) const 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 @@ -343,14 +305,6 @@ 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 @@ -404,6 +358,7 @@ Grob::extent (Grob *refp, Axis a) const 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); } @@ -412,40 +367,6 @@ Grob::extent (Grob *refp, Axis a) const 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 -Grob::spanned_rank_iv () -{ - return Interval_t (-1, 0); -} - /**************************************************************** REFPOINTS ****************************************************************/ @@ -523,11 +444,8 @@ Grob::warning (string s) const 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); } @@ -551,11 +469,8 @@ Grob::programming_error (string s) const 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); } diff --git a/lily/hara-kiri-engraver.cc b/lily/hara-kiri-engraver.cc index 5e0e0a3b2d..39cc48a90b 100644 --- a/lily/hara-kiri-engraver.cc +++ b/lily/hara-kiri-engraver.cc @@ -23,7 +23,7 @@ protected: 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: @@ -43,9 +43,9 @@ Hara_kiri_engraver::derived_mark () const } 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"); } diff --git a/lily/hara-kiri-group-spanner.cc b/lily/hara-kiri-group-spanner.cc index 1515e8fea2..981639c237 100644 --- a/lily/hara-kiri-group-spanner.cc +++ b/lily/hara-kiri-group-spanner.cc @@ -25,84 +25,22 @@ Hara_kiri_group_spanner::y_extent (SCM smob) 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 (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 ranks; - - for (vsize i = 0; i < worth.size (); i++) - { - Interval_t iv = worth[i]->spanned_rank_iv (); - for (int j = iv[LEFT]; j <= iv[RIGHT]; j++) - ranks.push_back (j); - } - vector_sort (ranks, less ()); - 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 (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 childs; @@ -161,7 +99,6 @@ ADD_INTERFACE (Hara_kiri_group_spanner, "hara-kiri-group-interface", /* properties */ "items-worth-living " - "important-column-ranks " "remove-empty " "remove-first " ); diff --git a/lily/horizontal-bracket-engraver.cc b/lily/horizontal-bracket-engraver.cc index cfcd882a8e..5c553374a3 100644 --- a/lily/horizontal-bracket-engraver.cc +++ b/lily/horizontal-bracket-engraver.cc @@ -12,7 +12,6 @@ #include "note-column.hh" #include "pointer-group-interface.hh" #include "side-position-interface.hh" -#include "stream-event.hh" #include "translator.icc" @@ -21,14 +20,14 @@ class Horizontal_bracket_engraver : public Engraver public: TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver); vector bracket_stack_; - vector events_; + vector 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); @@ -45,26 +44,31 @@ Horizontal_bracket_engraver::Horizontal_bracket_engraver () 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 diff --git a/lily/hyphen-engraver.cc b/lily/hyphen-engraver.cc index 989c8fb32c..e4f4f3a991 100644 --- a/lily/hyphen-engraver.cc +++ b/lily/hyphen-engraver.cc @@ -13,15 +13,12 @@ #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_; @@ -32,9 +29,9 @@ public: protected: DECLARE_ACKNOWLEDGER (lyric_syllable); - DECLARE_TRANSLATOR_LISTENER (hyphen); virtual void finalize (); + virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); @@ -63,11 +60,14 @@ Hyphen_engraver::acknowledge_lyric_syllable (Grob_info i) 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 @@ -144,6 +144,8 @@ Hyphen_engraver::stop_translation_timestep () ev_ = 0; } +#include "translator.icc" + ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable); ADD_TRANSLATOR (Hyphen_engraver, diff --git a/lily/include/GNUmakefile b/lily/include/GNUmakefile deleted file mode 100644 index ae2bfb62f3..0000000000 --- a/lily/include/GNUmakefile +++ /dev/null @@ -1,8 +0,0 @@ -# lily/include/Makefile - -depth = ../.. -STEPMAKE_TEMPLATES=c++ - -include $(depth)/make/stepmake.make - - diff --git a/lily/include/align-interface.hh b/lily/include/align-interface.hh index 273dbc660c..b01c744bff 100644 --- a/lily/include/align-interface.hh +++ b/lily/include/align-interface.hh @@ -11,7 +11,6 @@ #include "lily-proto.hh" #include "lily-guile.hh" -#include "std-vector.hh" struct Align_interface { @@ -19,17 +18,12 @@ 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 get_extents_aligned_translates (Grob *, vector 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); diff --git a/lily/include/all-font-metrics.hh b/lily/include/all-font-metrics.hh index c8c0de2f0a..59cc9f86ea 100644 --- a/lily/include/all-font-metrics.hh +++ b/lily/include/all-font-metrics.hh @@ -23,6 +23,7 @@ */ class All_font_metrics { + Scheme_hash_table *tfm_dict_; Scheme_hash_table *otf_dict_; File_path search_path_; @@ -43,6 +44,7 @@ public: 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; diff --git a/lily/include/audio-element-info.hh b/lily/include/audio-element-info.hh index fd529bfde2..8eed595373 100644 --- a/lily/include/audio-element-info.hh +++ b/lily/include/audio-element-info.hh @@ -19,12 +19,12 @@ class Audio_element_info { public: Audio_element *elem_; - Stream_event *event_; + Music *event_; Translator *origin_trans_; vector origin_contexts (Translator *) const; - Audio_element_info (Audio_element *, Stream_event *); + Audio_element_info (Audio_element *, Music *); Audio_element_info (); }; diff --git a/lily/include/audio-element.hh b/lily/include/audio-element.hh index 2941c7d105..a9d8f7ac47 100644 --- a/lily/include/audio-element.hh +++ b/lily/include/audio-element.hh @@ -16,8 +16,7 @@ class Audio_element 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: }; diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index 11f3cd31f5..1e7bfec32a 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -55,7 +55,7 @@ public: 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 *); @@ -63,7 +63,6 @@ public: Moment length_mom_; int transposing_; Audio_note *tied_; - bool tie_event_; }; class Audio_piano_pedal : public Audio_item diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index 767271ad34..94e1a256d9 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -18,17 +18,10 @@ 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 const &list, Grob *common, Axis); - static Interval relative_pure_height (Grob *me, vector const &list, - Grob *common, int start, int end, - bool use_cache); - static Interval cached_pure_height (Grob *me, vector const &list, - Grob *common, int, int); static void add_element (Grob *me, Grob *); static void set_axes (Grob *, Axis, Axis); diff --git a/lily/include/bar-line.hh b/lily/include/bar-line.hh index 39253a7b8d..4744aef855 100644 --- a/lily/include/bar-line.hh +++ b/lily/include/bar-line.hh @@ -18,7 +18,6 @@ class Bar_line 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)); diff --git a/lily/include/beaming-pattern.hh b/lily/include/beaming-pattern.hh index 5e0c7c30ec..9f2adb1940 100644 --- a/lily/include/beaming-pattern.hh +++ b/lily/include/beaming-pattern.hh @@ -19,14 +19,12 @@ struct Beam_rhythmic_element Drul_array 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 (); }; /* @@ -39,7 +37,6 @@ public: Beaming_pattern (); void beamify (Context*); - void de_grace (); void add_stem (Moment d, int beams); int beamlet_count (int idx, Direction d) const; diff --git a/lily/include/binary-source-file.hh b/lily/include/binary-source-file.hh new file mode 100644 index 0000000000..95d5b644de --- /dev/null +++ b/lily/include/binary-source-file.hh @@ -0,0 +1,27 @@ +// +// binary-source-file.hh -- declare Binary_source_file +// +// (c) 1997--2006 Jan Nieuwenhuizen + +#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 diff --git a/lily/include/book-paper-def.hh b/lily/include/book-paper-def.hh index ee0c4a15a3..55e7a01180 100644 --- a/lily/include/book-paper-def.hh +++ b/lily/include/book-paper-def.hh @@ -18,6 +18,7 @@ class Output_def : public Output_def public: VIRTUAL_COPY_CONSTRUCTOR (Output_def, Output_def); Output_def (Output_def const &); + Output_def (); virtual void derived_mark (); diff --git a/lily/include/book.hh b/lily/include/book.hh index 360276ed08..9ef2ca2130 100644 --- a/lily/include/book.hh +++ b/lily/include/book.hh @@ -15,7 +15,7 @@ #include "object-key.hh" #include "std-string.hh" -class Book +class Book : public Input { DECLARE_SMOBS (Book, foo); @@ -24,11 +24,8 @@ public: 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, diff --git a/lily/include/box.hh b/lily/include/box.hh index b6f933af9b..a8119664b7 100644 --- a/lily/include/box.hh +++ b/lily/include/box.hh @@ -24,7 +24,6 @@ public: Offset center () const; void translate (Offset o); - /// smallest box enclosing #b# void set_empty (); void add_point (Offset); diff --git a/lily/include/break-algorithm.hh b/lily/include/break-algorithm.hh new file mode 100644 index 0000000000..54385d8af6 --- /dev/null +++ b/lily/include/break-algorithm.hh @@ -0,0 +1,38 @@ +/* + break-algorithm.hh -- declare Break_algorithm + + source file of the GNU LilyPond music typesetter + + (c) 1996--2006 Han-Wen Nienhuys +*/ + +#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 const &) const; + +public: + virtual ~Break_algorithm (); + Simple_spacer *(*get_line_spacer) (); + Break_algorithm (); + void set_pscore (Paper_score *); + virtual vector solve (); +}; + +#endif // BREAK_HH + diff --git a/lily/include/constrained-breaking.hh b/lily/include/constrained-breaking.hh index 56c673705d..8f2a4de2ef 100644 --- a/lily/include/constrained-breaking.hh +++ b/lily/include/constrained-breaking.hh @@ -4,22 +4,20 @@ source file of the GNU LilyPond music typesetter - (c) 2006 Joe Neeman + (c) 2006 Han-Wen Nienhuys */ #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_; @@ -32,8 +30,8 @@ struct Line_details { Line_details () { force_ = infinity_f; + extent_ = 0; padding_ = 0; - bottom_padding_ = 0; space_ = 0; inverse_hooke_ = 1; break_permission_ = ly_symbol2scm ("allow"); @@ -43,21 +41,6 @@ struct Line_details { 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); - } }; /* @@ -89,15 +72,14 @@ struct Constrained_break_node /* A dynamic programming solution to breaking scores into lines */ -class Constrained_breaking +class Constrained_breaking : public Break_algorithm { public: vector solve (); - Constrained_breaking (Paper_score *ps); - Constrained_breaking (Paper_score *ps, vector const &start_col_posns); + Constrained_breaking (); + Constrained_breaking (vector const &start_col_posns); - vector get_solution (vsize start, vsize end, vsize sys_count); - vector get_best_solution (vsize start, vsize end); + vector get_solution(vsize start, vsize end, vsize sys_count); vector 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); @@ -105,19 +87,17 @@ public: 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 lines_; + vector 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 > state_; + vector > state_; vector start_; /* the columns at which we might be asked to start breaking */ vector starting_breakpoints_; /* the corresponding index in breaks_ */ @@ -125,10 +105,8 @@ private: vector all_; vector 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); diff --git a/lily/include/context-def.hh b/lily/include/context-def.hh index dd7045015b..8f5ba8686d 100644 --- a/lily/include/context-def.hh +++ b/lily/include/context-def.hh @@ -18,7 +18,7 @@ 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: /* @@ -32,20 +32,16 @@ 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 path_to_acceptable_context (SCM type_string, Output_def *) const; Context *instantiate (SCM extra_ops, Object_key const *); @@ -53,6 +49,7 @@ public: SCM to_alist () const; static SCM make_scm (); + SCM clone_scm () const; void apply_default_property_operations (Context *); private: diff --git a/lily/include/context-handle.hh b/lily/include/context-handle.hh index e32bc29cb7..ea7e255809 100644 --- a/lily/include/context-handle.hh +++ b/lily/include/context-handle.hh @@ -21,6 +21,7 @@ public: Context_handle (); void set_context (Context *); + bool try_music (Music *); void operator = (Context_handle const &); Context_handle (Context_handle const &); Context *get_outlet () const; diff --git a/lily/include/context.hh b/lily/include/context.hh index fd3c75b3f0..5a7eb92687 100644 --- a/lily/include/context.hh +++ b/lily/include/context.hh @@ -9,12 +9,12 @@ #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 { @@ -28,11 +28,10 @@ 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_; @@ -54,28 +53,23 @@ protected: 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_; } @@ -87,27 +81,17 @@ public: /* 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 (); @@ -117,6 +101,7 @@ public: 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); @@ -149,10 +134,10 @@ Rational measure_length (Context const *context); 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 */ diff --git a/lily/include/engraver-group.hh b/lily/include/engraver-group.hh index 3fa99e638e..d1df4cffb3 100644 --- a/lily/include/engraver-group.hh +++ b/lily/include/engraver-group.hh @@ -17,16 +17,12 @@ class Engraver_group : public virtual Translator_group protected: vector announce_infos_; Drul_array 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: diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh index 493c9c98d8..04a7623e3f 100644 --- a/lily/include/engraver.hh +++ b/lily/include/engraver.hh @@ -9,6 +9,7 @@ #ifndef ENGRAVER_HH #define ENGRAVER_HH +#include "music.hh" #include "grob-info.hh" #include "translator.hh" @@ -18,8 +19,6 @@ */ 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: @@ -41,22 +40,18 @@ public: 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 diff --git a/lily/include/font-metric.hh b/lily/include/font-metric.hh index 4217a6e95e..f5d036f972 100644 --- a/lily/include/font-metric.hh +++ b/lily/include/font-metric.hh @@ -22,12 +22,9 @@ public: 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; diff --git a/lily/include/global-context.hh b/lily/include/global-context.hh index 75172595cc..cc87ff3c9b 100644 --- a/lily/include/global-context.hh +++ b/lily/include/global-context.hh @@ -16,29 +16,34 @@ class Global_context : public virtual Context { PQueue 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_; }; diff --git a/lily/include/gourlay-breaking.hh b/lily/include/gourlay-breaking.hh new file mode 100644 index 0000000000..34a92f8dea --- /dev/null +++ b/lily/include/gourlay-breaking.hh @@ -0,0 +1,23 @@ +/* + gourlay-breaking.hh -- declare Gourlay_breaking + + source file of the GNU LilyPond music typesetter + + (c) 1997--2006 Han-Wen Nienhuys +*/ + +#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 solve (); + Gourlay_breaking (); + Real combine_demerits (Column_x_positions const &, Column_x_positions const &) const; +}; +#endif // GOURLAY_BREAKING_HH diff --git a/lily/include/gregorian-ligature-engraver.hh b/lily/include/gregorian-ligature-engraver.hh index 1016993c4c..96b87f84f2 100644 --- a/lily/include/gregorian-ligature-engraver.hh +++ b/lily/include/gregorian-ligature-engraver.hh @@ -12,7 +12,7 @@ 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 @@ -20,8 +20,7 @@ public: 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 primitives); virtual void transform_heads (Spanner *ligature, vector primitives) = 0; diff --git a/lily/include/grob-info.hh b/lily/include/grob-info.hh index b92f033718..4ed3790954 100644 --- a/lily/include/grob-info.hh +++ b/lily/include/grob-info.hh @@ -29,8 +29,8 @@ public: 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 origin_contexts (Translator *) const; Grob_info (Translator *, Grob *); Grob_info (); diff --git a/lily/include/grob.hh b/lily/include/grob.hh index eee95e9b98..6c3ef612bd 100644 --- a/lily/include/grob.hh +++ b/lily/include/grob.hh @@ -80,14 +80,9 @@ public: 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; @@ -114,22 +109,16 @@ public: /* 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 spanned_rank_iv (); }; /* smob utilities */ @@ -151,4 +140,5 @@ void chain_offset_callback (Grob *g, SCM proc, Axis a); SCM axis_offset_symbol (Axis a); SCM axis_parent_positioning (Axis a); + #endif /* GROB_HH */ diff --git a/lily/include/hara-kiri-group-spanner.hh b/lily/include/hara-kiri-group-spanner.hh index 0112b0864f..9533216be8 100644 --- a/lily/include/hara-kiri-group-spanner.hh +++ b/lily/include/hara-kiri-group-spanner.hh @@ -17,11 +17,9 @@ class Hara_kiri_group_spanner 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); }; diff --git a/lily/include/input-smob.hh b/lily/include/input-smob.hh new file mode 100644 index 0000000000..6b80f26832 --- /dev/null +++ b/lily/include/input-smob.hh @@ -0,0 +1,21 @@ +/* + input-smob.hh -- declare input smob + + source file of the GNU LilyPond music typesetter + + (c) 2000--2006 Han-Wen Nienhuys +*/ + +#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 */ + diff --git a/lily/include/input.hh b/lily/include/input.hh index 625910ea74..e1b4169841 100644 --- a/lily/include/input.hh +++ b/lily/include/input.hh @@ -20,23 +20,21 @@ class Input 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; @@ -52,14 +50,4 @@ public: Input (); }; - - -#include "input.hh" -#include "smobs.hh" - -SCM make_input (Input spot); -Input *unsmob_input (SCM); - -extern Input dummy_input_global; - #endif // INPUT_HH diff --git a/lily/include/item.hh b/lily/include/item.hh index 7c28a35240..9d1f2e73f6 100644 --- a/lily/include/item.hh +++ b/lily/include/item.hh @@ -30,7 +30,6 @@ public: static bool is_non_musical (Grob *); bool is_broken () const; - bool pure_is_visible (int start, int end) const; Direction break_status_dir () const; @@ -39,7 +38,6 @@ public: virtual System *get_system () const; virtual Paper_column *get_column () const; virtual void handle_prebroken_dependencies (); - virtual Interval_t spanned_rank_iv (); static bool has_interface (Grob *); protected: virtual void discretionary_processing (); diff --git a/lily/include/kpath.hh b/lily/include/kpath.hh index f71d891537..baffaf1ffc 100644 --- a/lily/include/kpath.hh +++ b/lily/include/kpath.hh @@ -12,6 +12,7 @@ #include "std-string.hh" string kpathsea_find_tfm (char const *name); +void initialize_kpathsea (char *av0); #endif /* KPATH_HH */ diff --git a/lily/include/ligature-engraver.hh b/lily/include/ligature-engraver.hh index 2ae5cb4fe9..c70523ae91 100644 --- a/lily/include/ligature-engraver.hh +++ b/lily/include/ligature-engraver.hh @@ -21,7 +21,7 @@ protected: 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, @@ -34,7 +34,7 @@ public: // class is abstract private: - Drul_array events_drul_; + Drul_array events_drul_; Spanner *ligature_; vector primitives_; @@ -42,7 +42,7 @@ private: Spanner *finished_ligature_; vector finished_primitives_; - Stream_event *prev_start_event_; + Music *prev_start_event_; // moment where ligature started. Moment ligature_start_mom_; diff --git a/lily/include/lily-guile-macros.hh b/lily/include/lily-guile-macros.hh index 87ceb88a7c..ef0db47479 100644 --- a/lily/include/lily-guile-macros.hh +++ b/lily/include/lily-guile-macros.hh @@ -21,31 +21,20 @@ #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; \ @@ -54,10 +43,10 @@ scm_or_str2symbol (SCM s) { 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 @@ -99,14 +88,14 @@ inline SCM ly_symbol2scm (char const *x) { return scm_str2symbol ((x)); } 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); \ } \ @@ -114,9 +103,6 @@ string mangle_cxx_identifier (string); 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, @@ -164,13 +150,7 @@ ly_add_function_documentation (SCM proc, char const *fname, #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 */ diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 07abff74ef..98e7ceadcf 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -64,7 +64,6 @@ Drul_array robust_scm2drul (SCM, Drul_array); Drul_array robust_scm2booldrul (SCM, Drul_array); Interval robust_scm2interval (SCM, Drul_array); 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); @@ -77,7 +76,7 @@ SCM alist_to_hashq (SCM); 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 */ diff --git a/lily/include/lily-lexer.hh b/lily/include/lily-lexer.hh index b22038fbeb..d0a188ab69 100644 --- a/lily/include/lily-lexer.hh +++ b/lily/include/lily-lexer.hh @@ -34,9 +34,7 @@ private: Keyword_table *keytable_; SCM scopes_; SCM start_module_; - int hidden_state_; public: - vector extra_token_types_; string main_input_name_; void *lexval; Input *lexloc; @@ -69,7 +67,6 @@ public: 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 (); @@ -79,7 +76,6 @@ public: 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; diff --git a/lily/include/listener.hh b/lily/include/listener.hh index 562380c576..fd7a7e2adf 100644 --- a/lily/include/listener.hh +++ b/lily/include/listener.hh @@ -63,8 +63,6 @@ class Listener { 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 @@ -74,29 +72,29 @@ public: }; 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); \ diff --git a/lily/include/ly-smobs.icc b/lily/include/ly-smobs.icc index 99c09fc043..2475b8ca75 100644 --- a/lily/include/ly-smobs.icc +++ b/lily/include/ly-smobs.icc @@ -74,8 +74,8 @@ void \ CL::smobify_self () \ { \ - protection_cons_ = SCM_EOL; \ self_scm_ = unprotected_smobify_self (); \ + protection_cons_ = SCM_EOL; \ protect (); \ } \ void \ @@ -86,7 +86,7 @@ SCM \ CL::unprotect () \ { \ - unprotect_smob (self_scm_, &protection_cons_); \ + unprotect_smob (&protection_cons_); \ return self_scm_; \ } \ SCM \ diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index 6ec530f68c..ba3f2c0a9a 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -29,16 +29,8 @@ public: 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 (); }; /** @@ -91,7 +83,7 @@ public: /** Change instrument event */ -class Midi_instrument : public Midi_channel_item +class Midi_instrument : public Midi_item { public: Midi_instrument (Audio_instrument *); @@ -128,7 +120,7 @@ public: /** Turn a note on. */ -class Midi_note : public Midi_channel_item +class Midi_note : public Midi_item { public: Midi_note (Audio_note *); @@ -141,8 +133,7 @@ public: Audio_note *audio_; - - static int const c0_pitch_ = 60; + static int const c0_pitch_i_ = 60; Byte dynamic_byte_; }; @@ -178,7 +169,7 @@ public: Audio_text *audio_; }; -class Midi_dynamic : public Midi_channel_item +class Midi_dynamic : public Midi_item { public: Midi_dynamic (Audio_dynamic *); @@ -189,7 +180,7 @@ public: 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 *); diff --git a/lily/include/midi-walker.hh b/lily/include/midi-walker.hh index 2d17efbc60..a01add8f1e 100644 --- a/lily/include/midi-walker.hh +++ b/lily/include/midi-walker.hh @@ -26,8 +26,7 @@ int compare (Midi_note_event const &left, Midi_note_event const &right); 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 (); @@ -39,7 +38,6 @@ private: 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_; diff --git a/lily/include/modified-font-metric.hh b/lily/include/modified-font-metric.hh index 7d1487d933..c5e6d3c5bf 100644 --- a/lily/include/modified-font-metric.hh +++ b/lily/include/modified-font-metric.hh @@ -16,7 +16,6 @@ struct Modified_font_metric : public Font_metric { 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); diff --git a/lily/include/moment.hh b/lily/include/moment.hh index ac895e99eb..f0c6fbb21b 100644 --- a/lily/include/moment.hh +++ b/lily/include/moment.hh @@ -50,7 +50,6 @@ public: static int compare (Moment const &, Moment const &); SCM as_scheme () const; }; - IMPLEMENT_ARITHMETIC_OPERATOR (Moment, +); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, -); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, /); diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh index 4078ec655b..3c62205b90 100644 --- a/lily/include/music-iterator.hh +++ b/lily/include/music-iterator.hh @@ -65,7 +65,7 @@ public: 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 (); diff --git a/lily/include/music.hh b/lily/include/music.hh index c307d07ff9..3c43209b47 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -29,8 +29,6 @@ public: 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); @@ -48,7 +46,7 @@ public: 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; @@ -64,7 +62,4 @@ Music *make_music_by_name (SCM sym); 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 */ diff --git a/lily/include/note-column.hh b/lily/include/note-column.hh index ec12414539..5085ee52eb 100644 --- a/lily/include/note-column.hh +++ b/lily/include/note-column.hh @@ -19,7 +19,7 @@ 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); diff --git a/lily/include/optimal-page-breaking.hh b/lily/include/optimal-page-breaking.hh deleted file mode 100644 index 8737e7e5a8..0000000000 --- a/lily/include/optimal-page-breaking.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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 -*/ - -#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 */ diff --git a/lily/include/output-def.hh b/lily/include/output-def.hh index a31dcd48fc..7d5563d474 100644 --- a/lily/include/output-def.hh +++ b/lily/include/output-def.hh @@ -42,7 +42,6 @@ class Output_def public: VIRTUAL_COPY_CONSTRUCTOR (Output_def, Output_def); DECLARE_SMOBS (Output_def, ); - public: SCM scope_; Output_def *parent_; @@ -68,6 +67,9 @@ SCM get_font_table (Output_def *def); 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); diff --git a/lily/include/page-breaking.hh b/lily/include/page-breaking.hh deleted file mode 100644 index 548100ca8b..0000000000 --- a/lily/include/page-breaking.hh +++ /dev/null @@ -1,130 +0,0 @@ -/* - 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 -*/ - -#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 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 lines_per_page, SCM lines); - - vsize min_system_count (vsize start, vsize end); - vsize max_system_count (vsize start, vsize end); - vector 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_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 breaks_; - -private: - vector chunks_; - vector all_; - vector line_breaking_; - - vector chunk_list (vsize start, vsize end); - Line_division system_count_bounds (vector 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 *result, - Line_division *cur); - - void create_system_list (); - void find_chunks_and_breaks (Break_predicate); -}; -#endif /* PAGE_BREAKING_HH */ diff --git a/lily/include/page-spacing.hh b/lily/include/page-spacing.hh deleted file mode 100644 index f64df2c8a2..0000000000 --- a/lily/include/page-spacing.hh +++ /dev/null @@ -1,93 +0,0 @@ -/* - page-spacing.hh -- routines for spacing systems - vertically across pages - - source file of the GNU LilyPond music typesetter - - (c) 2006 Joe Neeman -*/ - -#ifndef PAGE_SPACING_HH -#define PAGE_SPACING_HH - -#include "constrained-breaking.hh" - -struct Spacing_result { - vector systems_per_page_; - vector 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 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 lines_; - Matrix 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 const &lines, - Real page_height, bool ragged, bool ragged_last); - -Spacing_result -space_systems_on_n_pages (vector const&, - vsize n, - Real page_height, - bool ragged, - bool ragged_last); - -Spacing_result -space_systems_on_n_or_one_more_pages (vector const&, - vsize n, - Real page_height, - Real odd_pages_penalty, - bool ragged, - bool ragged_last); -Spacing_result -space_systems_on_best_pages (vector const&, - Real page_height, - Real odd_pages_penalty, - bool ragged, - bool ragged_last); - -#endif /* PAGE_SPACING_HH */ diff --git a/lily/include/page-turn-page-breaking.hh b/lily/include/page-turn-page-breaking.hh deleted file mode 100644 index 1706437908..0000000000 --- a/lily/include/page-turn-page-breaking.hh +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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 -*/ - -#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 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 state_; - - vsize final_page_num (Break_node const &b); - Break_node put_systems_on_pages (vsize start, - vsize end, - vector const &lines, - Line_division const &div, - int page_number); - - SCM make_lines (vector *breaks); - SCM make_pages (vector const &breaks, SCM systems); - - Real calc_demerits (Break_node const &me); - void calc_subproblem (vsize i); -}; -#endif /* PAGE_TURN_PAGE_BREAKING_HH */ diff --git a/lily/include/pango-font.hh b/lily/include/pango-font.hh index 9e330faeab..dc21ccf684 100644 --- a/lily/include/pango-font.hh +++ b/lily/include/pango-font.hh @@ -39,15 +39,11 @@ public: 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; }; diff --git a/lily/include/paper-column-engraver.hh b/lily/include/paper-column-engraver.hh index 1dd227e209..f850613bdd 100644 --- a/lily/include/paper-column-engraver.hh +++ b/lily/include/paper-column-engraver.hh @@ -10,9 +10,6 @@ #define PAPER_COLUMN_ENGRAVER_HH #include "engraver.hh" -#include "listener.hh" -#include "moment.hh" -#include "stream-event.hh" class Paper_column_engraver : public Engraver { @@ -20,24 +17,20 @@ 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 break_events_; + vector break_events_; int breaks_; // used for stat printing Paper_column *command_column_; Paper_column *musical_column_; @@ -45,6 +38,8 @@ protected: bool first_; Moment last_moment_; + Moment last_breakable_moment_; + Paper_column *last_breakable_column_; public: }; diff --git a/lily/include/paper-column.hh b/lily/include/paper-column.hh index 6adbdbe179..6ef3daacc4 100644 --- a/lily/include/paper-column.hh +++ b/lily/include/paper-column.hh @@ -29,12 +29,6 @@ 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); diff --git a/lily/include/paper-score.hh b/lily/include/paper-score.hh index 7f79aeb548..c165b9aacd 100644 --- a/lily/include/paper-score.hh +++ b/lily/include/paper-score.hh @@ -19,9 +19,6 @@ class Paper_score : public Music_output System *system_; SCM systems_; SCM paper_systems_; - - mutable vector cols_; - mutable vector break_indices_; public: Paper_score (Output_def *); @@ -33,8 +30,6 @@ public: void typeset_system (System *); vector calc_breaking (); vector find_break_indices () const; - vector get_break_indices () const; - vector get_columns () const; SCM get_paper_systems (); protected: virtual void process (); diff --git a/lily/include/percent-repeat-iterator.hh b/lily/include/percent-repeat-iterator.hh new file mode 100644 index 0000000000..8637d9f7ae --- /dev/null +++ b/lily/include/percent-repeat-iterator.hh @@ -0,0 +1,25 @@ +/* + percent-repeat-iterator.hh -- declare Percent_repeat_iterator + + source file of the GNU LilyPond music typesetter + + (c) 2001--2006 Han-Wen Nienhuys +*/ + +#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 */ diff --git a/lily/include/performer-group.hh b/lily/include/performer-group.hh index 94eceaecde..f5c1256a22 100644 --- a/lily/include/performer-group.hh +++ b/lily/include/performer-group.hh @@ -20,10 +20,14 @@ public: void do_announces (); virtual void announce_element (Audio_element_info); + virtual void play_element (Audio_element *p); + virtual int get_tempo () const; protected: vector announce_infos_; - virtual void acknowledge_audio_elements (); + +private: + void acknowledge_audio_elements (); }; void performer_each (SCM list, Performer_method method); diff --git a/lily/include/performer.hh b/lily/include/performer.hh index 4eab36a332..658a822b03 100644 --- a/lily/include/performer.hh +++ b/lily/include/performer.hh @@ -25,6 +25,8 @@ protected: 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 */ diff --git a/lily/include/pitch.hh b/lily/include/pitch.hh index 2ebbb71a41..57cb076b52 100644 --- a/lily/include/pitch.hh +++ b/lily/include/pitch.hh @@ -12,17 +12,6 @@ #include "lily-proto.hh" #include "smobs.hh" -#include "std-vector.hh" - -struct Scale -{ - vector 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. @@ -45,8 +34,7 @@ private: // fixme int notename_; int alteration_; int octave_; - Scale *scale_; - + void transpose (Pitch); void up_to (int); void down_to (int); @@ -96,7 +84,6 @@ INSTANTIATE_COMPARE (Pitch, Pitch::compare); extern SCM pitch_less_proc; Pitch pitch_interval (Pitch const &from, Pitch const &to); -extern Scale *default_global_scale; #endif /* MUSICAL_PITCH_HH */ diff --git a/lily/include/prob.hh b/lily/include/prob.hh index 0b82c4629e..141aba49b3 100644 --- a/lily/include/prob.hh +++ b/lily/include/prob.hh @@ -40,12 +40,7 @@ public: 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); diff --git a/lily/include/score-context.hh b/lily/include/score-context.hh new file mode 100644 index 0000000000..349c768696 --- /dev/null +++ b/lily/include/score-context.hh @@ -0,0 +1,24 @@ +/* + score-context.hh -- declare Score_context + + source file of the GNU LilyPond music typesetter + + (c) 2004--2006 Han-Wen Nienhuys +*/ +#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 */ diff --git a/lily/include/score-engraver.hh b/lily/include/score-engraver.hh index d2de464f60..7657114536 100644 --- a/lily/include/score-engraver.hh +++ b/lily/include/score-engraver.hh @@ -10,8 +10,10 @@ #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_; @@ -21,13 +23,13 @@ class Score_engraver : public Engraver_group 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); @@ -40,6 +42,7 @@ protected: public: Score_engraver (); + virtual SCM get_output (); }; #endif /* SCORE_ENGRAVER_HH */ diff --git a/lily/include/score-performer.hh b/lily/include/score-performer.hh index 929853bba0..e38f430c62 100644 --- a/lily/include/score-performer.hh +++ b/lily/include/score-performer.hh @@ -8,33 +8,31 @@ #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 &); diff --git a/lily/include/score-translator.hh b/lily/include/score-translator.hh new file mode 100644 index 0000000000..b74fb0fe22 --- /dev/null +++ b/lily/include/score-translator.hh @@ -0,0 +1,25 @@ +/* + score-translator.hh -- declare Score_translator + + source file of the GNU LilyPond music typesetter + + (c) 2004--2006 Han-Wen Nienhuys +*/ + +#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 */ + diff --git a/lily/include/score.hh b/lily/include/score.hh index fcc5752e52..004e251dd9 100644 --- a/lily/include/score.hh +++ b/lily/include/score.hh @@ -17,15 +17,13 @@ #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 defs_; string user_key_; SCM header_; @@ -34,7 +32,6 @@ public: Score (); Score (Score const &); - VIRTUAL_COPY_CONSTRUCTOR (Score, Score); SCM get_music () const; void add_output_def (Output_def *def); diff --git a/lily/include/semi-tie.hh b/lily/include/semi-tie.hh index ec63c627ef..d0a0baf5b7 100644 --- a/lily/include/semi-tie.hh +++ b/lily/include/semi-tie.hh @@ -20,8 +20,8 @@ struct Semi_tie 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 *); }; diff --git a/lily/include/sequential-music-iterator.hh b/lily/include/sequential-music-iterator.hh new file mode 100644 index 0000000000..a70d7bcd40 --- /dev/null +++ b/lily/include/sequential-music-iterator.hh @@ -0,0 +1,26 @@ +/* + Sequential_music-iterator.hh -- declare Sequential_music_iterator + + source file of the GNU LilyPond music typesetter + + (c) 1997--2006 Han-Wen Nienhuys +*/ + +#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 diff --git a/lily/include/side-position-interface.hh b/lily/include/side-position-interface.hh index 36b1e8fdf5..6c6e483066 100644 --- a/lily/include/side-position-interface.hh +++ b/lily/include/side-position-interface.hh @@ -22,15 +22,12 @@ struct Side_position_interface 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 *); diff --git a/lily/include/simple-spacer.hh b/lily/include/simple-spacer.hh index 758cd65b32..47e8080ced 100644 --- a/lily/include/simple-spacer.hh +++ b/lily/include/simple-spacer.hh @@ -45,11 +45,11 @@ public: 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 spring_positions () const; - Real force () const; - bool fits () const; + Real force (); + bool fits (); DECLARE_SIMPLE_SMOBS (Simple_spacer,); @@ -67,6 +67,7 @@ private: /* returns a vector of dimensions breaks.size () * breaks.size () */ vector get_line_forces (vector const &columns, + vector breaks, Real line_len, Real indent, bool ragged); diff --git a/lily/include/slur-configuration.hh b/lily/include/slur-configuration.hh index fa61e42b14..b1b9f9a6e5 100644 --- a/lily/include/slur-configuration.hh +++ b/lily/include/slur-configuration.hh @@ -13,17 +13,6 @@ #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_; @@ -33,7 +22,7 @@ public: Drul_array attachment_; Bezier curve_; Real height_; - unsigned tags_; + int index_; Slur_configuration (); diff --git a/lily/include/slur.hh b/lily/include/slur.hh index f0213372bc..2c797239ce 100644 --- a/lily/include/slur.hh +++ b/lily/include/slur.hh @@ -23,7 +23,6 @@ public: 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 *); diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh index dd384786ed..be08a073b0 100644 --- a/lily/include/smobs.hh +++ b/lily/include/smobs.hh @@ -138,7 +138,7 @@ #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 */ diff --git a/lily/include/source-file.hh b/lily/include/source-file.hh index 21060e3704..dd88a2c65a 100644 --- a/lily/include/source-file.hh +++ b/lily/include/source-file.hh @@ -12,7 +12,7 @@ #include "flower-proto.hh" #include "std-vector.hh" #include "lily-proto.hh" -#include "smobs.hh" +#include "protected-scm.hh" #include using namespace std; @@ -27,43 +27,58 @@ using namespace std; class Source_file { - vector newline_locations_; - istream *istream_; - vector 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 newline_locations_; + istream *istream_; + char *contents_str0_; + vector chs_; + int length_; + void load_stdin (); + void init_port (); + + Protected_scm str_port_; }; -vector gulp_file (string fn, int desired); +char *gulp_file (string fn, int *len); #endif /* SOURCE_FILE_HH */ diff --git a/lily/include/spacing-spanner.hh b/lily/include/spacing-spanner.hh index f39ea98bc3..7f560e2880 100644 --- a/lily/include/spacing-spanner.hh +++ b/lily/include/spacing-spanner.hh @@ -19,14 +19,13 @@ struct Spacing_options 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; }; /* @@ -45,6 +44,7 @@ public: 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 const &); static Rational effective_shortest_duration (Grob *me, vector const &all); static void breakable_column_spacing (Grob *, Item *l, Item *r, Spacing_options const *); static void prune_loose_columns (Grob *, vector *cols, Spacing_options const *); @@ -52,10 +52,7 @@ public: static void set_implicit_neighbor_columns (vector const &cols); static void generate_springs (Grob *me, vector const &cols, Spacing_options const *); static void musical_column_spacing (Grob *, Item *, Item *, Spacing_options const *); - static vector get_columns (Spanner *me); - DECLARE_SCHEME_CALLBACK (set_springs, (SCM)); - DECLARE_SCHEME_CALLBACK (calc_common_shortest_duration, (SCM)); static bool has_interface (Grob *); }; diff --git a/lily/include/spanner.hh b/lily/include/spanner.hh index 91153b79b8..c64c61d636 100644 --- a/lily/include/spanner.hh +++ b/lily/include/spanner.hh @@ -45,7 +45,8 @@ public: void substitute_one_mutable_property (SCM sym, SCM val); bool fast_substitute_grob_array (SCM sym, Grob_array *); - virtual Interval_t spanned_rank_iv (); + // TODO: make virtual and do this for Items as well. + Interval_t spanned_rank_iv (); void set_bound (Direction d, Grob *); Item *get_bound (Direction d) const; @@ -56,7 +57,6 @@ public: 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 *); diff --git a/lily/include/staff-symbol-engraver.hh b/lily/include/staff-symbol-engraver.hh new file mode 100644 index 0000000000..08bdc23bd5 --- /dev/null +++ b/lily/include/staff-symbol-engraver.hh @@ -0,0 +1,40 @@ +/* + staff-symbol-engraver.hh -- declare Staff_symbol_engraver + + source file of the GNU LilyPond music typesetter + + (c) 2005--2006 Han-Wen Nienhuys +*/ + +#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 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 */ diff --git a/lily/include/staff-symbol-referencer.hh b/lily/include/staff-symbol-referencer.hh index 1b4c096b8e..5e1fd878fd 100644 --- a/lily/include/staff-symbol-referencer.hh +++ b/lily/include/staff-symbol-referencer.hh @@ -40,7 +40,6 @@ public: 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 */ diff --git a/lily/include/stem-tremolo.hh b/lily/include/stem-tremolo.hh index 49b5fd4c5c..731d2462d3 100644 --- a/lily/include/stem-tremolo.hh +++ b/lily/include/stem-tremolo.hh @@ -22,8 +22,7 @@ public: 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); }; diff --git a/lily/include/stem.hh b/lily/include/stem.hh index 3d06bca6f6..da024edb35 100644 --- a/lily/include/stem.hh +++ b/lily/include/stem.hh @@ -50,7 +50,6 @@ public: 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 diff --git a/lily/include/stream-event.hh b/lily/include/stream-event.hh index 4e1688f6f4..13535c73f6 100644 --- a/lily/include/stream-event.hh +++ b/lily/include/stream-event.hh @@ -13,28 +13,33 @@ #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 */ diff --git a/lily/include/tfm-reader.hh b/lily/include/tfm-reader.hh new file mode 100644 index 0000000000..91433ad7af --- /dev/null +++ b/lily/include/tfm-reader.hh @@ -0,0 +1,44 @@ +/* + tfm-reader.hh -- declare Tex_font_metric_reader + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Jan Nieuwenhuizen + + + 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 *ligatures, + vector *kerns); + + Binary_source_file input_; + +public: + Tex_font_metric_reader (string name); + + Tfm_info info_; + Tfm_header header_; + vector char_metrics_; + vector ascii_to_metric_idx_; +}; + +#endif /* TFM_READER_HH */ + diff --git a/lily/include/tfm.hh b/lily/include/tfm.hh new file mode 100644 index 0000000000..4aa4845d7d --- /dev/null +++ b/lily/include/tfm.hh @@ -0,0 +1,173 @@ +/* + tfm.hh -- declare Tex_font_metric + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Jan Nieuwenhuizen + + + 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 kerns_; + vector 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 char_metrics_; + vector 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 */ + diff --git a/lily/include/tie.hh b/lily/include/tie.hh index 7f96b826cf..5b3706dafd 100644 --- a/lily/include/tie.hh +++ b/lily/include/tie.hh @@ -33,8 +33,8 @@ public: 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); }; diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh index 45a7c77030..3bb6b4255f 100644 --- a/lily/include/translator-group.hh +++ b/lily/include/translator-group.hh @@ -47,24 +47,20 @@ private: 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 (); @@ -78,6 +74,7 @@ public: Context *context () const { return context_; } protected: SCM simple_trans_list_; + SCM accept_hash_table_; Context *context_; friend class Context_def; diff --git a/lily/include/translator.hh b/lily/include/translator.hh index 14ff0b31a1..398a32ce06 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -16,7 +16,6 @@ #include "input.hh" #include "smobs.hh" #include "std-vector.hh" -#include "protected-scm.hh" struct Acknowledge_information { @@ -24,21 +23,7 @@ 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); \ @@ -57,21 +42,8 @@ private: \ } \ 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: @@ -108,19 +80,16 @@ public: 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); @@ -128,16 +97,13 @@ public: 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 diff --git a/lily/include/translator.icc b/lily/include/translator.icc index fa2e2842bb..14ba2b62b6 100644 --- a/lily/include/translator.icc +++ b/lily/include/translator.icc @@ -9,7 +9,6 @@ #ifndef TRANSLATOR_ICC #define TRANSLATOR_ICC -#include "listener.hh" #include "std-vector.hh" #include "translator.hh" @@ -17,7 +16,6 @@ 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 () \ { \ @@ -60,7 +58,7 @@ 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); \ @@ -119,40 +117,6 @@ generic_get_acknowledger (SCM sym, } \ 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 */ + diff --git a/lily/input-scheme.cc b/lily/input-scheme.cc index c24d2ed1b0..6e954ef162 100644 --- a/lily/input-scheme.cc +++ b/lily/input-scheme.cc @@ -7,7 +7,7 @@ */ #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. */ diff --git a/lily/input-smob.cc b/lily/input-smob.cc index 7f66bcd3d3..e3bc5d275d 100644 --- a/lily/input-smob.cc +++ b/lily/input-smob.cc @@ -6,8 +6,8 @@ (c) 2000--2006 Han-Wen Nienhuys */ -#include "input.hh" -#include "source-file.hh" +#include "input-smob.hh" + #include "std-string.hh" #include "ly-smobs.icc" @@ -18,13 +18,8 @@ Input dummy_input_global; 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; } diff --git a/lily/input.cc b/lily/input.cc index 5ab2be4c78..1379f1c7b5 100644 --- a/lily/input.cc +++ b/lily/input.cc @@ -75,15 +75,6 @@ Input::message (string s) const ::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 { diff --git a/lily/instrument-name-engraver.cc b/lily/instrument-name-engraver.cc index 000058d629..a2bf75a777 100644 --- a/lily/instrument-name-engraver.cc +++ b/lily/instrument-name-engraver.cc @@ -25,83 +25,55 @@ public: protected: Spanner *text_spanner_; - SCM long_text_; - SCM short_text_; - - vector 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 (info.grob ()) + if (text_spanner_ + && dynamic_cast (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); } } @@ -110,32 +82,21 @@ Instrument_name_engraver::finalize () { 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" @@ -154,11 +115,7 @@ ADD_TRANSLATOR (Instrument_name_engraver, "", /* read */ - "currentCommandColumn " - "shortInstrumentName " - "instrumentName " - "shortVocalName " - "vocalName " - , + "vocNam vocalName instrument instr " + "currentCommandColumn", /* write */ ""); diff --git a/lily/instrument-switch-engraver.cc b/lily/instrument-switch-engraver.cc deleted file mode 100644 index 67a6803a0e..0000000000 --- a/lily/instrument-switch-engraver.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - instrument-switch-engraver.cc -- implement - - source file of the GNU LilyPond music typesetter - - (c) 2006 Han-Wen Nienhuys - -*/ - -#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", - - ""); diff --git a/lily/item.cc b/lily/item.cc index ff00630b5f..f4760eb2fd 100644 --- a/lily/item.cc +++ b/lily/item.cc @@ -8,7 +8,6 @@ #include "item.hh" -#include "axis-group-interface.hh" #include "paper-score.hh" #include "warn.hh" #include "paper-column.hh" @@ -150,37 +149,13 @@ Item::handle_prebroken_dependencies () 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 -Item::spanned_rank_iv () -{ - int c = get_column ()->get_rank (); - return Interval_t (c, c); -} - void Item::derived_mark () const { diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc index f936283233..b0a87988a4 100644 --- a/lily/key-engraver.cc +++ b/lily/key-engraver.cc @@ -6,15 +6,14 @@ (c) 1997--2006 Han-Wen Nienhuys */ +#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" @@ -28,9 +27,9 @@ 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: @@ -39,10 +38,10 @@ 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); }; @@ -112,13 +111,20 @@ Key_engraver::create_key (bool is_default) } } -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 @@ -156,7 +162,7 @@ Key_engraver::stop_translation_timestep () } 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)) diff --git a/lily/key-performer.cc b/lily/key-performer.cc index df98520a1a..26dbe93a8d 100644 --- a/lily/key-performer.cc +++ b/lily/key-performer.cc @@ -6,14 +6,11 @@ (c) 1997--2006 Jan Nieuwenhuizen */ -#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: @@ -21,12 +18,12 @@ 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_; }; @@ -83,18 +80,22 @@ Key_performer::stop_translation_timestep () { 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", diff --git a/lily/keyword.cc b/lily/keyword.cc index b5f7947ada..84065ab4f6 100644 --- a/lily/keyword.cc +++ b/lily/keyword.cc @@ -9,9 +9,9 @@ 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) @@ -19,7 +19,7 @@ Keyword_table::Keyword_table (Keyword_ent *tab) while (tab->name_) table_.push_back (*tab++); - vector_sort (table_, tab_less); + vector_sort (table_, tabcmp); } vsize @@ -27,7 +27,7 @@ Keyword_table::lookup (char const *s) const { 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; diff --git a/lily/laissez-vibrer-engraver.cc b/lily/laissez-vibrer-engraver.cc index cfc331da0c..4568dd19e4 100644 --- a/lily/laissez-vibrer-engraver.cc +++ b/lily/laissez-vibrer-engraver.cc @@ -11,20 +11,20 @@ #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 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); }; @@ -43,11 +43,11 @@ Laissez_vibrer_engraver::stop_translation_timestep () 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 @@ -71,6 +71,8 @@ Laissez_vibrer_engraver::acknowledge_note_head (Grob_info inf) lv_ties_.push_back (lv_tie); } + + ADD_ACKNOWLEDGER (Laissez_vibrer_engraver, note_head); ADD_TRANSLATOR (Laissez_vibrer_engraver, /* doc */ "Create Laissez vibrer items.", diff --git a/lily/least-squares.cc b/lily/least-squares.cc index 2e0bcab3c6..c7ca185bbf 100644 --- a/lily/least-squares.cc +++ b/lily/least-squares.cc @@ -28,23 +28,22 @@ minimise_least_squares (Real *coef, Real *offset, 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; } } diff --git a/lily/ledger-line-engraver.cc b/lily/ledger-line-engraver.cc index 55c6b4bef1..550dc5a014 100644 --- a/lily/ledger-line-engraver.cc +++ b/lily/ledger-line-engraver.cc @@ -14,8 +14,7 @@ class Ledger_line_engraver : public Engraver { Spanner *span_; - vector ledgered_grobs_; - + public: TRANSLATOR_DECLARATIONS (Ledger_line_engraver); @@ -28,7 +27,6 @@ protected: void start_spanner (); void stop_spanner (); - void stop_translation_timestep (); }; Ledger_line_engraver::Ledger_line_engraver () @@ -40,26 +38,9 @@ void 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 @@ -95,7 +76,8 @@ Ledger_line_engraver::acknowledge_staff_symbol (Grob_info s) Spanner *sym = dynamic_cast (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 (); @@ -105,7 +87,12 @@ Ledger_line_engraver::acknowledge_staff_symbol (Grob_info s) 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" diff --git a/lily/lexer.ll b/lily/lexer.ll index 04a279b4ca..d69dbb5ffd 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -43,7 +43,6 @@ using namespace std; #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" @@ -61,6 +60,7 @@ RH 7 fix (?) 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); @@ -103,7 +103,6 @@ SCM (* scm_parse_error_handler) (void *); %option never-interactive %option warn -%x extratoken %x chords %x figures %x incl @@ -113,7 +112,6 @@ SCM (* scm_parse_error_handler) (void *); %x markup %x notes %x quote -%x sourcefileline %x sourcefilename %x version @@ -121,7 +119,6 @@ A [a-zA-Z] AA {A}|_ N [0-9] AN {AA}|{N} -ANY_CHAR (.|\n) PUNCT [?!:'`] ACCENT \\[`'"^] NATIONAL [\001-\006\021-\027\031\036\200-\377] @@ -155,22 +152,6 @@ BOM_UTF8 \357\273\277 // windows-suck-suck-suck } -{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; -} - {BOM_UTF8} { if (this->lexloc->line_number () != 1 || this->lexloc->column_number () != 0) { @@ -198,33 +179,22 @@ BOM_UTF8 \357\273\277 } } -{ - \" { - start_quote (); - } -} - \\version{WHITE}* { yy_push_state (version); } \\sourcefilename{WHITE}* { yy_push_state (sourcefilename); } -\\sourcefileline{WHITE}* { - yy_push_state (sourcefileline); -} \"[^"]*\" { /* 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); } \"[^"]*\" { @@ -240,16 +210,6 @@ BOM_UTF8 \357\273\277 scm_makfrom0str (s.c_str ())); } - -{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); -} - . { LexerError (_ ("quoted string expected after \\version").c_str ()); yy_pop_state (); @@ -258,10 +218,6 @@ BOM_UTF8 \357\273\277 LexerError (_ ("quoted string expected after \\sourcefilename").c_str ()); yy_pop_state (); } -. { - LexerError (_ ("integer expected after \\sourcefileline").c_str ()); - yy_pop_state (); -} { [^\%]* { } @@ -357,26 +313,16 @@ BOM_UTF8 \357\273\277 } yylval.scm = sval; - return SCM_TOKEN; + return SCM_T; } { - \<\< { + \<\< { return DOUBLE_ANGLE_OPEN; } - \>\> { + \>\> { return DOUBLE_ANGLE_CLOSE; } } - -{ - \< { - return ANGLE_OPEN; - } - \> { - return ANGLE_CLOSE; - } -} - { _ { return FIGURE_SPACE; @@ -414,9 +360,15 @@ BOM_UTF8 \357\273\277 yylval.i = String_convert::dec2int (string (YYText () +1)); return E_UNSIGNED; } + \" { + start_quote (); + } } -{ +\" { + start_quote (); +} +{ \\{ESCAPED} { *yylval.string += to_string (escaped_char (YYText ()[1])); } @@ -431,7 +383,28 @@ BOM_UTF8 \357\273\277 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 (); + } +} +{ + \\{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 (); @@ -490,6 +463,9 @@ BOM_UTF8 \357\273\277 yylval.i = String_convert::dec2int (string (YYText ())); return UNSIGNED; } + \" { + start_quote (); + } - { return CHORD_MINUS; } @@ -512,6 +488,9 @@ BOM_UTF8 \357\273\277 { + \" { + start_quote (); + } \\score { return SCORE; } @@ -569,7 +548,7 @@ BOM_UTF8 \357\273\277 } } -<*><> { +<> { if (is_main_input_) { is_main_input_ = false; @@ -665,20 +644,6 @@ BOM_UTF8 \357\273\277 %% -/* 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) { @@ -722,7 +687,6 @@ Lily_lexer::pop_state () { if (YYSTATE == notes || YYSTATE == chords) pitchname_tab_stack_ = scm_cdr (pitchname_tab_stack_); - yy_pop_state (); } @@ -751,20 +715,7 @@ Lily_lexer::scan_escaped_word (string str) 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) @@ -808,37 +759,28 @@ Lily_lexer::scan_bare_word (string str) 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; } /* @@ -936,6 +878,59 @@ lookup_markup_command (string s) 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 diff --git a/lily/ligature-engraver.cc b/lily/ligature-engraver.cc index 9922ca1c48..87db230110 100644 --- a/lily/ligature-engraver.cc +++ b/lily/ligature-engraver.cc @@ -12,8 +12,8 @@ #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" @@ -78,11 +78,16 @@ Ligature_engraver::Ligature_engraver () 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 @@ -189,7 +194,7 @@ Ligature_engraver::acknowledge_note_head (Grob_info info) 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); } @@ -201,7 +206,7 @@ Ligature_engraver::acknowledge_rest (Grob_info info) { 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? diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index e1a0e9bffd..e44e47f4be 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -105,8 +105,10 @@ gulp_file_to_string (string fn, bool must_exist, int size) if (be_verbose_global) progress_indication ("[" + s); - vector 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 ("]"); @@ -129,7 +131,7 @@ ly_scm2string (SCM str) { 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 * @@ -653,14 +655,6 @@ robust_scm2offset (SCM k, Offset o) 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) { @@ -748,4 +742,3 @@ mangle_cxx_identifier (string cxx_id) cxx_id = replace_all (cxx_id, '_', '-'); return cxx_id; } - diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index 2392f47b36..e677b9e5c5 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -74,6 +74,7 @@ static Keyword_ent the_key_tab[] {"time", TIME_T}, {"times", TIMES}, {"transpose", TRANSPOSE}, + {"transposition", TRANSPOSITION}, {"type", TYPE}, {"unset", UNSET}, {"with", WITH}, diff --git a/lily/lily-parser-scheme.cc b/lily/lily-parser-scheme.cc index 90d9a60366..1657438212 100644 --- a/lily/lily-parser-scheme.cc +++ b/lily/lily-parser-scheme.cc @@ -11,7 +11,6 @@ #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" @@ -37,7 +36,7 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", "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); @@ -65,7 +64,6 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", if (!output_name_global.empty ()) { - /* Interpret --output=DIR to mean --output=DIR/BASE. */ string dir; if (is_dir (output_name_global)) @@ -74,15 +72,7 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", 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 ()); @@ -110,9 +100,9 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", 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 ()))); } @@ -130,8 +120,8 @@ LY_DEFINE (ly_parse_file, "ly:parse-file", 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"), @@ -239,20 +229,4 @@ LY_DEFINE (ly_parser_output_name, "ly:parser-output-name", 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; -} diff --git a/lily/lily-parser.cc b/lily/lily-parser.cc index 1f073fb07a..65160851e1 100644 --- a/lily/lily-parser.cc +++ b/lily/lily-parser.cc @@ -141,6 +141,7 @@ Lily_parser::parse_string (string ly_code) lexer_->main_input_name_ = ""; lexer_->is_main_input_ = true; + set_yydebug (0); lexer_->new_input (lexer_->main_input_name_, ly_code, sources_); SCM mod = lexer_->set_current_scope (); diff --git a/lily/line-interface.cc b/lily/line-interface.cc index ff7fae5783..6401b3896a 100644 --- a/lily/line-interface.cc +++ b/lily/line-interface.cc @@ -44,7 +44,6 @@ Line_interface::make_dashed_line (Real thick, Offset from, Offset to, 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; diff --git a/lily/line-spanner.cc b/lily/line-spanner.cc index 688cf8db2e..ff37a4c258 100644 --- a/lily/line-spanner.cc +++ b/lily/line-spanner.cc @@ -307,11 +307,5 @@ ADD_INTERFACE (Line_spanner, "line-spanner-interface", "@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"); diff --git a/lily/listener.cc b/lily/listener.cc index c8202a9d34..edc96bdf1c 100644 --- a/lily/listener.cc +++ b/lily/listener.cc @@ -10,12 +10,6 @@ #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; @@ -36,13 +30,12 @@ SCM 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 ("#", p); return 1; diff --git a/lily/ly-module.cc b/lily/ly-module.cc index 740f9e4e52..45db747819 100644 --- a/lily/ly-module.cc +++ b/lily/ly-module.cc @@ -85,7 +85,13 @@ ly_use_module (SCM mod, SCM used) #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) @@ -93,7 +99,8 @@ 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 diff --git a/lily/lyric-combine-music-iterator.cc b/lily/lyric-combine-music-iterator.cc index dafed1d3c8..14d3959cee 100644 --- a/lily/lyric-combine-music-iterator.cc +++ b/lily/lyric-combine-music-iterator.cc @@ -63,8 +63,11 @@ void 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; } @@ -73,13 +76,13 @@ Lyric_combine_music_iterator::set_music_context (Context *to) { 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 ()); } } @@ -199,11 +202,7 @@ Lyric_combine_music_iterator::check_new_context (SCM sev) } /* - 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 () @@ -233,11 +232,7 @@ 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; diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index e11f4ec222..176c9b7166 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -14,9 +14,6 @@ #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. @@ -26,14 +23,14 @@ class Lyric_engraver : public Engraver { 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_; @@ -47,11 +44,15 @@ Lyric_engraver::Lyric_engraver () 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 @@ -156,6 +157,8 @@ Lyric_engraver::stop_translation_timestep () event_ = 0; } +#include "translator.icc" + ADD_TRANSLATOR (Lyric_engraver, /* doc */ "", /* create */ "LyricText", diff --git a/lily/lyric-extender.cc b/lily/lyric-extender.cc index 867a6d83d3..281296c506 100644 --- a/lily/lyric-extender.cc +++ b/lily/lyric-extender.cc @@ -16,8 +16,8 @@ #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); @@ -60,17 +60,16 @@ Lyric_extender::print (SCM 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 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) @@ -87,10 +86,4 @@ Lyric_extender::print (SCM smob) 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"); diff --git a/lily/lyric-performer.cc b/lily/lyric-performer.cc index fe0638eefc..935f06c35e 100644 --- a/lily/lyric-performer.cc +++ b/lily/lyric-performer.cc @@ -8,8 +8,7 @@ #include "audio-item.hh" #include "performer.hh" -#include "stream-event.hh" -#include "translator.icc" +#include "music.hh" class Lyric_performer : public Performer { @@ -17,11 +16,12 @@ public: 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 events_; + vector events_; Audio_text *audio_; }; @@ -51,17 +51,24 @@ Lyric_performer::stop_translation_timestep () { 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", "", ""); diff --git a/lily/main.cc b/lily/main.cc index ae4c86dd2a..f640801b84 100644 --- a/lily/main.cc +++ b/lily/main.cc @@ -89,7 +89,7 @@ bool make_print = true; bool relocate_binary = -#if 1 +#if ARGV0_RELOCATION true; #else false @@ -427,7 +427,6 @@ main_with_guile (void *, int, char **) *tail = scm_cons (scm_makfrom0str (arg), SCM_EOL); tail = SCM_CDRLOC (*tail); } - delete option_parser; option_parser = 0; @@ -541,12 +540,7 @@ parse_argv (int argc, char **argv) break; case 'f': - { - vector 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': diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index 70115d62fd..cb2ac141d9 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -17,12 +17,9 @@ using namespace std; #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. @@ -30,18 +27,18 @@ using namespace std; 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); }; @@ -101,7 +98,7 @@ Mark_engraver::stop_translation_timestep () } void -Mark_engraver::create_items (Stream_event *ev) +Mark_engraver::create_items (Music *ev) { if (text_) return; @@ -109,11 +106,11 @@ Mark_engraver::create_items (Stream_event *ev) 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; } /* @@ -161,6 +158,8 @@ Mark_engraver::process_music () } } +#include "translator.icc" + ADD_ACKNOWLEDGER (Mark_engraver, break_aligned); ADD_ACKNOWLEDGER (Mark_engraver, break_alignment); diff --git a/lily/melisma-translator.cc b/lily/melisma-translator.cc index adc873d4dc..74b0e10d5e 100644 --- a/lily/melisma-translator.cc +++ b/lily/melisma-translator.cc @@ -9,11 +9,8 @@ #include "engraver.hh" #include "grob.hh" #include "context.hh" -#include "music.hh" #include "translator.icc" -/* Remove this translator. */ - /** Signal existence of melismas. */ @@ -70,13 +67,6 @@ Melisma_translator::Melisma_translator () 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 */ ""); diff --git a/lily/mensural-ligature-engraver.cc b/lily/mensural-ligature-engraver.cc index f40ce004b0..5adc44122c 100644 --- a/lily/mensural-ligature-engraver.cc +++ b/lily/mensural-ligature-engraver.cc @@ -11,19 +11,16 @@ #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. @@ -50,8 +47,7 @@ class Mensural_ligature_engraver : public Coherent_ligature_engraver protected: virtual Spanner *create_ligature_spanner (); virtual void build_ligature (Spanner *ligature, vector primitives); - DECLARE_TRANSLATOR_LISTENER (ligature); - + public: TRANSLATOR_DECLARATIONS (Mensural_ligature_engraver); @@ -61,13 +57,6 @@ private: void fold_up_primitives (vector 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 = @@ -104,12 +93,12 @@ Mensural_ligature_engraver::transform_heads (vector primitives) Item *primitive = dynamic_cast (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")); @@ -174,7 +163,7 @@ Mensural_ligature_engraver::transform_heads (vector primitives) } // 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) { @@ -393,6 +382,8 @@ Mensural_ligature_engraver::build_ligature (Spanner *ligature, 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, diff --git a/lily/mensural-ligature.cc b/lily/mensural-ligature.cc index 936f64b877..a36f1b1723 100644 --- a/lily/mensural-ligature.cc +++ b/lily/mensural-ligature.cc @@ -110,7 +110,7 @@ internal_brew_primitive (Grob *me) 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); @@ -167,7 +167,7 @@ internal_brew_primitive (Grob *me) 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) @@ -221,12 +221,5 @@ Mensural_ligature::print (SCM) 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"); diff --git a/lily/metronome-engraver.cc b/lily/metronome-engraver.cc index 5e5986d2ea..21eb711a24 100644 --- a/lily/metronome-engraver.cc +++ b/lily/metronome-engraver.cc @@ -11,13 +11,9 @@ using namespace std; #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, @@ -30,28 +26,19 @@ public: 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 @@ -66,34 +53,42 @@ Metronome_mark_engraver::stop_translation_timestep () 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. " @@ -101,13 +96,6 @@ ADD_TRANSLATOR (Metronome_mark_engraver, "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 */ ""); diff --git a/lily/midi-def.cc b/lily/midi-def.cc new file mode 100644 index 0000000000..c3b80dbeae --- /dev/null +++ b/lily/midi-def.cc @@ -0,0 +1,46 @@ +/* + midi-def.cc -- implement midi output def functions + + source file of the GNU LilyPond music typesetter + + (c) 1997--2006 Jan Nieuwenhuizen +*/ + + +#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 ()); +} + diff --git a/lily/midi-item.cc b/lily/midi-item.cc index 88d303b4e7..7f8edb041c 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -104,25 +104,25 @@ Midi_event::to_string () const { 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, ""); @@ -157,15 +157,6 @@ Midi_instrument::to_string () const } Midi_item::Midi_item () -{ -} - -Midi_channel_item::~Midi_channel_item () -{ - channel_ = 0; -} - -Midi_channel_item::Midi_channel_item () { channel_ = 0; } @@ -177,20 +168,20 @@ Midi_item::~Midi_item () 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; } @@ -301,7 +292,7 @@ Midi_note::to_string () const } 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; @@ -326,7 +317,7 @@ Midi_note_off::to_string () const 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) @@ -401,9 +392,9 @@ Midi_tempo::Midi_tempo (Audio_tempo *a) 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); } diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 2979c9380c..13bf59db8c 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -33,10 +33,8 @@ compare (Midi_note_event const &left, Midi_note_event const &right) 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_; @@ -146,9 +144,7 @@ Midi_walker::process () if (Midi_item *midi = Midi_item::get_midi (audio)) { - if (Midi_channel_item *mci = dynamic_cast (midi)) - mci->channel_ = channel_; - + midi->channel_ = track_->channel_; //midi->channel_ = track_->number_; if (Midi_note *note = dynamic_cast (midi)) { diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index e03696abc4..3c7eed7524 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -10,11 +10,8 @@ #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 */ @@ -24,16 +21,15 @@ public: 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 text_events_; + Music *rest_ev_; + vector text_events_; int start_measure_; Rational last_main_moment_; Moment stop_moment_; @@ -61,25 +57,22 @@ Multi_measure_rest_engraver::Multi_measure_rest_engraver () 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 @@ -98,7 +91,8 @@ Multi_measure_rest_engraver::process_music () { 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"); @@ -137,7 +131,7 @@ Multi_measure_rest_engraver::process_music () } start_measure_ - = scm_to_int (get_property ("internalBarNumber")); + = scm_to_int (get_property ("currentBarNumber")); } bar_seen_ = bar_seen_ || scm_is_string (get_property ("whichBar")); @@ -204,7 +198,7 @@ Multi_measure_rest_engraver::start_translation_timestep () 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_; /* @@ -248,28 +242,21 @@ Multi_measure_rest_engraver::finalize () { } +#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 */ ""); diff --git a/lily/multi-measure-rest.cc b/lily/multi-measure-rest.cc index 0a87a137ed..997e76105d 100644 --- a/lily/multi-measure-rest.cc +++ b/lily/multi-measure-rest.cc @@ -32,22 +32,20 @@ Multi_measure_rest::percent (SCM smob) // 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. diff --git a/lily/music-function.cc b/lily/music-function.cc index 6795ca67d4..8f0f7813d9 100644 --- a/lily/music-function.cc +++ b/lily/music-function.cc @@ -33,9 +33,28 @@ LY_DEFINE (ly_make_music_function, "ly:make-music-function", 2, 0, 0, "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); } diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index 036a0c3249..fcfd2fc1f4 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -118,7 +118,7 @@ Music_iterator::music_start_mom ()const } void -Music_iterator::init_context (Music *m, Context *report) +Music_iterator::init_translator (Music *m, Context *report) { music_ = m; assert (m); @@ -145,7 +145,7 @@ Music_iterator::get_iterator (Music *m) const 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; @@ -165,11 +165,8 @@ Music_iterator::report_event (Music *m) { 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 ()); } diff --git a/lily/music.cc b/lily/music.cc index b938c86e22..02a9876b1c 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -11,7 +11,7 @@ #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" @@ -21,11 +21,11 @@ #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 @@ -184,18 +184,15 @@ Music::compress (Moment factor) 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)) @@ -209,29 +206,21 @@ transpose_mutable (SCM alist, Pitch delta) 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 @@ -247,68 +236,11 @@ Music::origin () const 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 * diff --git a/lily/new-fingering-engraver.cc b/lily/new-fingering-engraver.cc index 03eecc480d..cb2a1bd202 100644 --- a/lily/new-fingering-engraver.cc +++ b/lily/new-fingering-engraver.cc @@ -14,7 +14,7 @@ #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" @@ -23,8 +23,8 @@ struct Finger_tuple { Grob *head_; Grob *script_; - Stream_event *note_event_; - Stream_event *finger_event_; + Music *note_event_; + Music *finger_event_; bool follow_into_staff_; int position_; @@ -35,14 +35,12 @@ struct Finger_tuple 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 fingerings_; @@ -52,23 +50,22 @@ class New_fingering_engraver : public Engraver vector 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 *); }; 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; @@ -76,20 +73,20 @@ New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf) 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")); @@ -109,8 +106,8 @@ New_fingering_engraver::acknowledge_stem (Grob_info inf) void New_fingering_engraver::add_script (Grob *head, - Stream_event *event, - Stream_event *note) + Music *event, + Music *note) { (void) note; @@ -121,16 +118,17 @@ New_fingering_engraver::add_script (Grob *head, 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; @@ -138,12 +136,24 @@ New_fingering_engraver::add_fingering (Grob *head, 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; @@ -154,8 +164,8 @@ New_fingering_engraver::add_fingering (Grob *head, void New_fingering_engraver::add_string (Grob *head, - Stream_event *event, - Stream_event *hevent) + Music *event, + Music *hevent) { Finger_tuple ft; @@ -163,6 +173,11 @@ New_fingering_engraver::add_string (Grob *head, 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; @@ -205,7 +220,7 @@ New_fingering_engraver::position_scripts (SCM orientations, } } - vector_sort (*scripts, less ()); + 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; @@ -290,15 +305,6 @@ New_fingering_engraver::position_scripts (SCM orientations, void New_fingering_engraver::stop_translation_timestep () -{ - position_all(); - stem_ = 0; - heads_.clear (); -} - - -void -New_fingering_engraver::position_all () { if (fingerings_.size ()) { @@ -326,7 +332,12 @@ New_fingering_engraver::position_all () if (stem_ && to_boolean (script->get_property ("add-stem-support"))) Side_position_interface::add_support (script, stem_); + + } + + stem_ = 0; + heads_.clear (); articulations_.clear (); } @@ -334,8 +345,6 @@ New_fingering_engraver::New_fingering_engraver () { stem_ = 0; } - - ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head); ADD_ACKNOWLEDGER (New_fingering_engraver, stem); @@ -343,13 +352,7 @@ ADD_TRANSLATOR (New_fingering_engraver, /* 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 */ ""); diff --git a/lily/note-collision.cc b/lily/note-collision.cc index d9a08dcdc8..1df0a6c7ab 100644 --- a/lily/note-collision.cc +++ b/lily/note-collision.cc @@ -305,9 +305,7 @@ Note_collision_interface::calc_positioning_done (SCM smob) 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); @@ -371,7 +369,7 @@ Note_collision_interface::get_clash_groups (Grob *me) do { vector &clashes (clash_groups[d]); - vector_sort (clashes, Note_column::shift_less); + vector_sort (clashes, Note_column::shift_compare); } while ((flip (&d)) != UP); diff --git a/lily/note-column.cc b/lily/note-column.cc index 146b3b0654..ba8ebd6fd8 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -34,15 +34,15 @@ Note_column::has_rests (Grob *me) 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 * @@ -188,14 +188,4 @@ Note_column::arpeggio (Grob *me) 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"); diff --git a/lily/note-head.cc b/lily/note-head.cc index cb89b5ae17..5f86f6e401 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -43,11 +43,8 @@ internal_print (Grob *me, string *font_char) 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."; @@ -58,20 +55,18 @@ internal_print (Grob *me, string *font_char) 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; } diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 1c6bf4142d..7b91132246 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -9,29 +9,26 @@ #include 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 notes_; - vector note_evs_; + vector dots_; + vector 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 (); }; @@ -40,11 +37,18 @@ Note_heads_engraver::Note_heads_engraver () { } -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 @@ -52,9 +56,26 @@ Note_heads_engraver::process_music () { 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. */ @@ -99,14 +120,19 @@ void 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 */ ""); diff --git a/lily/note-name-engraver.cc b/lily/note-name-engraver.cc index 132bd17e29..585eb1fae2 100644 --- a/lily/note-name-engraver.cc +++ b/lily/note-name-engraver.cc @@ -8,28 +8,28 @@ #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 events_; + vector events_; vector 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 @@ -66,8 +66,10 @@ Note_name_engraver::Note_name_engraver () { } +#include "translator.icc" + ADD_TRANSLATOR (Note_name_engraver, - /* doc */ "Print pitches as words.", + /* doc */ "", /* create */ "NoteName", /* accept */ "note-event", /* read */ "printOctaveNames", diff --git a/lily/note-performer.cc b/lily/note-performer.cc index 4aecc39606..331e7cc60f 100644 --- a/lily/note-performer.cc +++ b/lily/note-performer.cc @@ -10,10 +10,8 @@ #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. @@ -24,12 +22,13 @@ public: TRANSLATOR_DECLARATIONS (Note_performer); protected: + virtual bool try_music (Music *ev); + void stop_translation_timestep (); void process_music (); - DECLARE_TRANSLATOR_LISTENER (note); private: - vector note_evs_; + vector note_evs_; vector notes_; }; @@ -46,28 +45,13 @@ Note_performer::process_music () 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); @@ -82,19 +66,32 @@ 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 (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 () diff --git a/lily/note-spacing.cc b/lily/note-spacing.cc index 2700c12835..8586cc5f4c 100644 --- a/lily/note-spacing.cc +++ b/lily/note-spacing.cc @@ -306,13 +306,13 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, 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 @@ -323,20 +323,12 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, 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); } } @@ -457,13 +449,5 @@ Note_spacing::stem_dir_correction (Grob *me, Item *rcolumn, 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"); diff --git a/lily/optimal-page-breaking.cc b/lily/optimal-page-breaking.cc deleted file mode 100644 index 03d72629a0..0000000000 --- a/lily/optimal-page-breaking.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - 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 -*/ - -#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 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 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 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); -} - diff --git a/lily/output-property-engraver.cc b/lily/output-property-engraver.cc index ca6f868732..7f59d44430 100644 --- a/lily/output-property-engraver.cc +++ b/lily/output-property-engraver.cc @@ -8,9 +8,8 @@ */ #include "engraver.hh" -#include "context.hh" #include "grob.hh" -#include "stream-event.hh" +#include "context.hh" #include "translator.icc" @@ -19,24 +18,30 @@ class Output_property_engraver : public Engraver { TRANSLATOR_DECLARATIONS (Output_property_engraver); protected: - vector props_; - - DECLARE_ACKNOWLEDGER (grob); - DECLARE_TRANSLATOR_LISTENER (apply_output); + vector 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 @@ -44,7 +49,7 @@ Output_property_engraver::acknowledge_grob (Grob_info inf) { 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, @@ -74,7 +79,7 @@ ADD_TRANSLATOR (Output_property_engraver, "", /* accept */ - "apply-output-event", + "layout-instruction", /* read */ "", diff --git a/lily/page-breaking-scheme.cc b/lily/page-breaking-scheme.cc deleted file mode 100644 index 2c28da917e..0000000000 --- a/lily/page-breaking-scheme.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - page-breaking-scheme.cc -- implement bindings to the various - page-breakers - - source file of the GNU LilyPond music typesetter - - (c) 2006 Joe Neeman -*/ - -#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 (); -} diff --git a/lily/page-breaking.cc b/lily/page-breaking.cc deleted file mode 100644 index b43c302367..0000000000 --- a/lily/page-breaking.cc +++ /dev/null @@ -1,427 +0,0 @@ -/* - 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 -*/ - -#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 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 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 -Page_breaking::line_details (vsize start_break, vsize end_break, Line_division const &div) -{ - vector chunks = chunk_list (start_break, end_break); - vector 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 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 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 (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 cols = all_[i].pscore_->root_system ()->columns (); - vector 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 -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 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 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 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 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_divisions (vsize start, - vsize end, - vsize system_count, - Line_division lower_bound, - Line_division upper_bound) -{ - vector 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 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 *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 (); - } -} diff --git a/lily/page-spacing.cc b/lily/page-spacing.cc deleted file mode 100644 index 945a52b60a..0000000000 --- a/lily/page-spacing.cc +++ /dev/null @@ -1,441 +0,0 @@ -/* - page-spacing.cc - implement routines for spacing - systems vertically on pages - - source file of the GNU LilyPond music typesetter - - (c) 2006 Joe Neeman -*/ - -#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 -compress_lines (const vector &orig) -{ - vector 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 -uncompress_solution (vector const &systems_per_page, - vector const &compressed) -{ - vector 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 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 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 lines1 (lines.begin (), lines.begin () + i + 1); - vector 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 page1_force; - vector 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 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 const &uncompressed_lines, - Real page_height, bool ragged, bool ragged_last) -{ - vsize ret = 1; - Real cur_rod_height = 0; - vector 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 const &lines, - vsize n, - Real page_height, - bool ragged, - bool ragged_last) -{ - vector 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 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 const &lines, - Real page_height, - Real odd_pages_penalty, - bool ragged, - bool ragged_last) -{ - vector 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; -} diff --git a/lily/page-turn-engraver.cc b/lily/page-turn-engraver.cc deleted file mode 100644 index a00c5922ad..0000000000 --- a/lily/page-turn-engraver.cc +++ /dev/null @@ -1,337 +0,0 @@ -/* - page-turn-engraver.cc -- implement Page_turn_engraver - - source file of the GNU LilyPond music typesetter - - (c) 2006 Joe Neeman -*/ - -#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 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 penalize (Page_turn_event const &penalty) - { - Interval_t intersect = intersection (duration_, penalty.duration_); - vector 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 forced_breaks_; - vector automatic_breaks_; - vector repeat_penalties_; - - /* the next 3 are in sync (ie. same number of elements, etc.) */ - vector breakable_moments_; - vector breakable_columns_; - vector 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 ()); - vsize end = upper_bound (breakable_moments_, brk.duration_[RIGHT], less ()); - - 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 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 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 */ "" - ); diff --git a/lily/page-turn-page-breaking.cc b/lily/page-turn-page-breaking.cc deleted file mode 100644 index e60ccfe033..0000000000 --- a/lily/page-turn-page-breaking.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - page-turn-page-breaking.cc -- implement Page_turn_page_breaking - - source file of the GNU LilyPond music typesetter - - (c) 2006 Joe Neeman -*/ - -#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 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 div = line_divisions (start, end, sys_count, min_division, max_division); - bool found = false; - - for (vsize d = 0; d < div.size (); d++) - { - vector 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 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 *psoln) -{ - vector &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 const &soln, SCM systems) -{ - vector 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); -} diff --git a/lily/pango-font.cc b/lily/pango-font.cc index 6c5735fec8..73ea7426a6 100644 --- a/lily/pango-font.cc +++ b/lily/pango-font.cc @@ -99,8 +99,7 @@ get_unicode_name (char*s, FT_ULong code) 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]; @@ -119,28 +118,22 @@ Pango_font::pango_item_string_stencil (PangoItem const *item, string str, 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; @@ -181,8 +174,7 @@ Pango_font::pango_item_string_stencil (PangoItem const *item, string str, 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; } @@ -270,21 +262,8 @@ Pango_font::physical_font_tab () const 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_, @@ -308,7 +287,7 @@ Pango_font::text_stencil (string str, bool tight) const { 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) { @@ -344,11 +323,14 @@ Pango_font::text_stencil (string str, bool tight) const /* 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); @@ -358,16 +340,6 @@ Pango_font::text_stencil (string str, bool tight) const 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 { diff --git a/lily/paper-book.cc b/lily/paper-book.cc index 926f9f5a96..8ef498aaec 100644 --- a/lily/paper-book.cc +++ b/lily/paper-book.cc @@ -8,7 +8,6 @@ #include "paper-book.hh" -#include "grob.hh" #include "main.hh" #include "output-def.hh" #include "paper-score.hh" @@ -216,12 +215,8 @@ Paper_book::score_title (SCM header) 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)) { @@ -229,17 +224,10 @@ set_system_penalty (SCM sys, SCM 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 (unsmob_music_output (sys))) - { - vector 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)); } } } @@ -260,6 +248,7 @@ Paper_book::get_score_title (SCM header) 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(); } @@ -279,6 +268,7 @@ Paper_book::get_system_specs () 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 (); @@ -289,7 +279,7 @@ Paper_book::get_system_specs () 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))) { @@ -302,10 +292,6 @@ Paper_book::get_system_specs () if (Paper_score *pscore = dynamic_cast (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); @@ -372,7 +358,7 @@ Paper_book::systems () 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)); @@ -394,22 +380,8 @@ Paper_book::pages () 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_; } diff --git a/lily/paper-column-engraver.cc b/lily/paper-column-engraver.cc index af67b67fe2..7bc7c665ac 100644 --- a/lily/paper-column-engraver.cc +++ b/lily/paper-column-engraver.cc @@ -8,15 +8,14 @@ #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" @@ -29,6 +28,8 @@ Paper_column_engraver::Paper_column_engraver () breaks_ = 0; system_ = 0; first_ = true; + last_breakable_column_ = 0; + last_breakable_moment_ = Moment (-1); } void @@ -40,7 +41,6 @@ Paper_column_engraver::finalize () 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_); } } @@ -53,11 +53,10 @@ Paper_column_engraver::make_columns () */ 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); } @@ -85,7 +84,6 @@ Paper_column_engraver::acknowledge_staff_spacing (Grob_info gi) ly_symbol2scm ("spacing-wishes"), gi.grob ()); } - void Paper_column_engraver::acknowledge_note_spacing (Grob_info gi) { @@ -110,11 +108,12 @@ Paper_column_engraver::set_columns (Paper_column *new_command, 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 @@ -123,17 +122,18 @@ Paper_column_engraver::process_music () 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"; @@ -172,10 +172,6 @@ Paper_column_engraver::process_music () 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]; @@ -193,12 +189,26 @@ Paper_column_engraver::stop_translation_timestep () 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 (); @@ -235,9 +245,9 @@ ADD_TRANSLATOR (Paper_column_engraver, /* accept */ "break-event", /* read */ "forbidBreak " - , + "allowPageTurn", /* write */ "forbidBreak " + "allowPageTurn " "currentCommandColumn " - "currentMusicalColumn " - ); + "currentMusicalColumn"); diff --git a/lily/paper-column.cc b/lily/paper-column.cc index aa7d918c8e..525dca36b8 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -45,12 +45,6 @@ Paper_column::get_system () const return system_; } -void -Paper_column::set_system (System *s) -{ - system_ = s; -} - Paper_column * Paper_column::get_column () const { @@ -71,24 +65,6 @@ Paper_column::Paper_column (Paper_column const &src, int count) rank_ = src.rank_; } -int -Paper_column::compare (Grob * const &a, - Grob * const &b) -{ - return sign (dynamic_cast (a)->rank_ - - dynamic_cast (b)->rank_); -} - -bool -Paper_column::less_than (Grob *const &a, - Grob *const &b) -{ - Paper_column *pa = dynamic_cast (a); - Paper_column *pb = dynamic_cast (b); - - return pa->rank_ < pb->rank_; -} - Moment Paper_column::when_mom (Grob *me) { @@ -222,7 +198,6 @@ ADD_INTERFACE (Paper_column, /* properties */ "between-cols " "bounded-by-me " - "grace-spacing " "line-break-system-details " "line-break-penalty " "line-break-permission " @@ -232,7 +207,6 @@ ADD_INTERFACE (Paper_column, "page-turn-permission " "shortest-playing-duration " "shortest-starter-duration " - "spacing " "used " "when "); diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index f11f40d905..c321c6f8df 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -17,7 +17,7 @@ using namespace std; #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" diff --git a/lily/paper-score.cc b/lily/paper-score.cc index 028fb37a14..8dfbc38939 100644 --- a/lily/paper-score.cc +++ b/lily/paper-score.cc @@ -10,6 +10,7 @@ #include "all-font-metrics.hh" #include "book.hh" +#include "gourlay-breaking.hh" #include "international.hh" #include "main.hh" #include "misc.hh" @@ -74,41 +75,33 @@ Paper_score::find_break_indices () const retval.push_back (i); } - cols_ = all; - break_indices_ = retval; - return retval; } -vector -Paper_score::get_break_indices () const -{ - if (break_indices_.empty ()) - find_break_indices (); - return break_indices_; -} - -vector -Paper_score::get_columns () const -{ - if (cols_.empty ()) - find_break_indices (); - return cols_; -} vector Paper_score::calc_breaking () { - Constrained_breaking algorithm (this); + Break_algorithm *algorithm = 0; vector 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 diff --git a/lily/parenthesis-engraver.cc b/lily/parenthesis-engraver.cc index 2c48c2597a..01ea191cb3 100644 --- a/lily/parenthesis-engraver.cc +++ b/lily/parenthesis-engraver.cc @@ -9,12 +9,12 @@ #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" @@ -33,17 +33,19 @@ Parenthesis_engraver::Parenthesis_engraver() 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 (info.grob ())) { Engraver *eng = dynamic_cast (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); diff --git a/lily/parser.yy b/lily/parser.yy index 6299ad3eb9..795639ae5b 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -9,7 +9,6 @@ %{ -#define YYDEBUG 1 #define YYERROR_VERBOSE 1 #define YYPARSE_PARAM my_lily_parser #define YYLEX_PARAM my_lily_parser @@ -75,6 +74,7 @@ using namespace std; #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" @@ -114,12 +114,11 @@ using namespace std; - 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 (); @@ -133,10 +132,12 @@ 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); @@ -160,7 +161,7 @@ void set_music_properties (Music *p, SCM a); %token ADDQUOTE "\\addquote" %token ALIAS "\\alias" %token ALTERNATIVE "\\alternative" -%token BOOK "\\book" +%token BOOK "\book" %token CHANGE "\\change" %token CHORDMODE "\\chordmode" %token CHORDS "\\chords" @@ -206,6 +207,7 @@ void set_music_properties (Music *p, SCM a); %token TEMPO "\\tempo" %token TIMES "\\times" %token TRANSPOSE "\\transpose" +%token TRANSPOSITION "\\transposition" %token TYPE "\\type" %token UNSET "\\unset" %token WITH "\\with" @@ -222,10 +224,8 @@ void set_music_properties (Music *p, SCM a); %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]" @@ -250,19 +250,13 @@ If we give names, Bison complains. %token CHORDMODIFIERS %token LYRIC_MARKUP %token MULTI_MEASURE_REST +%token SCM_T %token DIGIT %token E_UNSIGNED %token UNSIGNED -/* Artificial tokens, for more generic function syntax */ -%token EXPECT_MARKUP; -%token EXPECT_MUSIC; -%token EXPECT_SCM; -/* After the last argument. */ -%token EXPECT_NO_MORE_ARGS; - %token BOOK_IDENTIFIER %token CHORDMODIFIER_PITCH %token CHORD_MODIFIER @@ -284,6 +278,22 @@ If we give names, Bison complains. %token MARKUP_HEAD_SCM0_SCM1_SCM2 %token MARKUP_IDENTIFIER %token MUSIC_FUNCTION +%token MUSIC_FUNCTION_MARKUP +%token MUSIC_FUNCTION_MARKUP_MARKUP +%token MUSIC_FUNCTION_MARKUP_MARKUP_MUSIC +%token MUSIC_FUNCTION_MARKUP_MUSIC +%token MUSIC_FUNCTION_MARKUP_MUSIC_MUSIC +%token MUSIC_FUNCTION_MUSIC +%token MUSIC_FUNCTION_MUSIC_MUSIC +%token MUSIC_FUNCTION_SCM +%token MUSIC_FUNCTION_SCM_MUSIC +%token MUSIC_FUNCTION_SCM_MUSIC_MUSIC +%token MUSIC_FUNCTION_SCM_SCM_MUSIC_MUSIC +%token MUSIC_FUNCTION_SCM_SCM +%token MUSIC_FUNCTION_SCM_SCM_MUSIC +%token MUSIC_FUNCTION_SCM_SCM_SCM +%token MUSIC_FUNCTION_SCM_SCM_SCM_MUSIC +%token MUSIC_FUNCTION_SCM_SCM_SCM_SCM_MUSIC %token MUSIC_IDENTIFIER %token NOTENAME_PITCH %token NUMBER_IDENTIFIER @@ -291,7 +301,7 @@ If we give names, Bison complains. %token REAL %token RESTNAME %token SCM_IDENTIFIER -%token SCM_TOKEN +%token SCM_T %token SCORE_IDENTIFIER %token STRING %token STRING_IDENTIFIER @@ -313,14 +323,14 @@ If we give names, Bison complains. %type tremolo_type /* Music */ -%type composite_music -%type grouped_music_list -%type music -%type prefix_composite_music -%type repeated_music -%type sequential_music -%type simple_music -%type simultaneous_music +%type Composite_music +%type Grouped_music_list +%type Music +%type Prefix_composite_music +%type Repeated_music +%type Sequential_music +%type Simple_music +%type Simultaneous_music %type chord_body %type chord_body_element %type command_element @@ -336,9 +346,9 @@ If we give names, Bison complains. %type re_rhythmed_music %type relative_music %type simple_element -%type simple_music_property_def %type string_number_event %type tempo_event +%type toplevel_music %type output_def_body %type output_def_head @@ -346,12 +356,15 @@ If we give names, Bison complains. %type output_def %type paper_block -%type alternative_music -%type generic_prefix_music_scm -%type music_list +%type Alternative_music +%type Generic_prefix_music_scm +%type Music_list %type absolute_pitch %type assignment_id %type bare_number +%type music_function_event +%type music_function_chord_body +%type music_function_musicless_prefix %type bass_figure %type figured_bass_modification %type br_bass_figure @@ -373,11 +386,6 @@ If we give names, Bison complains. %type figure_spec %type fraction %type full_markup -%type function_scm_argument -%type function_arglist -%type function_arglist_music_last -%type function_arglist_nonmusic_last -%type function_arglist_nonmusic %type identifier_init %type lilypond_header %type lilypond_header_body @@ -394,9 +402,6 @@ If we give names, Bison complains. %type mode_changing_head %type mode_changing_head_with_context %type multiplied_duration -%type music_function_identifier_musicless_prefix -%type music_function_event -%type music_function_chord_body %type new_chord %type new_lyrics %type number_expression @@ -413,7 +418,6 @@ If we give names, Bison complains. %type property_operation %type scalar %type script_abbreviation -%type simple_chord_elements %type simple_markup %type simple_string %type steno_duration @@ -422,6 +426,7 @@ If we give names, Bison complains. %type step_number %type step_numbers %type string +%type function_scm_argument %type score_block %type score_body @@ -471,7 +476,7 @@ toplevel_expression: 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 ()); @@ -496,8 +501,13 @@ toplevel_expression: } ; +toplevel_music: + Composite_music { + } + ; + embedded_scm: - SCM_TOKEN + SCM_T | SCM_IDENTIFIER ; @@ -528,6 +538,15 @@ assignment_id: 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); /* @@ -558,17 +577,8 @@ identifier_init: | 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; @@ -600,11 +610,11 @@ context_def_spec_block: 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 ($$); @@ -636,15 +646,14 @@ book_block: book_body: { $$ = new Book; - $$->origin ()->set_spot (@$); + $$->set_spot (@$); $$->paper_ = dynamic_cast (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; @@ -677,7 +686,7 @@ score_block: ; 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 ()); @@ -685,12 +694,11 @@ score_body: // 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); @@ -726,7 +734,6 @@ paper_block: if ($$->lookup_variable (ly_symbol2scm ("is-paper")) != SCM_BOOL_T) { PARSER->parser_error (@1, _ ("need \\paper for paper block")); - $1->unprotect (); $$ = get_paper (PARSER); } } @@ -775,11 +782,9 @@ output_def_body: } | 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_); } @@ -789,6 +794,15 @@ output_def_body: | 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 { } @@ -796,8 +810,11 @@ output_def_body: 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 (); + } ; /* @@ -807,11 +824,11 @@ The representation of a list is the 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); @@ -821,10 +838,10 @@ music_list: 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); @@ -840,47 +857,47 @@ music_list: } ; -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 @@ -904,14 +921,14 @@ context_mod_list: } ; -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: @@ -919,52 +936,48 @@ 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 { @@ -973,31 +986,48 @@ optional_id: ; -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 { @@ -1005,11 +1035,13 @@ prefix_composite_music: } 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 (); } @@ -1077,11 +1109,11 @@ mode_changing_head_with_context: 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); } @@ -1090,8 +1122,8 @@ relative_music: 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 (); @@ -1099,27 +1131,56 @@ new_lyrics: } | 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 (); } ; @@ -1183,46 +1244,50 @@ context_prop_spec: } ; -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 { @@ -1267,25 +1332,45 @@ scalar: 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 ; @@ -1308,10 +1393,26 @@ 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 (); } ; @@ -1363,83 +1464,121 @@ chord_body_element: $$ = 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 { @@ -1501,7 +1640,9 @@ post_event: $$ = $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 ()) @@ -1702,7 +1843,7 @@ gen_text_def: $$ = 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 (); @@ -1722,7 +1863,7 @@ script_abbreviation: | '|' { $$ = scm_makfrom0str ("Bar"); } - | ANGLE_CLOSE { + | '>' { $$ = scm_makfrom0str ("Larger"); } | '.' { @@ -1924,7 +2065,10 @@ figure_list: 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 (); } ; @@ -1959,16 +2103,36 @@ simple_element: 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") { @@ -1981,7 +2145,17 @@ simple_element: } 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 ()) @@ -1991,26 +2165,16 @@ simple_element: 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: @@ -2024,11 +2188,11 @@ 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)); } ; @@ -2309,9 +2473,11 @@ markup: %% void -Lily_parser::set_yydebug (bool x) +Lily_parser::set_yydebug (bool ) { - yydebug = x; +#if 0 + yydebug = 1; +#endif } void @@ -2337,26 +2503,17 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) *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 (); @@ -2367,7 +2524,6 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) 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 (); @@ -2375,9 +2531,8 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM sid) } 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; @@ -2389,6 +2544,66 @@ Lily_lexer::try_special_identifiers (SCM *destination, SCM 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 () { @@ -2406,7 +2621,7 @@ get_next_unique_lyrics_context_id () } -SCM +Music * run_music_function (Lily_parser *parser, SCM expr) { SCM func = scm_car (expr); @@ -2415,15 +2630,34 @@ run_music_function (Lily_parser *parser, SCM 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 @@ -2475,7 +2709,7 @@ void 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)); } @@ -2493,10 +2727,13 @@ make_chord_step (int step, int alter) 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; } @@ -2508,6 +2745,15 @@ ly_input_procedure_p (SCM x) || (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) { @@ -2521,6 +2767,16 @@ 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) { diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc index 284f7616c7..016b08598e 100644 --- a/lily/part-combine-engraver.cc +++ b/lily/part-combine-engraver.cc @@ -9,14 +9,11 @@ */ #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 { @@ -26,19 +23,19 @@ protected: 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 () @@ -53,13 +50,13 @@ Part_combine_engraver::process_music () 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)) @@ -97,6 +94,7 @@ Part_combine_engraver::stop_translation_timestep () event_ = 0; } +#include "translator.icc" ADD_ACKNOWLEDGER (Part_combine_engraver, note_head); ADD_ACKNOWLEDGER (Part_combine_engraver, stem); ADD_TRANSLATOR (Part_combine_engraver, diff --git a/lily/part-combine-iterator.cc b/lily/part-combine-iterator.cc index 9f06f3821f..65c7f1aac9 100644 --- a/lily/part-combine-iterator.cc +++ b/lily/part-combine-iterator.cc @@ -15,16 +15,6 @@ #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: @@ -77,13 +67,16 @@ private: /* 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 (); @@ -99,14 +92,11 @@ Part_combine_iterator::do_quit () 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 () @@ -164,21 +154,21 @@ Part_combine_iterator::chords_together () 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 @@ -189,42 +179,50 @@ Part_combine_iterator::solo1 () 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); } } @@ -242,24 +240,23 @@ Part_combine_iterator::unisono (bool silent) 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; @@ -275,15 +272,15 @@ Part_combine_iterator::solo2 () { 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; } } @@ -300,7 +297,7 @@ Part_combine_iterator::apart (bool silent) else { state_ = APART; - substitute_both (CONTEXT_ONE, CONTEXT_TWO); + substitute_both (one_.get_outlet (), two_.get_outlet ()); } } @@ -309,27 +306,56 @@ Part_combine_iterator::construct_children () { 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", @@ -343,6 +369,13 @@ Part_combine_iterator::construct_children () 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); @@ -362,8 +395,11 @@ Part_combine_iterator::set_busy (SCM se) 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; } @@ -388,11 +424,6 @@ Part_combine_iterator::process (Moment m) 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_)); diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index e76bbaeb08..a979a2e743 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -14,10 +14,11 @@ #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" @@ -34,7 +35,7 @@ public: TRANSLATOR_DECLARATIONS (Percent_repeat_engraver); protected: - Stream_event *percent_event_; + Music *percent_event_; /// moment (global time) where percent started. Moment stop_mom_; @@ -51,13 +52,9 @@ protected: 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 (); @@ -68,67 +65,43 @@ Percent_repeat_engraver::Percent_repeat_engraver () { 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 @@ -140,10 +113,9 @@ Percent_repeat_engraver::process_music () { 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"); @@ -208,7 +180,7 @@ Percent_repeat_engraver::typeset_perc () { if (percent_) { - Grob *col = first_command_column_; + Grob *col = unsmob_grob (get_property ("currentCommandColumn")); percent_->set_bound (RIGHT, col); percent_ = 0; @@ -219,7 +191,17 @@ Percent_repeat_engraver::typeset_perc () } } - +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 () diff --git a/lily/percent-repeat-iterator.cc b/lily/percent-repeat-iterator.cc index 495f30f33c..7ba527da5d 100644 --- a/lily/percent-repeat-iterator.cc +++ b/lily/percent-repeat-iterator.cc @@ -7,20 +7,10 @@ Erik Sandberg */ +#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); @@ -44,11 +34,9 @@ Percent_repeat_iterator::get_music_list () const 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; diff --git a/lily/performance.cc b/lily/performance.cc index 0bfe37ee82..f765a31937 100644 --- a/lily/performance.cc +++ b/lily/performance.cc @@ -36,12 +36,13 @@ Performance::~Performance () 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++) @@ -61,22 +62,88 @@ Performance::output (Midi_stream &midi_stream) 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 (p)) + audio_staffs_.push_back (s); + audio_elements_.push_back (p); } @@ -98,4 +165,3 @@ Performance::write_output (string out) progress_indication ("\n"); } - diff --git a/lily/performer-group.cc b/lily/performer-group.cc index d1696dac74..9e71c6e762 100644 --- a/lily/performer-group.cc +++ b/lily/performer-group.cc @@ -84,3 +84,27 @@ Performer_group::do_announces () announce_infos_.clear (); } } + +void +Performer_group::play_element (Audio_element *e) +{ + Context *c = context_->get_parent_context (); + if (c) + { + Performer_group *pgp = dynamic_cast (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 (c->implementation ()); + return pgp->get_tempo (); + } + return 60; +} + diff --git a/lily/performer.cc b/lily/performer.cc index 9d99873989..af896f23dd 100644 --- a/lily/performer.cc +++ b/lily/performer.cc @@ -11,6 +11,17 @@ #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 diff --git a/lily/pfb.cc b/lily/pfb.cc index a96aac7761..678e480b90 100644 --- a/lily/pfb.cc +++ b/lily/pfb.cc @@ -78,16 +78,17 @@ LY_DEFINE (ly_pfb_to_pfa, "ly:pfb->pfa", SCM_ARG1, __FUNCTION__, "string"); string file_name = ly_scm2string (pfb_file_name); + int len = -1; if (be_verbose_global) progress_indication ("[" + file_name); - vector 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 ("]"); diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index 1c14503adf..b3b9abbe00 100644 --- a/lily/phrasing-slur-engraver.cc +++ b/lily/phrasing-slur-engraver.cc @@ -14,34 +14,24 @@ #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 events_; - Stream_event *running_slur_start_; + Drul_array events_; + Music *running_slur_start_; vector slurs_; vector end_slurs_; protected: + virtual bool try_music (Music *); + void acknowledge_extra_object (Grob_info); DECLARE_ACKNOWLEDGER (accidental); DECLARE_ACKNOWLEDGER (dynamic_line_spanner); @@ -51,7 +41,6 @@ protected: DECLARE_ACKNOWLEDGER (slur); DECLARE_ACKNOWLEDGER (text_script); DECLARE_ACKNOWLEDGER (tie); - DECLARE_TRANSLATOR_LISTENER (phrasing_slur); void stop_translation_timestep (); virtual void finalize (); @@ -66,18 +55,30 @@ Phrasing_slur_engraver::Phrasing_slur_engraver () 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 @@ -117,8 +118,7 @@ Phrasing_slur_engraver::acknowledge_fingering (Grob_info info) 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 @@ -157,7 +157,7 @@ Phrasing_slur_engraver::process_music () 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")); @@ -175,10 +175,12 @@ Phrasing_slur_engraver::stop_translation_timestep () 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); diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc index c8a44bd4e4..2d380fb352 100644 --- a/lily/piano-pedal-engraver.cc +++ b/lily/piano-pedal-engraver.cc @@ -3,8 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 2000--2006 Jan Nieuwenhuizen , - Erik Sandberg + (c) 2000--2006 Jan Nieuwenhuizen Chris Jackson - extended to support bracketed pedals. @@ -20,57 +19,20 @@ #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? @@ -78,12 +40,12 @@ struct Pedal_info 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 event_drul_; + Drul_array event_drul_; Item *item_; Spanner *bracket_; // A single portion of a pedal bracket Spanner *finished_bracket_; @@ -95,8 +57,6 @@ struct Pedal_info Spanner *finished_line_spanner_; }; -static Pedal_type_info pedal_types_[NUM_PEDAL_TYPES]; - class Piano_pedal_engraver : public Engraver { public: @@ -105,15 +65,14 @@ 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 @@ -128,78 +87,41 @@ private: 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_; } /* @@ -209,7 +131,7 @@ Piano_pedal_engraver::~Piano_pedal_engraver () 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_) { @@ -223,42 +145,38 @@ Piano_pedal_engraver::acknowledge_note_column (Grob_info info) } } -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 @@ -274,7 +192,8 @@ Piano_pedal_engraver::process_music () 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 @@ -294,11 +213,11 @@ void 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", @@ -316,7 +235,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) 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]; @@ -327,7 +246,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) 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; @@ -352,11 +271,11 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) 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_); @@ -374,7 +293,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed) { 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; } @@ -480,7 +399,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed) 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? @@ -527,7 +446,7 @@ Piano_pedal_engraver::del_linespanner (Spanner *g) 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_) { @@ -539,7 +458,7 @@ Piano_pedal_engraver::stop_translation_timestep () 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; @@ -591,6 +510,8 @@ Piano_pedal_engraver::typeset_all (Pedal_info *p) } } +#include "translator.icc" + ADD_ACKNOWLEDGER (Piano_pedal_engraver, note_column); ADD_TRANSLATOR (Piano_pedal_engraver, diff --git a/lily/piano-pedal-performer.cc b/lily/piano-pedal-performer.cc index 3b51fd83ec..4083c468f9 100644 --- a/lily/piano-pedal-performer.cc +++ b/lily/piano-pedal-performer.cc @@ -10,12 +10,7 @@ #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 @@ -24,77 +19,71 @@ class Piano_pedal_performer : public Performer { struct Pedal_info { - Stream_event *start_event_; - Drul_array event_drul_; + char const *name_; + Music *start_event_; + Drul_array 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 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]); @@ -107,7 +96,7 @@ Piano_pedal_performer::process_music () { 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]); @@ -121,43 +110,42 @@ Piano_pedal_performer::process_music () 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", diff --git a/lily/pitch.cc b/lily/pitch.cc index 566b729e24..80b32e3c69 100644 --- a/lily/pitch.cc +++ b/lily/pitch.cc @@ -19,7 +19,6 @@ Pitch::Pitch (int o, int n, int a) notename_ = n; alteration_ = a; octave_ = o; - scale_ = default_global_scale; normalise (); } @@ -28,7 +27,6 @@ Pitch::Pitch () { notename_ = 0; alteration_ = 0; - scale_ = default_global_scale; octave_ = 0; } @@ -51,13 +49,11 @@ Pitch::compare (Pitch const &m1, Pitch const &m2) 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. */ @@ -68,15 +64,15 @@ Pitch::semitone_pitch () const 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)); } @@ -87,12 +83,12 @@ Pitch::quartertone_pitch () const 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_); } @@ -100,15 +96,15 @@ void 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; } @@ -173,7 +169,7 @@ char const *accname[] = {"eses", "eseh", "es", "eh", "", 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]); @@ -238,11 +234,11 @@ Pitch::down_to (int notename) } 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); diff --git a/lily/pitched-trill-engraver.cc b/lily/pitched-trill-engraver.cc index 71913d2bb9..84e391e231 100644 --- a/lily/pitched-trill-engraver.cc +++ b/lily/pitched-trill-engraver.cc @@ -8,15 +8,14 @@ #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 @@ -38,7 +37,7 @@ private: vector heads_; - void make_trill (Stream_event *); + void make_trill (Music *); }; Pitched_trill_engraver::Pitched_trill_engraver () @@ -62,18 +61,18 @@ Pitched_trill_engraver::acknowledge_note_head (Grob_info info) 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"); @@ -83,7 +82,8 @@ Pitched_trill_engraver::make_trill (Stream_event *ev) 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_) { @@ -91,7 +91,7 @@ Pitched_trill_engraver::make_trill (Stream_event *ev) 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; @@ -100,21 +100,21 @@ Pitched_trill_engraver::make_trill (Stream_event *ev) 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); } } @@ -144,16 +144,11 @@ ADD_ACKNOWLEDGER (Pitched_trill_engraver, dots); 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 */ ""); diff --git a/lily/pointer-group-interface.cc b/lily/pointer-group-interface.cc index 2d58941b72..1ab1d02c6e 100644 --- a/lily/pointer-group-interface.cc +++ b/lily/pointer-group-interface.cc @@ -42,7 +42,7 @@ Pointer_group_interface::get_grob_array (Grob *me, SCM sym) { 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; } diff --git a/lily/prob-scheme.cc b/lily/prob-scheme.cc index bfa355d9a2..ceadabdd69 100644 --- a/lily/prob-scheme.cc +++ b/lily/prob-scheme.cc @@ -16,7 +16,7 @@ LY_DEFINE (ly_prob_set_property_x, "ly:prob-set-property!", 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; } @@ -70,7 +70,7 @@ LY_DEFINE (ly_make_prob, "ly:make-prob", SCM sym = scm_car (s); SCM val = scm_cadr (s); - pr->set_property (sym, val); + pr->internal_set_property (sym, val); } return pr->unprotect (); diff --git a/lily/prob.cc b/lily/prob.cc index bff24e5ade..5a1caca155 100644 --- a/lily/prob.cc +++ b/lily/prob.cc @@ -25,7 +25,6 @@ Prob::Prob (SCM type, SCM immutable_init) smobify_self (); } - Prob::~Prob () { } @@ -99,11 +98,7 @@ Prob::internal_get_property (SCM sym) const } 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); diff --git a/lily/program-option.cc b/lily/program-option.cc index 9ec4901c85..215bcfe0b9 100644 --- a/lily/program-option.cc +++ b/lily/program-option.cc @@ -48,7 +48,7 @@ void internal_set_option (SCM var, SCM 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)); @@ -58,12 +58,12 @@ void internal_set_option (SCM var, SCM 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)); @@ -133,7 +133,7 @@ get_help_string () } string help ("Options supported by ly:set-option\n\n"); - vector_sort (opts, less ()); + vector_sort (opts, string_compare); for (vsize i = 0; i < opts.size (); i++) help += opts[i]; diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc index cfa6fb6286..a4c993b756 100644 --- a/lily/property-iterator.cc +++ b/lily/property-iterator.cc @@ -22,10 +22,16 @@ bool check_grob (Music *mus, SCM sym); 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); } @@ -33,21 +39,22 @@ void 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 (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; } @@ -102,33 +109,27 @@ Push_property_iterator::process (Moment m) 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 (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; } @@ -155,10 +156,7 @@ Pop_property_iterator::process (Moment m) 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); } @@ -167,3 +165,4 @@ IMPLEMENT_CTOR_CALLBACK (Pop_property_iterator); IMPLEMENT_CTOR_CALLBACK (Push_property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_unset_iterator); + diff --git a/lily/quote-iterator.cc b/lily/quote-iterator.cc index dead1d503e..9ca8fd25b7 100644 --- a/lily/quote-iterator.cc +++ b/lily/quote-iterator.cc @@ -9,13 +9,11 @@ #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 @@ -35,7 +33,7 @@ public: 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; @@ -54,14 +52,16 @@ Quote_iterator::do_quit () } 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; } @@ -230,12 +230,11 @@ Quote_iterator::process (Moment m) { 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; @@ -246,11 +245,14 @@ Quote_iterator::process (Moment m) 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); } } diff --git a/lily/recording-group-engraver.cc b/lily/recording-group-engraver.cc index 896ad6f694..c0091cc834 100644 --- a/lily/recording-group-engraver.cc +++ b/lily/recording-group-engraver.cc @@ -4,17 +4,11 @@ source file of the GNU LilyPond music typesetter (c) 2003--2006 Han-Wen Nienhuys - -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 { @@ -57,7 +51,7 @@ Recording_group_engraver::finalize () 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; diff --git a/lily/relocate.cc b/lily/relocate.cc index ac4c31bac4..8cb2b0861f 100644 --- a/lily/relocate.cc +++ b/lily/relocate.cc @@ -385,7 +385,7 @@ read_relocation_file (string filename) 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); @@ -394,11 +394,14 @@ read_relocation_file (string filename) 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 ()); + } + } } diff --git a/lily/repeat-tie-engraver.cc b/lily/repeat-tie-engraver.cc index c793449dda..4bce211310 100644 --- a/lily/repeat-tie-engraver.cc +++ b/lily/repeat-tie-engraver.cc @@ -11,20 +11,19 @@ #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 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); }; @@ -43,11 +42,11 @@ Repeat_tie_engraver::stop_translation_timestep () 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 @@ -70,6 +69,8 @@ Repeat_tie_engraver::acknowledge_note_head (Grob_info inf) semi_ties_.push_back (semi_tie); } + + ADD_ACKNOWLEDGER (Repeat_tie_engraver, note_head); ADD_TRANSLATOR (Repeat_tie_engraver, /* doc */ "Create Laissez vibrer items.", diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index 959bf2156b..589dd0dbec 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -40,7 +40,7 @@ Rest_collision::force_shift_callback (SCM smob) 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) { @@ -51,8 +51,7 @@ 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 ()); @@ -152,7 +151,7 @@ Rest_collision::calc_positioning_done (SCM smob) 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) ; @@ -213,14 +212,13 @@ Rest_collision::calc_positioning_done (SCM smob) 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); @@ -234,10 +232,9 @@ Rest_collision::calc_positioning_done (SCM smob) 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) { @@ -246,16 +243,13 @@ Rest_collision::calc_positioning_done (SCM smob) } // 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; } diff --git a/lily/rest-engraver.cc b/lily/rest-engraver.cc index 68ec862843..7dffbeb9dd 100644 --- a/lily/rest-engraver.cc +++ b/lily/rest-engraver.cc @@ -8,25 +8,23 @@ #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); }; @@ -55,8 +53,29 @@ Rest_engraver::process_music () 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 (); @@ -69,16 +88,22 @@ Rest_engraver::process_music () } } -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 */ ""); diff --git a/lily/rest.cc b/lily/rest.cc index d7351d648a..b274aab872 100644 --- a/lily/rest.cc +++ b/lily/rest.cc @@ -27,9 +27,9 @@ Rest::y_offset_callback (SCM smob) 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) { diff --git a/lily/scale.cc b/lily/scale.cc deleted file mode 100644 index b71f43fe20..0000000000 --- a/lily/scale.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - scale.cc -- implement Scale - - source file of the GNU LilyPond music typesetter - - (c) 2006 Han-Wen Nienhuys - -*/ - -#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 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 ("#", 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); diff --git a/lily/score-context.cc b/lily/score-context.cc new file mode 100644 index 0000000000..1191856546 --- /dev/null +++ b/lily/score-context.cc @@ -0,0 +1,50 @@ +/* + score-context.cc -- implement Score_context + + source file of the GNU LilyPond music typesetter + + (c) 2004--2006 Han-Wen Nienhuys +*/ + +#include "score-context.hh" + +#include "score-translator.hh" + +void +Score_context::prepare (Moment w) +{ + Translator_group *t = implementation (); + Score_translator *s = dynamic_cast (t); + + s->prepare (w); +} + +void +Score_context::finish () +{ + Translator_group *t = implementation (); + Score_translator *s = dynamic_cast (t); + + s->finish (); +} + +void +Score_context::one_time_step () +{ + Translator_group *t = implementation (); + Score_translator *s = dynamic_cast (t); + s->one_time_step (); +} + +SCM +Score_context::get_output () +{ + Translator_group *t = implementation (); + Score_translator *s = dynamic_cast (t); + return s->get_output (); +} + +Score_context::Score_context (Object_key const *key) + : Context (key) +{ +} diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index c81c5fce6b..ba80e75bb6 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -11,7 +11,6 @@ #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" @@ -20,7 +19,6 @@ #include "paper-column-engraver.hh" #include "paper-column.hh" #include "paper-score.hh" -#include "stream-event.hh" #include "system.hh" #include "warn.hh" @@ -35,19 +33,20 @@ Score_engraver::derived_mark () const { 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, @@ -76,7 +75,6 @@ Score_engraver::initialize () pscore_ = new Paper_score (dynamic_cast (context ()->get_output_def ())); pscore_->unprotect (); - context ()->set_property ("output", pscore_->self_scm ()); SCM props = updated_grob_properties (context (), ly_symbol2scm ("System")); @@ -89,39 +87,16 @@ Score_engraver::initialize () 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"))) { @@ -157,6 +132,22 @@ Score_engraver::typeset_all () 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 " @@ -170,7 +161,7 @@ ADD_TRANSLATOR_GROUP (Score_engraver, "System ", /* accept */ - "", + "break-event", /* read */ "currentMusicalColumn " diff --git a/lily/score-performer.cc b/lily/score-performer.cc index 2bdfdd54b9..5bff2797da 100644 --- a/lily/score-performer.cc +++ b/lily/score-performer.cc @@ -6,22 +6,18 @@ (c) 1996--2006 Jan Nieuwenhuizen */ +#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 */ "", @@ -34,7 +30,6 @@ Score_performer::Score_performer () { performance_ = 0; skipping_ = false; - audio_column_ = 0; } Score_performer::~Score_performer () @@ -42,65 +37,29 @@ Score_performer::~Score_performer () } void -Score_performer::announce_element (Audio_element_info info) -{ - announce_infos_.push_back (info); - if (Audio_staff *s = dynamic_cast (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 (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 (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, @@ -108,9 +67,8 @@ Score_performer::finish (SCM) 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"))) { @@ -136,12 +94,27 @@ Score_performer::one_time_step (SCM) 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 (); } @@ -150,11 +123,7 @@ Score_performer::initialize () { performance_ = new Performance; performance_->unprotect (); - context ()->set_property ("output", performance_->self_scm ()); performance_->midi_ = context ()->get_output_def (); - Translator_group::initialize (); } - - diff --git a/lily/score-translator.cc b/lily/score-translator.cc new file mode 100644 index 0000000000..5d2cbc4093 --- /dev/null +++ b/lily/score-translator.cc @@ -0,0 +1,31 @@ +/* + score-translator.cc -- implement Score_translator + + source file of the GNU LilyPond music typesetter + + (c) 2004--2006 Han-Wen Nienhuys +*/ + +#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 () +{ +} diff --git a/lily/score.cc b/lily/score.cc index 3f00330e61..99ec51880a 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -28,21 +28,13 @@ using namespace std; #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 () @@ -61,8 +53,6 @@ Score::mark_smob (SCM s) 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_; } @@ -75,13 +65,12 @@ Score::print_smob (SCM, SCM p, scm_print_state*) } 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) diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index e25405b732..9a06474c6b 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -19,14 +19,11 @@ #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 () { @@ -38,12 +35,14 @@ struct Script_tuple class Script_engraver : public Engraver { vector 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); @@ -55,23 +54,28 @@ public: 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 @@ -81,7 +85,7 @@ copy_property (Grob *g, SCM sym, SCM alist) { 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)); } } @@ -89,9 +93,8 @@ copy_property (Grob *g, SCM sym, SCM alist) 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); @@ -133,7 +136,7 @@ make_script_from_event (Grob *p, Context *tg, 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) @@ -150,17 +153,17 @@ Script_engraver::process_music () { 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); } @@ -196,7 +199,7 @@ Script_engraver::acknowledge_stem_tremolo (Grob_info info) 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++) { @@ -231,12 +234,21 @@ Script_engraver::acknowledge_note_column (Grob_info info) } } +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); diff --git a/lily/semi-tie-column.cc b/lily/semi-tie-column.cc index 055b377c72..a7542249b1 100644 --- a/lily/semi-tie-column.cc +++ b/lily/semi-tie-column.cc @@ -45,7 +45,7 @@ Semi_tie_column::calc_positioning_done (SCM smob) extract_grob_set (me, "ties", lv_ro_ties); vector lv_ties (lv_ro_ties); - vector_sort (lv_ties, Semi_tie::less); + vector_sort (lv_ties, &Semi_tie::compare); Ties_configuration ties_config; diff --git a/lily/semi-tie.cc b/lily/semi-tie.cc index fbc98f20aa..bddae0e2b2 100644 --- a/lily/semi-tie.cc +++ b/lily/semi-tie.cc @@ -70,10 +70,10 @@ Semi_tie::get_position (Grob *me) 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)); } diff --git a/lily/sequential-iterator.cc b/lily/sequential-iterator.cc index db8eb5865e..86bacecf48 100644 --- a/lily/sequential-iterator.cc +++ b/lily/sequential-iterator.cc @@ -42,12 +42,7 @@ Sequential_iterator::Sequential_iterator () 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 @@ -176,7 +171,7 @@ Sequential_iterator::next_element (bool) in that chunk should be in len.grace_part_ */ - last_mom_ = here_mom_; + last_mom_ = here_mom_;; here_mom_ += len; } diff --git a/lily/sequential-music-iterator.cc b/lily/sequential-music-iterator.cc new file mode 100644 index 0000000000..f933df7bb4 --- /dev/null +++ b/lily/sequential-music-iterator.cc @@ -0,0 +1,20 @@ +/* + sequential-music-iterator.cc -- implement Sequential_music_iterator + + source file of the GNU LilyPond music typesetter + + (c) 1997--2006 Han-Wen Nienhuys +*/ + +#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"); +} diff --git a/lily/side-position-interface.cc b/lily/side-position-interface.cc index 38880cb52e..4964c47572 100644 --- a/lily/side-position-interface.cc +++ b/lily/side-position-interface.cc @@ -46,15 +46,9 @@ Side_position_interface::get_direction (Grob *me) } /* 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); @@ -73,7 +67,7 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten 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); @@ -84,10 +78,10 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten 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)); } } @@ -97,7 +91,7 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten 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; @@ -107,25 +101,6 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten && 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) @@ -143,67 +118,50 @@ Side_position_interface::general_side_position (Grob *me, Axis a, bool use_exten 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 @@ -216,8 +174,8 @@ Side_position_interface::aligned_side (Grob *me, Axis a, bool pure, int start, i 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); @@ -234,15 +192,13 @@ Side_position_interface::aligned_side (Grob *me, Axis a, bool pure, int start, i } 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); } @@ -256,11 +212,11 @@ Side_position_interface::set_axis (Grob *me, Axis a) 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 diff --git a/lily/simple-closure.cc b/lily/simple-closure.cc index 77764b2bc6..40efbdd727 100644 --- a/lily/simple-closure.cc +++ b/lily/simple-closure.cc @@ -63,7 +63,7 @@ evaluate_with_simple_closure (SCM delayed_argument, } 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; @@ -107,4 +107,4 @@ void init_simple_closure () -ADD_SCM_INIT_FUNC (simple_closure, init_simple_closure); +ADD_SCM_INIT_FUNC(simple_closure, init_simple_closure); diff --git a/lily/simple-spacer.cc b/lily/simple-spacer.cc index bb4104678a..0c595f1d94 100644 --- a/lily/simple-spacer.cc +++ b/lily/simple-spacer.cc @@ -59,20 +59,18 @@ 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_; } @@ -131,11 +129,11 @@ Simple_spacer::range_stiffness (int l, int r) const } 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; } @@ -143,24 +141,29 @@ Simple_spacer::configuration_length (Real force) const 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++) @@ -174,7 +177,7 @@ Real 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; @@ -194,18 +197,8 @@ Simple_spacer::compress_line () 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_; @@ -218,22 +211,22 @@ Simple_spacer::compress_line () 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 @@ -243,7 +236,7 @@ Simple_spacer::spring_positions () const 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; } @@ -261,9 +254,7 @@ Spring_description::is_sane () const { return (inverse_hooke_ >= 0) && ideal_ > 0 - && !isinf (ideal_) && !isnan (ideal_) - && (inverse_hooke_ == 0.0 || fabs (inverse_hooke_) > 1e-8) - ; + && !isinf (ideal_) && !isnan (ideal_); } Real @@ -288,50 +279,37 @@ Spring_description::length (Real f) const 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 rods_; - vector end_rods_; /* use these if they end at the last column of the line */ + vector rods_; + vector 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) { @@ -356,6 +334,20 @@ next_spaceable_column (vector const &list, vsize starting) 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 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 (list[i])->find_prebroken_piece (LEFT); +} + static void get_column_spring (Grob *this_col, Grob *next_col, Real *ideal, Real *inv_hooke) { @@ -379,70 +371,64 @@ 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 const &cols, vsize col_index, bool line_starter) +static Column_desc +get_column_desc (vector 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 (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 -get_line_forces (vector const &columns, +get_line_forces (vector const &icols, vector breaks, Real line_len, Real indent, bool ragged) { - vector breaks; vector force; - vector non_loose; - vector 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 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++) @@ -452,7 +438,7 @@ get_line_forces (vector const &columns, 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++) @@ -470,23 +456,10 @@ get_line_forces (vector const &columns, } } 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; } } @@ -495,12 +468,12 @@ get_line_forces (vector const &columns, } Column_x_positions -get_line_configuration (vector const &columns, +get_line_configuration (vectorconst &columns, Real line_len, Real indent, bool ragged) { - vector cols; + vector cols; Simple_spacer spacer; Column_x_positions ret; @@ -514,24 +487,18 @@ get_line_configuration (vector const &columns, } ret.cols_.push_back (dynamic_cast (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 (); @@ -559,3 +526,9 @@ get_line_configuration (vector const &columns, 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); +} diff --git a/lily/simultaneous-music-iterator.cc b/lily/simultaneous-music-iterator.cc index 62d3b3c200..a264d55ba9 100644 --- a/lily/simultaneous-music-iterator.cc +++ b/lily/simultaneous-music-iterator.cc @@ -51,14 +51,14 @@ Simultaneous_music_iterator::construct_children () 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 ()) diff --git a/lily/slash-repeat-engraver.cc b/lily/slash-repeat-engraver.cc index 16d5c4ba5f..aa5b52c405 100644 --- a/lily/slash-repeat-engraver.cc +++ b/lily/slash-repeat-engraver.cc @@ -3,22 +3,18 @@ source file of the GNU LilyPond music typesetter - (c) 2000--2006 Han-Wen Nienhuys , Erik Sandberg - + (c) 2000--2006 Han-Wen Nienhuys , Erik Sandberg */ -#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 @@ -29,9 +25,9 @@ class Slash_repeat_engraver : public Engraver 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 (); }; @@ -40,21 +36,24 @@ Slash_repeat_engraver::Slash_repeat_engraver () 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 @@ -67,6 +66,8 @@ Slash_repeat_engraver::process_music () } } +#include "translator.icc" + ADD_TRANSLATOR (Slash_repeat_engraver, /* doc */ "Make beat repeats.", /* create */ "RepeatSlash", diff --git a/lily/slur-configuration.cc b/lily/slur-configuration.cc index b1ce277351..3aabe8407d 100644 --- a/lily/slur-configuration.cc +++ b/lily/slur-configuration.cc @@ -166,7 +166,6 @@ Slur_configuration::generate_curve (Slur_score_state const &state, Slur_configuration::Slur_configuration () { - tags_ = 0x0; score_ = 0.0; index_ = -1; }; diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 55080f092b..0e649fe566 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -14,22 +14,8 @@ #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 @@ -37,15 +23,16 @@ */ class Slur_engraver : public Engraver { - Drul_array events_; - Stream_event *running_slur_start_; + Drul_array events_; + Music *running_slur_start_; vector slurs_; vector 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); @@ -54,13 +41,10 @@ protected: 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); @@ -71,16 +55,24 @@ Slur_engraver::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 @@ -164,14 +156,13 @@ Slur_engraver::process_music () 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")); @@ -196,12 +187,12 @@ Slur_engraver::process_music () 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); diff --git a/lily/slur-performer.cc b/lily/slur-performer.cc index 447897d8b6..b699058f21 100644 --- a/lily/slur-performer.cc +++ b/lily/slur-performer.cc @@ -10,10 +10,8 @@ #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. @@ -25,14 +23,13 @@ public: 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_; }; @@ -72,19 +69,26 @@ Slur_performer::start_translation_timestep () 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", "", ""); + diff --git a/lily/slur-scoring.cc b/lily/slur-scoring.cc index 6371082b07..f4b312e5bd 100644 --- a/lily/slur-scoring.cc +++ b/lily/slur-scoring.cc @@ -354,16 +354,8 @@ Slur_score_state::get_best_curve () 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); @@ -395,6 +387,7 @@ Slur_score_state::get_best_curve () } else { + programming_error ("No optimal slur found. Guessing 0."); total = "no sol?"; } @@ -403,12 +396,6 @@ Slur_score_state::get_best_curve () } #endif - if (opt_idx < 0) - { - opt_idx = 0; - programming_error ("No optimal slur found. Guessing 0."); - } - return configurations_[opt_idx]->curve_; } diff --git a/lily/slur.cc b/lily/slur.cc index d8c81f7836..92610d47e7 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -57,35 +57,6 @@ Slur::calc_direction (SCM smob) 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) @@ -165,7 +136,7 @@ Slur::get_curve (Grob *me) { 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)); @@ -186,7 +157,7 @@ Slur::add_extra_encompass (Grob *me, Grob *n) } -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) { @@ -216,8 +187,8 @@ 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"), @@ -258,7 +229,7 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) 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); } /* @@ -266,8 +237,7 @@ Slur::outside_slur_callback (SCM grob, SCM offset_scm) */ void Slur::auxiliary_acknowledge_extra_object (Grob_info info, - vector &slurs, - vector &end_slurs) + vector& slurs, vector& end_slurs) { if (slurs.empty () && end_slurs.empty ()) return; @@ -316,13 +286,12 @@ ADD_INTERFACE (Slur, "slur-interface", "eccentricity " "encompass-objects " "height-limit " - "inspect-quants " - "inspect-index " "line-thickness " "note-columns " "positions " "quant-score " "ratio " "thickness " + ); diff --git a/lily/smobs.cc b/lily/smobs.cc index fff178ccb2..a6fdc76b9e 100644 --- a/lily/smobs.cc +++ b/lily/smobs.cc @@ -11,60 +11,51 @@ /* 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); @@ -72,5 +63,4 @@ unprotect_smob (SCM smob, SCM *prot_cons) } *prot_cons = SCM_EOL; -#endif } diff --git a/lily/source-file.cc b/lily/source-file.cc index 57d67b464b..902baa0e47 100644 --- a/lily/source-file.cc +++ b/lily/source-file.cc @@ -34,17 +34,19 @@ using namespace std; 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 -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. */ @@ -52,17 +54,15 @@ gulp_file (string filename, int desired_size) if (!f) { warning (_f ("can't open file: `%s'", filename.c_str ())); - - vector 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); @@ -74,75 +74,60 @@ gulp_file (string filename, int desired_size) warning (_f ("expected to read %d characters, got %d", bytes_read, read_count)); fclose (f); - int filesize = bytes_read; - - vector 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 () @@ -201,6 +186,8 @@ Source_file::name_string () const Source_file::~Source_file () { delete istream_; + istream_ = 0; + delete[] contents_str0_; } Slice @@ -326,69 +313,82 @@ Source_file::get_line (char const *pos_str0) const 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 ()); + 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 ("#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_; +} diff --git a/lily/source.cc b/lily/source.cc index 9d978d4fae..002768038c 100644 --- a/lily/source.cc +++ b/lily/source.cc @@ -58,10 +58,7 @@ Sources::add (Source_file *sourcefile) Sources::~Sources () { - for (vsize i = 0; i < sourcefiles_.size (); i++) - { - sourcefiles_[i]->unprotect (); - } + junk_pointers (sourcefiles_); } Source_file * diff --git a/lily/spacing-basic.cc b/lily/spacing-basic.cc index fcae3dfcc2..659d3f8b8e 100644 --- a/lily/spacing-basic.cc +++ b/lily/spacing-basic.cc @@ -9,6 +9,7 @@ #include "spacing-spanner.hh" #include "moment.hh" #include "paper-column.hh" +#include "misc.hh" #include "warn.hh" /* @@ -16,6 +17,54 @@ 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. @@ -70,7 +119,7 @@ Spacing_spanner::standard_breakable_column_spacing (Grob *me, Item *l, Item *r, else { bool dummy; - *space = *fixed + options->get_duration_space (dt.main_part_, &dummy); + *space = *fixed + options->get_duration_space (dt, &dummy); } } } @@ -80,8 +129,6 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc, Spacing_options const *options, bool *expand_only) { - (void) me; - Moment shortest_playing_len = 0; SCM s = lc->get_property ("shortest-playing-duration"); @@ -122,7 +169,7 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc, 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_); } @@ -133,19 +180,39 @@ Spacing_spanner::note_spacing (Grob *me, Grob *lc, Grob *rc, 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); +} diff --git a/lily/spacing-determine-loose-columns.cc b/lily/spacing-determine-loose-columns.cc index 93f70b5cec..34f4c97214 100644 --- a/lily/spacing-determine-loose-columns.cc +++ b/lily/spacing-determine-loose-columns.cc @@ -32,8 +32,7 @@ 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; diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index 914c672ccd..d567cb6ebc 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -6,15 +6,13 @@ (c) 1999--2006 Han-Wen Nienhuys */ +#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" @@ -34,21 +32,9 @@ struct Rhythmic_tuple 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. @@ -60,68 +46,50 @@ class Spacing_engraver : public Engraver vector 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_) { @@ -156,10 +124,10 @@ Spacing_engraver::acknowledge_rhythmic_head (Grob_info i) */ 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); } @@ -172,14 +140,6 @@ Spacing_engraver::stop_translation_timestep () Paper_column *musical_column = dynamic_cast (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)) { @@ -192,10 +152,10 @@ Spacing_engraver::stop_translation_timestep () 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); } } @@ -204,7 +164,7 @@ Spacing_engraver::stop_translation_timestep () 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); @@ -223,16 +183,11 @@ Spacing_engraver::stop_translation_timestep () 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_) @@ -248,8 +203,7 @@ ADD_TRANSLATOR (Spacing_engraver, "bookkeeping of shortest starting and playing notes ", /* create */ "SpacingSpanner", - /* accept */ - "spacing-section-event ", + /* accept */ "", /* read */ "currentMusicalColumn " "currentCommandColumn " diff --git a/lily/spacing-loose-columns.cc b/lily/spacing-loose-columns.cc index 13a37071c0..0570741117 100644 --- a/lily/spacing-loose-columns.cc +++ b/lily/spacing-loose-columns.cc @@ -13,7 +13,7 @@ #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 @@ -25,6 +25,7 @@ set_loose_columns (System *which, Column_x_positions const *posns) if (!loose_col_count) return; + Real default_padding = 1.0; for (int i = 0; i < loose_col_count; i++) { int divide_over = 1; @@ -68,81 +69,73 @@ set_loose_columns (System *which, Column_x_positions const *posns) if (!right->get_system ()) right = right->find_prebroken_piece (LEFT); - Grob *common = right->common_refpoint (left, X_AXIS); - clique.push_back (right); - vector 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 (clique[j]); - Paper_column *next_col = dynamic_cast (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 (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; } - } } diff --git a/lily/spacing-options.cc b/lily/spacing-options.cc deleted file mode 100644 index 916408aa73..0000000000 --- a/lily/spacing-options.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - spacing-options.cc -- implement Spacing_options - - source file of the GNU LilyPond music typesetter - - (c) 2006 Han-Wen Nienhuys - -*/ - -#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_; - } -} - diff --git a/lily/spacing-spanner.cc b/lily/spacing-spanner.cc index 2f6e90326c..4c301b6a64 100644 --- a/lily/spacing-spanner.cc +++ b/lily/spacing-spanner.cc @@ -26,34 +26,48 @@ using namespace std; #include "system.hh" #include "warn.hh" -vector -Spacing_spanner::get_columns (Spanner *me) + +/* + TODO: + + use callback instead? + +*/ +Rational +Spacing_spanner::effective_shortest_duration (Grob *me, + vector const &all) { - vector 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::vector (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 all (get_columns (me)); + vector 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); @@ -71,15 +85,9 @@ Spacing_spanner::set_springs (SCM smob) 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 const &cols) { - Spanner *me = unsmob_spanner (grob); - - vector cols (get_columns (me)); - /* ascending in duration */ @@ -157,7 +165,7 @@ Spacing_spanner::calc_common_shortest_duration (SCM grob) if (max_idx >= 0) d = min (d, durations[max_idx]); - return Moment (d).smobbed_copy (); + return d; } void @@ -264,11 +272,12 @@ Spacing_spanner::musical_column_spacing (Grob *me, if (!lext.is_empty ()) compound_note_space += -lext[LEFT]; } + } else { int wish_count = 0; - + extract_grob_set (left_col, "right-neighbors", neighbors); /* @@ -316,33 +325,8 @@ Spacing_spanner::musical_column_spacing (Grob *me, 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"))) { @@ -505,22 +489,19 @@ ADD_INTERFACE (Spacing_spanner, "spacing-spanner-interface", "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.", - ""); diff --git a/lily/span-bar-engraver.cc b/lily/span-bar-engraver.cc index c46b3d1db0..503bdf265b 100644 --- a/lily/span-bar-engraver.cc +++ b/lily/span-bar-engraver.cc @@ -65,7 +65,7 @@ Span_bar_engraver::stop_translation_timestep () 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; } diff --git a/lily/span-bar.cc b/lily/span-bar.cc index 5c1c76e855..84fe893a0c 100644 --- a/lily/span-bar.cc +++ b/lily/span-bar.cc @@ -72,7 +72,7 @@ Span_bar::print (SCM smobbed_me) 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++) diff --git a/lily/span-dynamic-performer.cc b/lily/span-dynamic-performer.cc index 4da025d57d..3d8d053be2 100644 --- a/lily/span-dynamic-performer.cc +++ b/lily/span-dynamic-performer.cc @@ -10,9 +10,7 @@ #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 @@ -33,17 +31,16 @@ public: 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 span_events_; + Music *span_start_event_; + Drul_array span_events_; vector dynamic_tuples_; vector finished_dynamic_tuples_; Direction dir_; @@ -98,7 +95,7 @@ Span_dynamic_performer::process_music () 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]; @@ -158,6 +155,7 @@ Span_dynamic_performer::stop_translation_timestep () if (audio_) { + play_element (audio_); audio_ = 0; } @@ -165,21 +163,19 @@ Span_dynamic_performer::stop_translation_timestep () 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, "", "", diff --git a/lily/spanner.cc b/lily/spanner.cc index 77285e8ed1..bb6f743a24 100644 --- a/lily/spanner.cc +++ b/lily/spanner.cc @@ -124,7 +124,7 @@ Spanner::do_break_processing () } } } - 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; } @@ -238,7 +238,7 @@ Spanner::get_system () const 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; @@ -250,12 +250,6 @@ Spanner::compare (Spanner *const &p1, Spanner *const &p2) 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 { @@ -327,14 +321,10 @@ Spanner::set_spacing_rods (SCM smob) Spanner *sp = dynamic_cast (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; } diff --git a/lily/staff-collecting-engraver.cc b/lily/staff-collecting-engraver.cc index a7ee6d181a..fe522a0497 100644 --- a/lily/staff-collecting-engraver.cc +++ b/lily/staff-collecting-engraver.cc @@ -16,7 +16,6 @@ class Staff_collecting_engraver : public Engraver public: TRANSLATOR_DECLARATIONS (Staff_collecting_engraver); DECLARE_ACKNOWLEDGER (staff_symbol); - DECLARE_END_ACKNOWLEDGER (staff_symbol); }; Staff_collecting_engraver::Staff_collecting_engraver () @@ -32,19 +31,8 @@ Staff_collecting_engraver::acknowledge_staff_symbol (Grob_info gi) 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", diff --git a/lily/staff-performer.cc b/lily/staff-performer.cc index c73ab6eb81..b8facd2364 100644 --- a/lily/staff-performer.cc +++ b/lily/staff-performer.cc @@ -64,11 +64,14 @@ Staff_performer::initialize () { 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 @@ -88,6 +91,8 @@ Staff_performer::process_music () /* Have to be here before notes arrive into the staff. */ + play_element (instrument_); + play_element (instrument_name_); } } @@ -100,10 +105,12 @@ Staff_performer::stop_translation_timestep () 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; @@ -113,6 +120,7 @@ Staff_performer::stop_translation_timestep () void Staff_performer::finalize () { + Performer::play_element (audio_staff_); audio_staff_ = 0; } diff --git a/lily/staff-symbol-engraver.cc b/lily/staff-symbol-engraver.cc index 242e06e46a..4eee00b116 100644 --- a/lily/staff-symbol-engraver.cc +++ b/lily/staff-symbol-engraver.cc @@ -6,36 +6,8 @@ (c) 1997--2006 Han-Wen Nienhuys */ -#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 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 () { @@ -51,15 +23,17 @@ 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 @@ -82,27 +56,14 @@ 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; } @@ -110,8 +71,10 @@ void 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; } @@ -145,8 +108,8 @@ Staff_symbol_engraver::acknowledge_grob (Grob_info s) } } +#include "translator.icc" ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob); - ADD_TRANSLATOR (Staff_symbol_engraver, /* doc */ "Create the constellation of five (default) " "staff lines.", diff --git a/lily/staff-symbol-referencer.cc b/lily/staff-symbol-referencer.cc index aa45e55e7a..cfde343029 100644 --- a/lily/staff-symbol-referencer.cc +++ b/lily/staff-symbol-referencer.cc @@ -110,6 +110,7 @@ Staff_symbol_referencer::callback (SCM smob) { 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); @@ -156,13 +157,6 @@ compare_position (Grob *const &a, Grob *const &b) - 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. " diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc index d9d278799d..797406b4fb 100644 --- a/lily/stem-engraver.cc +++ b/lily/stem-engraver.cc @@ -19,9 +19,6 @@ #include "staff-symbol-referencer.hh" #include "stem-tremolo.hh" #include "stem.hh" -#include "stream-event.hh" - -#include "translator.icc" /** Make stems upon receiving noteheads. @@ -30,17 +27,17 @@ class Stem_engraver : public Engraver { 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 () @@ -58,6 +55,15 @@ Stem_engraver::make_stem (Grob_info gi) 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, @@ -80,14 +86,6 @@ Stem_engraver::make_stem (Grob_info gi) 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) @@ -116,7 +114,7 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi) 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")); @@ -129,9 +127,9 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi) 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 ()); @@ -161,30 +159,30 @@ Stem_engraver::stop_translation_timestep () 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 */ ""); diff --git a/lily/stem-tremolo.cc b/lily/stem-tremolo.cc index 6729aa934c..f15d2c4154 100644 --- a/lily/stem-tremolo.cc +++ b/lily/stem-tremolo.cc @@ -83,8 +83,7 @@ Stem_tremolo::get_beam_translation (Grob *me) 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 @@ -119,7 +118,7 @@ Stem_tremolo::raw_stencil (Grob *me, Real slope, Direction stemdir) 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++) @@ -142,34 +141,40 @@ Stem_tremolo::height (SCM smob) /* 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); @@ -202,17 +207,7 @@ Stem_tremolo::translated_stencil (Grob *me, Real slope) } 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", diff --git a/lily/stem.cc b/lily/stem.cc index 6a0fb43485..a25c37f777 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -65,9 +65,7 @@ Stem::get_beaming (Grob *me, Direction d) return 0; SCM lst = index_get_cell (pair, d); - - int len = scm_ilength (lst); - return max (len, 0); + return scm_ilength (lst); } Interval @@ -180,6 +178,12 @@ Stem::extremal_heads (Grob *me) return exthead; } +static int +integer_compare (int const &a, int const &b) +{ + return a - b; +} + /* The positions, in ascending order. */ vector Stem::note_head_positions (Grob *me) @@ -195,7 +199,7 @@ Stem::note_head_positions (Grob *me) ps.push_back (p); } - vector_sort (ps, less ()); + vector_sort (ps, integer_compare); return ps; } @@ -221,32 +225,6 @@ Stem::is_invisible (Grob *me) && 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) @@ -256,11 +234,6 @@ 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); @@ -404,7 +377,7 @@ Stem::calc_positioning_done (SCM smob) extract_grob_set (me, "note-heads", ro_heads); vector heads (ro_heads); - vector_sort (heads, position_less); + vector_sort (heads, compare_position); Direction dir = get_grob_direction (me); if (dir < 0) @@ -680,8 +653,6 @@ SCM Stem::print (SCM smob) { Grob *me = unsmob_grob (smob); - Grob *beam = get_beam (me); - Stencil mol; Direction d = get_grob_direction (me); @@ -695,6 +666,7 @@ Stem::print (SCM smob) = 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; diff --git a/lily/stencil-scheme.cc b/lily/stencil-scheme.cc index 2669e14808..66f1825931 100644 --- a/lily/stencil-scheme.cc +++ b/lily/stencil-scheme.cc @@ -213,37 +213,23 @@ LY_DEFINE (ly_stencil_add, "ly:stencil-add", } 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 (); } diff --git a/lily/stencil.cc b/lily/stencil.cc index 329c5cae61..dd3bb2626e 100644 --- a/lily/stencil.cc +++ b/lily/stencil.cc @@ -10,7 +10,7 @@ #include "main.hh" #include "font-metric.hh" -#include "input.hh" +#include "input-smob.hh" #include "string-convert.hh" #include "warn.hh" @@ -201,6 +201,7 @@ Stencil::moved_to_edge (Axis a, Direction d, Stencil const &s, { 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]; diff --git a/lily/stream-event-scheme.cc b/lily/stream-event-scheme.cc index ea93654961..bdccd1483b 100644 --- a/lily/stream-event-scheme.cc +++ b/lily/stream-event-scheme.cc @@ -9,21 +9,15 @@ #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") @@ -34,11 +28,3 @@ LY_DEFINE (ly_event_property, "ly:event-property", 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); -} diff --git a/lily/stream-event.cc b/lily/stream-event.cc index ff736d8832..f8c868c34a 100644 --- a/lily/stream-event.cc +++ b/lily/stream-event.cc @@ -11,58 +11,82 @@ #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 ("#", 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); @@ -73,21 +97,28 @@ Stream_event::dump (SCM self) { 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 (unsmob_prob (m)); + property_alist_ = scm_assq_set_x (property_alist_, prop, val); } diff --git a/lily/swallow-perf.cc b/lily/swallow-perf.cc index a2e3aa7b85..150e61b274 100644 --- a/lily/swallow-perf.cc +++ b/lily/swallow-perf.cc @@ -20,7 +20,8 @@ protected: 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; diff --git a/lily/system-start-delimiter-engraver.cc b/lily/system-start-delimiter-engraver.cc index dd2151146d..b03c1d20a4 100644 --- a/lily/system-start-delimiter-engraver.cc +++ b/lily/system-start-delimiter-engraver.cc @@ -76,7 +76,8 @@ void 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++) { diff --git a/lily/system-start-text.cc b/lily/system-start-text.cc index 5a90191081..2bc4e507d6 100644 --- a/lily/system-start-text.cc +++ b/lily/system-start-text.cc @@ -13,7 +13,6 @@ #include "font-interface.hh" #include "spanner.hh" #include "stencil.hh" -#include "item.hh" class System_start_text { @@ -57,12 +56,6 @@ System_start_text::print (SCM smob) { 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 elts; for (vsize i = 0; i < all_elts.size (); i++) @@ -88,8 +81,7 @@ System_start_text::print (SCM smob) } 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 (); } diff --git a/lily/system.cc b/lily/system.cc index 07c705ffe6..dda8fdf132 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -23,6 +23,7 @@ #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) @@ -184,7 +185,6 @@ System::get_paper_systems () progress_indication ("["); System *system = dynamic_cast (broken_intos_[i]); - system->post_processing (); scm_vector_set_x (lines, scm_from_int (i), system->get_paper_system ()); @@ -206,11 +206,6 @@ System::break_into_pieces (vector const &breaking) vector 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++) @@ -218,7 +213,6 @@ System::break_into_pieces (vector const &breaking) c[j]->translate_axis (breaking[i].config_[j], X_AXIS); dynamic_cast (c[j])->system_ = system; } - set_loose_columns (system, &breaking[i]); broken_intos_.push_back (system); } @@ -317,7 +311,7 @@ System::post_processing () anyway. */ vector all_elts_sorted (all_elements_->array ()); - vector_sort (all_elts_sorted, std::less ()); + vector_sort (all_elts_sorted, default_compare); uniq (all_elts_sorted); this->get_stencil (); for (vsize i = all_elts_sorted.size (); i--;) @@ -357,7 +351,7 @@ System::get_paper_system () entries.push_back (e); } - vector_sort (entries, std::less ()); + vector_sort (entries, default_compare); for (vsize j = 0; j < entries.size (); j++) { Grob *g = entries[j].grob_; @@ -397,12 +391,14 @@ System::get_paper_system () 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"))) { @@ -508,6 +504,5 @@ ADD_INTERFACE (System, "system-interface", /* properties */ "all-elements " "columns " - "pure-Y-extent " "spaceable-staves " ) diff --git a/lily/tab-note-heads-engraver.cc b/lily/tab-note-heads-engraver.cc index d7e3f9bd66..be9fa38515 100644 --- a/lily/tab-note-heads-engraver.cc +++ b/lily/tab-note-heads-engraver.cc @@ -10,19 +10,16 @@ #include 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 @@ -31,14 +28,14 @@ class Tab_note_heads_engraver : public Engraver { vector notes_; - vector note_events_; - vector tabstring_events_; + vector dots_; + vector note_events_; + vector 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 (); @@ -48,18 +45,23 @@ Tab_note_heads_engraver::Tab_note_heads_engraver () { } -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 @@ -72,17 +74,17 @@ Tab_note_heads_engraver::process_music () 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; } @@ -107,6 +109,22 @@ Tab_note_heads_engraver::process_music () } 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"); @@ -140,27 +158,17 @@ void 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 */ ""); diff --git a/lily/tab-staff-symbol-engraver.cc b/lily/tab-staff-symbol-engraver.cc index 538223bfe8..3483cb86f7 100644 --- a/lily/tab-staff-symbol-engraver.cc +++ b/lily/tab-staff-symbol-engraver.cc @@ -6,23 +6,28 @@ (c) 2005--2006 Han-Wen Nienhuys */ -#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 () @@ -31,12 +36,10 @@ 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", diff --git a/lily/tempo-performer.cc b/lily/tempo-performer.cc index 23ea8fa74f..9a70f9cdc4 100644 --- a/lily/tempo-performer.cc +++ b/lily/tempo-performer.cc @@ -9,10 +9,8 @@ #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 { @@ -22,23 +20,18 @@ public: 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; } @@ -49,19 +42,18 @@ Tempo_performer::~Tempo_performer () 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; } } @@ -70,11 +62,23 @@ Tempo_performer::stop_translation_timestep () { 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", + "", ""); diff --git a/lily/text-engraver.cc b/lily/text-engraver.cc index 2c86f50d67..6a59be8664 100644 --- a/lily/text-engraver.cc +++ b/lily/text-engraver.cc @@ -8,38 +8,39 @@ #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 evs_; + vector evs_; vector 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 @@ -83,7 +84,7 @@ Text_engraver::process_acknowledged () 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 ()); @@ -124,6 +125,8 @@ Text_engraver::Text_engraver () { } +#include "translator.icc" + ADD_ACKNOWLEDGER (Text_engraver, stem); ADD_ACKNOWLEDGER (Text_engraver, stem_tremolo); ADD_ACKNOWLEDGER (Text_engraver, rhythmic_head); diff --git a/lily/text-interface.cc b/lily/text-interface.cc index c249052da5..62375fbb9c 100644 --- a/lily/text-interface.cc +++ b/lily/text-interface.cc @@ -35,7 +35,7 @@ Text_interface::interpret_string (SCM layout_smob, 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); diff --git a/lily/text-spanner-engraver.cc b/lily/text-spanner-engraver.cc index b10832f1b3..d5212ded7f 100644 --- a/lily/text-spanner-engraver.cc +++ b/lily/text-spanner-engraver.cc @@ -11,9 +11,6 @@ #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 { @@ -22,15 +19,15 @@ public: 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 event_drul_; + Music *current_event_; + Drul_array event_drul_; void typeset_all (); }; @@ -43,12 +40,17 @@ Text_spanner_engraver::Text_spanner_engraver () 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 @@ -135,9 +137,10 @@ Text_spanner_engraver::finalize () } } +#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 */ "", diff --git a/lily/tfm-reader.cc b/lily/tfm-reader.cc new file mode 100644 index 0000000000..b416301134 --- /dev/null +++ b/lily/tfm-reader.cc @@ -0,0 +1,292 @@ +/* + tfm-reader.cc -- implement Tex_font_metric_reader + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Jan Nieuwenhuizen + + + 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 *ligatures, vector *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); +} + diff --git a/lily/tfm.cc b/lily/tfm.cc new file mode 100644 index 0000000000..3f415802e4 --- /dev/null +++ b/lily/tfm.cc @@ -0,0 +1,132 @@ +/* + tfm.cc -- implement Tex_font_metric + + source file of the GNU LilyPond music typesetter + + (c) 1999--2006 Jan Nieuwenhuizen + + 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; +} diff --git a/lily/tie-column.cc b/lily/tie-column.cc index 13d5fb0177..e8384f1855 100644 --- a/lily/tie-column.cc +++ b/lily/tie-column.cc @@ -83,7 +83,7 @@ Tie_column::calc_positioning_done (SCM smob) return SCM_BOOL_T; } - vector_sort (ties, Tie::less); + vector_sort (ties, &Tie::compare); Tie_formatting_problem problem; problem.from_ties (ties); diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 1dfb42fa52..39be6c057f 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -16,13 +16,10 @@ #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 @@ -35,23 +32,22 @@ 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 now_heads_; vector heads_to_tie_; vector ties_; @@ -63,7 +59,7 @@ protected: 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: @@ -84,22 +80,19 @@ Tie_engraver::Tie_engraver () 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); } @@ -107,31 +100,23 @@ void 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); @@ -153,25 +138,14 @@ Tie_engraver::start_translation_timestep () { 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++) @@ -181,71 +155,21 @@ Tie_engraver::stop_translation_timestep () tie_column_ = 0; } - vector 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 (); } @@ -272,12 +196,14 @@ Tie_engraver::typeset_tie (Grob *her) 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", diff --git a/lily/tie-formatting-problem.cc b/lily/tie-formatting-problem.cc index d5bd961887..f6d9675d64 100644 --- a/lily/tie-formatting-problem.cc +++ b/lily/tie-formatting-problem.cc @@ -163,24 +163,6 @@ Tie_formatting_problem::set_column_chord_outline (vector bounds, 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 @@ -219,7 +201,7 @@ Tie_formatting_problem::set_chord_outline (vector bounds, for (vsize i = 0; i < bounds.size (); i++) ranks.push_back (bounds[i]->get_column ()->get_rank ()); - vector_sort (ranks, less ()); + vector_sort (ranks, default_compare); uniq (ranks); for (vsize i = 0; i < ranks.size (); i++) @@ -885,6 +867,7 @@ Tie_formatting_problem::find_best_variation (Ties_configuration const &base, Ties_configuration Tie_formatting_problem::generate_optimal_chord_configuration () { + Ties_configuration base = generate_base_chord_configuration (); vector vars = generate_collision_variations (base); diff --git a/lily/tie-performer.cc b/lily/tie-performer.cc index c22fe255ec..bf3c513bcb 100644 --- a/lily/tie-performer.cc +++ b/lily/tie-performer.cc @@ -8,17 +8,16 @@ #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 now_heads_; - vector now_tied_heads_; vector heads_to_tie_; bool ties_created_; @@ -27,8 +26,8 @@ protected: 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); }; @@ -36,14 +35,17 @@ public: 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 @@ -58,17 +60,13 @@ Tie_performer::acknowledge_audio_element (Audio_element_info inf) { if (Audio_note *an = dynamic_cast (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 (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"), @@ -94,22 +92,21 @@ Tie_performer::stop_translation_timestep () 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 */ "", diff --git a/lily/tie.cc b/lily/tie.cc index b4b5206386..3f282071e7 100644 --- a/lily/tie.cc +++ b/lily/tie.cc @@ -28,11 +28,11 @@ #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 @@ -235,7 +235,7 @@ Tie::print (SCM smob) 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++; diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index 9ab2673eeb..7406d88469 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -7,137 +7,40 @@ Erik Sandberg */ +#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); diff --git a/lily/time-signature-performer.cc b/lily/time-signature-performer.cc index cef302c49c..b6c6b8af11 100644 --- a/lily/time-signature-performer.cc +++ b/lily/time-signature-performer.cc @@ -64,6 +64,7 @@ Time_signature_performer::stop_translation_timestep () { if (audio_) { + play_element (audio_); audio_ = 0; } } diff --git a/lily/timing-translator.cc b/lily/timing-translator.cc index d792918171..a5cf4adb3f 100644 --- a/lily/timing-translator.cc +++ b/lily/timing-translator.cc @@ -40,7 +40,6 @@ Timing_translator::initialize () { 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))); @@ -103,8 +102,10 @@ Timing_translator::start_translation_timestep () 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); @@ -113,12 +114,10 @@ Timing_translator::start_translation_timestep () 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 ()); } @@ -133,14 +132,4 @@ ADD_TRANSLATOR (Timing_translator, "@code{Staff}. " "\n\nThis engraver adds the alias @code{Timing} to its containing context.", - "", "", - - "internalBarNumber " - "currentBarNumber " - "measureLength " - "measurePosition ", - - "internalBarNumber " - "currentBarNumber " - "measurePosition " - ); + "", "", "", ""); diff --git a/lily/translator-group.cc b/lily/translator-group.cc index da3fda5ed5..e2541996ef 100644 --- a/lily/translator-group.cc +++ b/lily/translator-group.cc @@ -12,12 +12,10 @@ #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" @@ -45,33 +43,9 @@ void 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 @@ -79,115 +53,78 @@ Translator_group::finalize () { } -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 (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 (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 (g)) - g->simple_trans_list_ = filter_performers (trans_list); - else if (dynamic_cast (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 @@ -247,9 +184,11 @@ recurse_over_translators (Context *c, Translator_method ptr, Translator_group_me 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 @@ -326,6 +265,6 @@ Translator_group::mark_smob (SCM smob) 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_; } diff --git a/lily/translator.cc b/lily/translator.cc index d90c8be045..391af52b4b 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -8,12 +8,10 @@ #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" @@ -52,6 +50,12 @@ Translator::Translator (Translator const &src) must_be_last_ = src.must_be_last_; } +bool +Translator::try_music (Music *) +{ + return false; +} + Moment Translator::now_mom () const { @@ -70,12 +74,6 @@ Translator::get_daddy_translator () 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 { @@ -88,9 +86,12 @@ Translator::stop_translation_timestep () } /* - 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 () @@ -107,96 +108,6 @@ Translator::finalize () { } -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 */ @@ -214,7 +125,7 @@ Translator::get_global_context () const return daddy_context_->get_global_context (); } -Context * +Score_context * Translator::get_score_context () const { return daddy_context_->get_score_context (); @@ -258,9 +169,6 @@ add_acknowledger (Engraver_void_function_engraver_grob_info ptr, 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); } @@ -276,48 +184,6 @@ generic_get_acknowledger (SCM sym, vector const *ack_ar 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", "", diff --git a/lily/trill-spanner-engraver.cc b/lily/trill-spanner-engraver.cc index 8770ab9cef..4806758b00 100644 --- a/lily/trill-spanner-engraver.cc +++ b/lily/trill-spanner-engraver.cc @@ -18,7 +18,6 @@ #include "international.hh" #include "note-column.hh" #include "side-position-interface.hh" -#include "stream-event.hh" #include "translator.icc" @@ -29,15 +28,15 @@ public: 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 event_drul_; + Music *current_event_; + Drul_array event_drul_; void typeset_all (); }; @@ -50,12 +49,17 @@ Trill_spanner_engraver::Trill_spanner_engraver () 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 @@ -135,14 +139,15 @@ Trill_spanner_engraver::finalize () 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 */ "", diff --git a/lily/tuplet-bracket.cc b/lily/tuplet-bracket.cc index 68852c8353..4ca5032829 100644 --- a/lily/tuplet-bracket.cc +++ b/lily/tuplet-bracket.cc @@ -70,17 +70,12 @@ flatten_number_pair_property (Grob *me, = 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 const &cols, - bool *equally_long) +Tuplet_bracket::parallel_beam (Grob *me_grob, vector const &cols, bool *equally_long) { Spanner *me = dynamic_cast (me_grob); @@ -114,8 +109,7 @@ Tuplet_bracket::parallel_beam (Grob *me_grob, vector const &cols, } *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]; } @@ -663,29 +657,20 @@ Tuplet_bracket::calc_positions (SCM smob) 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 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; } diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index 7ac0e53322..92b062f116 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -6,31 +6,22 @@ (c) 1998--2006 Han-Wen Nienhuys */ +#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; } @@ -46,30 +37,32 @@ protected: vector stopped_tuplets_; vector 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 @@ -77,14 +70,12 @@ Tuplet_engraver::process_music () { 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); @@ -109,18 +100,13 @@ Tuplet_engraver::process_music () /* 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 ()); @@ -130,6 +116,13 @@ Tuplet_engraver::process_music () 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); + } } } @@ -155,11 +148,13 @@ void 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 () @@ -169,11 +164,7 @@ 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 */ ""); diff --git a/lily/tuplet-number.cc b/lily/tuplet-number.cc index a68b99b0a5..97c49129b3 100644 --- a/lily/tuplet-number.cc +++ b/lily/tuplet-number.cc @@ -43,9 +43,8 @@ Tuplet_number::print (SCM smob) 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); @@ -57,7 +56,7 @@ Tuplet_number::print (SCM smob) stc->translate ((points[RIGHT] + points[LEFT]) / 2); - return stc_scm; + return stc->smobbed_copy (); } diff --git a/lily/tweak-engraver.cc b/lily/tweak-engraver.cc index 5fcf3981e4..9843dce725 100644 --- a/lily/tweak-engraver.cc +++ b/lily/tweak-engraver.cc @@ -9,8 +9,8 @@ #include "engraver.hh" +#include "music.hh" #include "grob.hh" -#include "stream-event.hh" #include "translator.icc" class Tweak_engraver : public Engraver @@ -28,19 +28,19 @@ Tweak_engraver::Tweak_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 */ "", diff --git a/lily/vaticana-ligature-engraver.cc b/lily/vaticana-ligature-engraver.cc index f84ecaa6b2..22c42c1cd2 100644 --- a/lily/vaticana-ligature-engraver.cc +++ b/lily/vaticana-ligature-engraver.cc @@ -15,7 +15,6 @@ #include "paper-column.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" -#include "stream-event.hh" #include "vaticana-ligature.hh" #include "warn.hh" @@ -46,24 +45,8 @@ protected: virtual Spanner *create_ligature_spanner (); virtual void transform_heads (Spanner *ligature, vector 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 = @@ -222,13 +205,13 @@ Vaticana_ligature_engraver::align_heads (vector primitives, 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; } @@ -385,13 +368,13 @@ Vaticana_ligature_engraver::transform_heads (Spanner *ligature, Item *primitive = dynamic_cast (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; } diff --git a/lily/vaticana-ligature.cc b/lily/vaticana-ligature.cc index 6c0beaf387..85e88b51ed 100644 --- a/lily/vaticana-ligature.cc +++ b/lily/vaticana-ligature.cc @@ -210,7 +210,7 @@ vaticana_brew_primitive (Grob *me) 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); @@ -303,6 +303,6 @@ ADD_INTERFACE (Vaticana_ligature, "vaticana-ligature-interface", "add-cauda " "add-stem " "add-join " - "delta-position " + "delta-pitch " "x-offset " ); diff --git a/lily/vertical-align-engraver.cc b/lily/vertical-align-engraver.cc index 9523d3c6a8..8b8d04ea0c 100644 --- a/lily/vertical-align-engraver.cc +++ b/lily/vertical-align-engraver.cc @@ -41,7 +41,7 @@ ADD_TRANSLATOR (Vertical_align_engraver, "them vertically.", /* create */ "VerticalAlignment", /* accept */ "", - /* read */ "alignAboveContext alignBelowContext", + /* read */ "", /* write */ ""); Vertical_align_engraver::Vertical_align_engraver () diff --git a/lily/volta-engraver.cc b/lily/volta-engraver.cc index 9439d6f6d7..fefc68e7f3 100644 --- a/lily/volta-engraver.cc +++ b/lily/volta-engraver.cc @@ -30,7 +30,6 @@ public: TRANSLATOR_DECLARATIONS (Volta_engraver); protected: - DECLARE_END_ACKNOWLEDGER (staff_symbol); DECLARE_ACKNOWLEDGER (staff_symbol); DECLARE_ACKNOWLEDGER (note_column); DECLARE_ACKNOWLEDGER (bar_line); @@ -190,13 +189,6 @@ Volta_engraver::acknowledge_bar_line (Grob_info i) 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) { @@ -210,7 +202,6 @@ Volta_engraver::acknowledge_staff_symbol (Grob_info i) staff_ = i.grob ()->self_scm (); } - void Volta_engraver::finalize () { @@ -253,7 +244,6 @@ Volta_engraver::stop_translation_timestep () 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, diff --git a/lily/volta-repeat-iterator.cc b/lily/volta-repeat-iterator.cc index 1828dfdbca..31f6295410 100644 --- a/lily/volta-repeat-iterator.cc +++ b/lily/volta-repeat-iterator.cc @@ -69,7 +69,7 @@ Volta_repeat_iterator::add_repeat_command (SCM what) && 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); } } diff --git a/ly/GNUmakefile b/ly/GNUmakefile index fd82839f73..ba9200edec 100644 --- a/ly/GNUmakefile +++ b/ly/GNUmakefile @@ -1,6 +1,6 @@ depth = .. -INI_FILES = $(LY_FILES) +INI_FILES = $(FLY_FILES) $(SLY_FILES) $(LY_FILES) EXTRA_DIST_FILES = $(SCM_FILES) INSTALLATION_DIR=$(local_lilypond_datadir)/ly/ diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index d62be48370..5a322c2af7 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -46,7 +46,6 @@ pageTurn = #(make-event-chord (list (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))) @@ -72,9 +71,8 @@ escapedSmallerSymbol = #(make-span-event 'CrescendoEvent 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) @@ -109,8 +107,7 @@ partCombineListener = \layout { \context { \Score skipTypesetting = ##t - ignoreBarChecks = ##t - \alias "Timing" + ignoreBarChecks = ##t } } diff --git a/ly/english.ly b/ly/english.ly index 5277d125f5..67820fffb5 100644 --- a/ly/english.ly +++ b/ly/english.ly @@ -1,15 +1,6 @@ %{ 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 = #`( @@ -50,79 +41,46 @@ 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)) ) diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index 2959ce7187..654f5dd8df 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -46,14 +46,13 @@ 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" @@ -94,7 +93,7 @@ \consists "System_start_delimiter_engraver" systemStartDelimiter = #'SystemStartBracket vocalName = #'() - shortVocalName = #'() + vocNam = #'() \accepts "Staff" \accepts "DrumStaff" @@ -149,7 +148,6 @@ contained staves are not connected vertically." \consists "Time_signature_engraver" \consists "Instrument_name_engraver" \consists "Axis_group_engraver" - \consists "Ledger_line_engraver" \accepts "Voice" \accepts "CueVoice" @@ -192,7 +190,6 @@ contained staves are not connected vertically." \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 @@ -203,19 +200,16 @@ contained staves are not connected vertically." \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" @@ -226,7 +220,7 @@ contained staves are not connected vertically." \consists "Tie_engraver" \consists "Tuplet_engraver" \consists "Grace_engraver" - \consists "Instrument_switch_engraver" + \consists "Skip_event_swallow_translator" } @@ -281,7 +275,6 @@ contained staves are not connected vertically." systemStartDelimiter = #'SystemStartBrace \accepts "Staff" - \accepts "FiguredBass" } \context{ @@ -299,8 +292,8 @@ contained staves are not connected vertically." \consists "Vertical_align_engraver" \consists "Instrument_name_engraver" - instrumentName = #'() - shortInstrumentName = #'() + instrument = #'() + instr = #'() } \context { @@ -352,7 +345,7 @@ staffs, with a bracket in front and spanning bar lines. " \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" @@ -464,7 +457,6 @@ AncientRemoveEmptyStaffContext = \context { \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" @@ -531,6 +523,7 @@ AncientRemoveEmptyStaffContext = \context { harmonicAccidentals = ##t fingeringOrientations = #'(up down) stringNumberOrientations = #'(up down) + tupletNumberFormatFunction = #denominator-tuplet-formatter markFormatter = #format-mark-letters rehearsalMark = #1 subdivideBeams = ##f @@ -655,6 +648,7 @@ AncientRemoveEmptyStaffContext = \context { \alias "Staff" \name "TabStaff" \denies "Voice" + \remove "Staff_symbol_engraver" \consists "Tab_staff_symbol_engraver" \description "Context for generating tablature. [DOCME]" diff --git a/ly/gregorian-init.ly b/ly/gregorian-init.ly index 2247081083..23495a0e64 100644 --- a/ly/gregorian-init.ly +++ b/ly/gregorian-init.ly @@ -1,62 +1,11 @@ -%{ - 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 @@ -86,7 +35,7 @@ cavum = \once \override NoteHead #'cavum = ##t % -% Declare divisiones shortcuts. +% declare divisiones shortcuts % virgula = { \once \override BreathingSign #'text = #(make-musicglyph-markup "scripts.rcomma") @@ -142,8 +91,14 @@ finalis = { \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") @@ -151,16 +106,10 @@ semicirculus = #(make-articulation "semicirculus") 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) @@ -210,15 +159,6 @@ ligature = #(define-music-function % '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 @@ -277,12 +217,9 @@ ligature = #(define-music-function } % -% 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 { @@ -306,7 +243,3 @@ neumeDemoLayout = \layout { \override Stem #'transparent = ##t } } - -%%% Local Variables: -%%% coding: utf-8 -%%% End: diff --git a/ly/init.ly b/ly/init.ly index 1a9ec369cb..71633013a6 100644 --- a/ly/init.ly +++ b/ly/init.ly @@ -16,7 +16,7 @@ #(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 @@ -30,7 +30,7 @@ (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)) diff --git a/ly/lilypond-book-preamble.ly b/ly/lilypond-book-preamble.ly deleted file mode 100644 index 75bce0045d..0000000000 --- a/ly/lilypond-book-preamble.ly +++ /dev/null @@ -1,13 +0,0 @@ - -\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) diff --git a/ly/midi-init.ly b/ly/midi-init.ly index f4e50d89ec..a2a65b51cd 100644 --- a/ly/midi-init.ly +++ b/ly/midi-init.ly @@ -1,5 +1,6 @@ \version "2.7.39" \midi { + \tempo 4=60 \include "performer-init.ly" } diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index b910223f68..b2780027c7 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -1,93 +1,72 @@ % -*-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?) @@ -99,184 +78,40 @@ applyContext = '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) @@ -298,15 +133,38 @@ or @code{\"GrobName\"}" (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 = @@ -318,24 +176,68 @@ 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) @@ -362,16 +264,81 @@ pitchedTrill = (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?) @@ -442,7 +409,7 @@ Example: 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)) @@ -463,152 +430,60 @@ Example: -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 - -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)) diff --git a/ly/paper-defaults.ly b/ly/paper-defaults.ly index 44ec0b961e..41c846feab 100644 --- a/ly/paper-defaults.ly +++ b/ly/paper-defaults.ly @@ -1,5 +1,5 @@ \version "2.7.39" -#(use-modules (scm layout-page-layout)) + \paper { %%%% WARNING @@ -76,12 +76,6 @@ %% ragged-last-bottom= ##t - %% - %% settings for the page breaker - %% - blank-last-page-force = 0 - blank-page-force = 10 - #(define font-defaults '((font-encoding . fetaMusic))) @@ -96,18 +90,7 @@ (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 ) diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 726ffaa661..d22c422775 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -7,11 +7,12 @@ \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 @@ -38,6 +39,7 @@ \consists "Note_performer" \consists "Beam_performer" \consists "Slur_performer" + \consists "Melisma_translator" } \context { @@ -46,12 +48,6 @@ \alias Voice } -\context { - \Voice - \name VaticanaVoice - \alias Voice -} - \context { \Voice \remove "Note_performer" @@ -99,26 +95,13 @@ \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 @@ -132,14 +115,10 @@ \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 @@ -154,6 +133,8 @@ \consists "Staff_performer" % Performer_group ? \consists "Lyric_performer" \name Lyrics + \consists "Time_signature_performer" + \consists "Tempo_performer" } \context{ @@ -186,13 +167,6 @@ \name StaffGroup \accepts Staff \accepts DrumStaff - \accepts TabStaff - \accepts RhythmicStaff - \accepts GrandStaff - \accepts PianoStaff - \accepts Lyrics - \accepts ChordNames - \accepts FiguredBass \defaultchild Staff } diff --git a/ly/spanners-init.ly b/ly/spanners-init.ly index 43d0ef0cb6..d2493903c9 100644 --- a/ly/spanners-init.ly +++ b/ly/spanners-init.ly @@ -91,5 +91,3 @@ sostenutoUp = #(make-span-event 'SostenutoEvent STOP) %crescpoco = \set crescendoText = "cresc. poco a poco" %decresc = \set crescendoText = "decr." %dim = \set crescendoText = "dim." - -newSpacingSection = #(make-event-chord (list (make-music 'SpacingSectionEvent))) diff --git a/ly/titling-init.ly b/ly/titling-init.ly index b5f5797c4e..26bca808c8 100644 --- a/ly/titling-init.ly +++ b/ly/titling-init.ly @@ -100,7 +100,7 @@ scoreTitleMarkup = \markup { \column { #(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)) diff --git a/make/lilypond-vars.make b/make/lilypond-vars.make index 3c55dbeedc..1dd53512b8 100644 --- a/make/lilypond-vars.make +++ b/make/lilypond-vars.make @@ -1,10 +1,11 @@ ## ## 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 @@ -22,11 +23,9 @@ the-script-dir=$(wildcard $(script-dir)) 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 diff --git a/make/ly-rules.make b/make/ly-rules.make index e7dbb42719..b3c4f4108c 100644 --- a/make/ly-rules.make +++ b/make/ly-rules.make @@ -1,19 +1,19 @@ -.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 $< diff --git a/make/ly-vars.make b/make/ly-vars.make index d355969130..802c89b4ce 100644 --- a/make/ly-vars.make +++ b/make/ly-vars.make @@ -5,7 +5,7 @@ # 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) diff --git a/make/mutopia-rules.make b/make/mutopia-rules.make index 4d0ae69548..e5d647d626 100644 --- a/make/mutopia-rules.make +++ b/make/mutopia-rules.make @@ -1,7 +1,12 @@ -$(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 $< $@ @@ -10,6 +15,10 @@ $(outdir)/%.ly: %.abc # 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 $< $@ + + diff --git a/make/mutopia-vars.make b/make/mutopia-vars.make index 1e09d8dcec..22c63ba39a 100644 --- a/make/mutopia-vars.make +++ b/make/mutopia-vars.make @@ -10,7 +10,7 @@ M4_FILES = $(call src-wildcard,*.m4) 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))) diff --git a/mf/SConscript b/mf/SConscript index 323a1bbdac..0bfbe5d5fd 100644 --- a/mf/SConscript +++ b/mf/SConscript @@ -5,7 +5,7 @@ import re 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', @@ -16,14 +16,24 @@ feta_alphabet = base_glob ('feta-alphabet[0-9][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) @@ -40,30 +50,21 @@ env.Append (BUILDERS = {'OTF_TABLE': otf_table}) 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') @@ -79,33 +80,73 @@ env.Command ('aybabtu.otf-gtable', 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 > $TARGET', + 'echo "Aybabtu-Regular Aybabtu-Regular > $TARGET', + 'echo "PFAAybabtu-Regular PFAAybabtu-Regular > $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') diff --git a/mf/feta-bolletjes.mf b/mf/feta-bolletjes.mf index 48eb3649c3..c09c3d2df9 100644 --- a/mf/feta-bolletjes.mf +++ b/mf/feta-bolletjes.mf @@ -1010,7 +1010,7 @@ def draw_re_head (expr width_factor, dir) = 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; @@ -1094,7 +1094,7 @@ def draw_mi_head (expr width_factor) = 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; @@ -1169,7 +1169,7 @@ fet_endchar; 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; @@ -1260,7 +1260,7 @@ fet_endchar; 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; @@ -1319,7 +1319,7 @@ fet_endchar; 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; diff --git a/po/de.po b/po/de.po index 3b67f19be4..4ab5640b56 100644 --- a/po/de.po +++ b/po/de.po @@ -1789,7 +1789,7 @@ msgstr "Bezeichner sollte nur aus alphabetischen Zeichen bestehen" #: 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 diff --git a/po/fi.po b/po/fi.po index dcb040cefa..751b57857b 100644 --- a/po/fi.po +++ b/po/fi.po @@ -1,105 +1,106 @@ +# 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 , 2003-2006. +# First translator: Heikki Junes , 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: \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" @@ -117,76 +118,76 @@ msgstr "" " 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" @@ -196,27 +197,27 @@ msgstr "" "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" @@ -224,47 +225,48 @@ msgstr "" "\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" @@ -272,202 +274,198 @@ msgstr "" "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ä." @@ -491,12 +489,12 @@ msgstr "tunnistamaton optio: `%s'" 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" @@ -515,47 +513,43 @@ msgstr "sivutetaan tuntematan etumerkki: %s" 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" @@ -576,32 +570,28 @@ msgstr "onko käytössä kaksi Axis_group_engraver:ia?" 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ä" @@ -609,15 +599,15 @@ 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'" @@ -647,18 +637,18 @@ msgstr "ei vaihdettu samaan konteksti tyyppiin: %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 @@ -674,42 +664,61 @@ msgstr "tuntematon klusterityyli: `%s'" 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'" @@ -718,58 +727,50 @@ 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" @@ -786,36 +787,54 @@ msgstr "asetetaan nollaksi" 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ä" @@ -829,19 +848,15 @@ msgstr "Tuntematon rajapinta `%s'" 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" @@ -865,40 +880,40 @@ msgstr "päättämätön tavuviiva" 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ä" @@ -907,53 +922,53 @@ 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..." @@ -963,12 +978,12 @@ msgstr "Jäsennetään..." 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" @@ -980,7 +995,7 @@ msgstr "" "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" @@ -1010,11 +1025,11 @@ msgstr "" "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" @@ -1024,11 +1039,11 @@ msgstr "" "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." @@ -1036,77 +1051,77 @@ msgstr "" "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" @@ -1114,27 +1129,27 @@ msgstr "" "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" @@ -1144,125 +1159,125 @@ msgstr "" "%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" @@ -1270,7 +1285,7 @@ msgstr "" "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" @@ -1282,7 +1297,7 @@ msgstr "" "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" @@ -1299,11 +1314,11 @@ msgstr "Mensural_ligature: (join_right == 0)" 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." @@ -1318,33 +1333,36 @@ msgstr "tiedostoa ei voitu avata kirjoitettavaksi: %s: `%s'" 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" @@ -1352,12 +1370,12 @@ 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" @@ -1371,44 +1389,27 @@ msgstr "ei voitu varata %lu bittiä" 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ä" @@ -1417,16 +1418,12 @@ 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..." @@ -1434,43 +1431,55 @@ 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'" @@ -1480,56 +1489,56 @@ 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" @@ -1538,26 +1547,11 @@ msgstr "" "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" @@ -1566,55 +1560,51 @@ 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" @@ -1623,64 +1613,91 @@ 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? #. @@ -1703,34 +1720,19 @@ msgstr "aikamerkintäsymbolia `%s' ei löytynyt; vaihdetaan numeroituun tyyliin" 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 " @@ -1739,10 +1741,11 @@ msgstr "" "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" @@ -1757,131 +1760,145 @@ msgid "Vaticana_ligature: zero join (delta_pitch == 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'..." @@ -1891,63 +1908,53 @@ 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" @@ -1981,42 +1988,42 @@ msgstr "Kirjoitetaan ~S..." 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 to ~S" msgstr "ei voida konvertoida ~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" @@ -2031,7 +2038,7 @@ msgstr "" "\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'" @@ -2046,55 +2053,39 @@ msgstr "Virhe palkin laskennassa. Odotettiin (~S,~S), löytyi ~S." 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" @@ -2105,46 +2096,37 @@ msgstr "Väärä argumenttin määrä. Odotettiin: ~A, löytyi ~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" @@ -2163,23 +2145,18 @@ msgstr "Ei huipputason piirissä" 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" @@ -2192,3 +2169,126 @@ msgstr "~a komento lopetettiin tilassa: ~S" 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'" diff --git a/po/fr.po b/po/fr.po index 7c9cb1e780..3c009fcff9 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,32 +1,34 @@ # translation of fr.po to -# Messages français pour LilyPond. +# Messages français pour lilypond. # Copyright © 2004 Free Software Foundation, Inc. # Michel Robitaille , traducteur depuis/since 1996. # revisité par Jean-Charles Malahieude , -# et par John Mandereau , 2006. +# et par John Mandereau +# John Mandereau , 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 \n" +"PO-Revision-Date: 2005-09-01 15:35+0200\n" +"Last-Translator: John Mandereau \n" "Language-Team: \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 @@ -39,7 +41,7 @@ msgstr "Le fichier source LilyPond doit être encodé en UTF-8" #: 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 @@ -78,29 +80,29 @@ msgstr "Exécution de %s..." #: 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" @@ -110,14 +112,10 @@ msgid "" " 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 @@ -139,35 +137,36 @@ msgstr "Le logiciel est distribué SANS GARANTIE." #: 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" @@ -184,9 +183,9 @@ msgid "can't open file: `%s'" 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 "" @@ -194,8 +193,6 @@ 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" @@ -206,10 +203,12 @@ msgid "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" @@ -219,7 +218,8 @@ msgid "" " 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" @@ -230,12 +230,12 @@ msgstr "" #: 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" @@ -246,12 +246,15 @@ msgid "pipe snippets through FILTER [convert-ly -n -]" 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" @@ -266,20 +269,21 @@ msgid "process ly_files using COMMAND FILE..." 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 @@ -354,12 +358,12 @@ msgstr "Écriture de « %s »..." #: 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..." @@ -368,7 +372,7 @@ msgstr "Dissection en cours..." #: 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 @@ -386,8 +390,9 @@ msgid "Writing fonts to %s..." 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" @@ -412,11 +417,11 @@ msgstr "Fin d'exécution... " #: 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" @@ -432,7 +437,7 @@ msgstr "quantifier les durées de note d'après DUR" #: 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" @@ -452,19 +457,20 @@ msgstr "DUR*NUM/DEN" #: 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 @@ -493,39 +499,37 @@ msgstr "erreur de programmation : %s" #: 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 @@ -539,7 +543,7 @@ msgstr "chargement de la police par défaut" #: 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 @@ -557,7 +561,7 @@ msgstr "l'argument de \\applycontext n'est pas une procédure" #: 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" @@ -597,8 +601,9 @@ msgid "beam was started here" 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" @@ -606,13 +611,14 @@ msgstr "retrait du lien ayant moins de deux hampes" #: 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 @@ -632,7 +638,7 @@ msgstr "impossible de repérer le contexte vers lequel commuter" #: 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 @@ -650,7 +656,7 @@ msgstr "accord de trémolo non terminé" #: 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 @@ -664,7 +670,7 @@ msgstr "style de cluster inconnu : « %s »" #: 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 @@ -683,16 +689,18 @@ msgstr "distance=%f" #: 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 @@ -726,11 +734,11 @@ msgstr "impossible de trouver ou créer : « %s »" #: 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" @@ -759,7 +767,7 @@ msgstr "prolongation non terminée" #: 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..." @@ -768,7 +776,7 @@ msgstr "Initialisation de 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 @@ -777,7 +785,7 @@ msgstr "ajout d'un répertoire de polices : « %s »" #: 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" @@ -812,11 +820,11 @@ msgstr "Démérites optimaux : %f" #: 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 @@ -830,13 +838,18 @@ msgstr "\\%s implicite ajouté" #. 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 @@ -850,8 +863,9 @@ msgstr "" "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" @@ -871,11 +885,11 @@ msgstr "événements de groupe de notes conflictuels" #: 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" @@ -912,7 +926,7 @@ msgstr "ligature non terminée" #: 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" @@ -930,7 +944,7 @@ msgstr "Vérification de type de propriété pour « %s » (%s) non trouvée." #: 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" @@ -939,8 +953,9 @@ msgstr "affectation faite malgré tout" #: 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 @@ -958,9 +973,9 @@ msgid "deprecated function called: %s" 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 @@ -983,7 +998,7 @@ msgstr "accolades non pairées" #: 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 @@ -993,9 +1008,11 @@ msgid "" "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 "" @@ -1034,26 +1051,24 @@ msgid "BACK" 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" @@ -1061,7 +1076,7 @@ msgstr "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. @@ -1079,7 +1094,7 @@ msgstr "générer le DVI (uniquement pour tex)" #: 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)" @@ -1106,8 +1121,9 @@ msgid "FIELD" 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" @@ -1126,12 +1142,13 @@ msgid "USER,GROUP,JAIL,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" @@ -1147,11 +1164,11 @@ msgstr "produire une image du premier système" #: 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 @@ -1181,7 +1198,7 @@ msgstr "LilyPond produit une jolie notation musicale." #: 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 @@ -1189,14 +1206,14 @@ msgid "Options:" 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 @@ -1206,7 +1223,8 @@ msgstr "utilisateur inconnu : « %s »" #: 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 @@ -1217,37 +1235,38 @@ msgstr "groupe inconnu : %s" #: 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 @@ -1256,31 +1275,33 @@ msgstr "rehearsalMark doit être un entier" #: 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 "" @@ -1341,7 +1362,7 @@ msgstr "impossible d'écrire dans le fichier : « %s »" #: 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 @@ -1350,7 +1371,8 @@ msgstr "La transposition de %s crée des altérations supérieures aux doubles" #: 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? @@ -1361,7 +1383,7 @@ msgstr "musique pour les martiens." #: 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" @@ -1373,7 +1395,7 @@ msgstr "trop de notes se chevauchent. On les ignore." #: 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 @@ -1382,12 +1404,12 @@ msgstr "tête de note « %s » non repérée" #: 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 @@ -1412,7 +1434,7 @@ msgstr "FT_Get_Glyph_Name() a renvoyé l'erreur : %d" #: 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" @@ -1426,7 +1448,7 @@ msgstr "Sortie mise en page vers « %s »..." #: 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..." @@ -1442,7 +1464,7 @@ msgstr "répétition en pourcent non terminée" #: 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..." @@ -1474,9 +1496,10 @@ msgid "unterminated phrasing slur" 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 @@ -1487,7 +1510,8 @@ msgstr "impossible de repérer le début de la pédale de piano : « %s »" #: 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 @@ -1509,14 +1533,14 @@ msgid "Failed octave check, got: " 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 @@ -1526,22 +1550,22 @@ msgstr "" #: 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 @@ -1549,12 +1573,10 @@ msgid "" "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" @@ -1639,7 +1661,7 @@ msgstr "la source devrait peut-être spécifier des voix polyphoniques" #: 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 @@ -1649,7 +1671,7 @@ msgstr "crochet `%s' non repéré" #: 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 @@ -1687,7 +1709,8 @@ msgstr "L'en-tête TFM de « %s » a seulement %u mot(s)" #: 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 @@ -1711,14 +1734,16 @@ msgstr "début de l'accolade de n-olet indéterminé" #: 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 @@ -1779,7 +1804,7 @@ msgstr "a déjà une extension terminée" #. 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" @@ -1787,7 +1812,7 @@ msgstr "dans la section \\score, utiliser \\layout au lieu de \\paper" #: 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" @@ -1812,7 +1837,7 @@ msgstr "doit être en mode Lyric pour des paroles" #: 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 @@ -1833,11 +1858,11 @@ msgstr "une fonction musicale primitive devrait renvoyer un objet Music" #: 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 @@ -1854,7 +1879,7 @@ msgstr "\\sourcefilename doit être suivi d'une chaîne entre guillemets" #: 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" @@ -1872,11 +1897,12 @@ msgstr "absence de guillemet fermant" #: 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 @@ -1895,7 +1921,7 @@ msgstr "Version de LilyPond incorrecte : %s (%s, %s)" #: 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 @@ -1935,7 +1961,8 @@ msgstr "symbole ~S redéfini" #: 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 @@ -1959,7 +1986,7 @@ msgstr "type de répétition inconnu : « ~S »" #: 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 @@ -1972,9 +1999,9 @@ msgid "can't find interface for property: ~S" 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 @@ -1984,37 +2011,37 @@ msgstr "Traitement de ~S..." #: 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 @@ -2035,17 +2062,11 @@ msgid "" "\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 \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 @@ -2069,7 +2090,8 @@ msgstr "unité inconnue : « ~S »" #: 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 @@ -2087,9 +2109,9 @@ msgid "failed files: ~S" 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 @@ -2110,13 +2132,13 @@ msgstr "attendait une expression musicale : ~S" #: 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 @@ -2124,6 +2146,7 @@ msgid "unknown accidental style: ~S" 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" @@ -2160,18 +2183,294 @@ msgstr "#(set-paper-size ..) doit être dans la section \\paper { ... }" #: 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'" diff --git a/ps/lilyponddefs.ps b/ps/lilyponddefs.ps index ad0d89a61b..442ae20046 100644 --- a/ps/lilyponddefs.ps +++ b/ps/lilyponddefs.ps @@ -6,6 +6,10 @@ % /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 diff --git a/ps/music-drawing-routines.ps b/ps/music-drawing-routines.ps index 8864569af1..e0f28e82a6 100644 --- a/ps/music-drawing-routines.ps +++ b/ps/music-drawing-routines.ps @@ -7,6 +7,29 @@ % 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 diff --git a/python/convertrules.py b/python/convertrules.py index 40a8300e73..d535ae8ce9 100644 --- a/python/convertrules.py +++ b/python/convertrules.py @@ -623,13 +623,13 @@ def conv (str): 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')) @@ -2680,7 +2680,6 @@ conversions.append (((2, 7, 28), conv, 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, @@ -2691,7 +2690,7 @@ conversions.append (((2, 7, 29), conv, """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, @@ -2795,77 +2794,4 @@ def conv (str): 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[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#denominator-tuplet-formatter""", - r"""\\override \gTupletNumber #'text = #tuplet-number::calc-denominator-text""", str) - - str = re.sub (r"""(\\set\s+)?(?P[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#fraction-tuplet-formatter""", - r"""\\override \gTupletNumber #'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 """)) diff --git a/python/lilylib.py b/python/lilylib.py index 877b98e360..7b43bcb241 100644 --- a/python/lilylib.py +++ b/python/lilylib.py @@ -52,16 +52,6 @@ except: 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, @@ -69,11 +59,12 @@ def command_name (cmd): 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 @@ -123,42 +114,6 @@ def subprocess_system (cmd, 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: diff --git a/python/midi.c b/python/midi.c index 8ccbaf9758..b5e2f5bf57 100644 --- a/python/midi.c +++ b/python/midi.c @@ -135,8 +135,7 @@ get_number (unsigned char ** str, unsigned char * end_str, int length) 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; @@ -205,8 +204,8 @@ read_string (unsigned char **track, unsigned char *end) } 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 * @@ -300,8 +299,7 @@ midi_parse_track (unsigned char **track, unsigned char *track_end) 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); @@ -359,6 +357,7 @@ midi_parse (unsigned char **midi,unsigned char *midi_end) /* Header */ header_len = get_number (midi, *midi + 4, 4); + if (header_len < 6) return midi_error (__FUNCTION__, ": header too short"); @@ -401,7 +400,7 @@ pymidi_parse (PyObject *self, PyObject *args) return 0; if (memcmp (midi, "MThd", 4)) - return midi_error (__FUNCTION__, ": MThd expected"); + return midi_error (__FUNCTION__, ": MThd expected"); midi += 4; diff --git a/python/musicxml.py b/python/musicxml.py index 3466473c43..519a0c3f6c 100644 --- a/python/musicxml.py +++ b/python/musicxml.py @@ -165,7 +165,7 @@ class Attributes (Measure_element): "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 () diff --git a/scm/autochange.scm b/scm/autochange.scm index e4a27d7063..b7169c8a99 100644 --- a/scm/autochange.scm +++ b/scm/autochange.scm @@ -11,10 +11,10 @@ (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))) @@ -30,16 +30,17 @@ (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)) diff --git a/scm/backend-library.scm b/scm/backend-library.scm index aa432017db..731dcf083e 100644 --- a/scm/backend-library.scm +++ b/scm/backend-library.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 2005--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; backend helpers. @@ -48,24 +48,15 @@ ;; 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 \ @@ -76,10 +67,10 @@ " (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, @@ -99,16 +90,17 @@ (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"))) @@ -120,10 +112,9 @@ (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) diff --git a/scm/c++.scm b/scm/c++.scm index adc21cea23..61fb34e782 100644 --- a/scm/c++.scm +++ b/scm/c++.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys ;;; Note: this file can't be used without LilyPond executable diff --git a/scm/chord-entry.scm b/scm/chord-entry.scm index cf8ea886f2..b703e5e630 100644 --- a/scm/chord-entry.scm +++ b/scm/chord-entry.scm @@ -4,13 +4,14 @@ ;;;; ;;;; (c) 2004--2006 Han-Wen Nienhuys -(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)) @@ -154,12 +155,12 @@ the bass specified. (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) @@ -180,7 +181,7 @@ DURATION, and INVERSION." (- (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. diff --git a/scm/chord-ignatzek-names.scm b/scm/chord-ignatzek-names.scm index b3cdb56946..2783f32a86 100644 --- a/scm/chord-ignatzek-names.scm +++ b/scm/chord-ignatzek-names.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys diff --git a/scm/chord-name.scm b/scm/chord-name.scm index fe4ba7ab12..bdef88a476 100644 --- a/scm/chord-name.scm +++ b/scm/chord-name.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 2000--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys (define (natural-chord-alteration p) "Return the natural alteration for step P." diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 85e4ece2ba..427c14c2bc 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -2,22 +2,15 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (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) @@ -39,6 +32,8 @@ "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 @@ -187,7 +182,9 @@ The layout style is a hash table, containing the drum-pitches (e.g. the 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. @@ -249,16 +246,15 @@ get accidentals.") 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? " @@ -268,8 +264,6 @@ Function taking a string (instrument name), and returning a (@var{min} . @var{ma 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 @@ -312,12 +306,8 @@ markup. Called with 2 arguments, event and context.") (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 @@ -350,8 +340,6 @@ whether they are processed in this context.") 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 @@ -423,7 +411,11 @@ number is specified.") (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 @@ -457,6 +449,7 @@ context names whose vertical axis groups should be taken into account for 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 @@ -480,10 +473,6 @@ Example: 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 diff --git a/scm/define-event-classes.scm b/scm/define-event-classes.scm index 808fcf716c..84d6ef57d4 100644 --- a/scm/define-event-classes.scm +++ b/scm/define-event-classes.scm @@ -7,42 +7,16 @@ (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 .. ) @@ -51,76 +25,14 @@ (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) (stringmake-music e))) ((ly:moment? e) @@ -159,5 +71,8 @@ (#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))) diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index 5876ae40e9..4234fd5e1e 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen @@ -20,11 +20,6 @@ "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 "" @@ -45,17 +40,17 @@ "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" @@ -123,22 +118,11 @@ 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." diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index 7f46e9890b..09d7187b5c 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (define-grob-property symbol type? description) @@ -141,7 +141,7 @@ dash-period. Should be between 0.0 (no line) and 1.0 (continuous 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}.") @@ -202,7 +202,6 @@ include @code{medium}, @code{bold}, @code{bold-narrow}, etc.") (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.") @@ -226,6 +225,9 @@ typeset. Valid choices depend on the function that is reading this 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?") @@ -240,9 +242,7 @@ of note-column for horizontal shifting. This is used by 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.") @@ -261,7 +261,8 @@ objects in higher layers.") 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 @@ -351,7 +352,8 @@ quicker the slur attains it @code{height-limit}.") (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 @@ -367,8 +369,7 @@ direction. Values in between may also be specified.") 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. @@ -384,7 +385,7 @@ note that starts here.") "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.") @@ -415,13 +416,10 @@ staff spaces, counted from the middle line.") 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.") @@ -486,9 +484,6 @@ sizes (like the dynamic @b{p} and @b{f}) on their baselines.") (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") @@ -503,7 +498,6 @@ set, which grob to get the direction from .") (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.") @@ -526,8 +520,6 @@ paper-columns or note-column objects.") 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.") @@ -563,7 +555,6 @@ columns. (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 @@ -590,11 +581,12 @@ debugging") ;;; 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}).") @@ -615,15 +607,9 @@ than a whole rest.") ;;;;;;; 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?") @@ -633,17 +619,20 @@ than a whole rest.") (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 ))) diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index a82741dc69..02bc9cc8ad 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen ;;;; distances are given in line-thickness (thicknesses) and @@ -67,7 +67,7 @@ . ( (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)) @@ -142,7 +142,6 @@ . ( (break-align-symbol . staff-bar) (glyph . "|") - (gap . 0.4) (layer . 0) (break-visibility . ,all-visible) (non-musical . #t) @@ -194,8 +193,6 @@ (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) @@ -317,14 +314,6 @@ (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) @@ -508,7 +497,7 @@ (Dots . ( (stencil . ,ly:dots::print) - (dot-count . ,dots::calc-dot-count) + (dot-count . 1) (meta . ((class . Item) (interfaces . (font-interface staff-symbol-referencer-interface @@ -609,12 +598,10 @@ (meta . ((class . Spanner) (interfaces . (font-interface text-interface - line-spanner-interface dynamic-interface dynamic-text-spanner-interface spanner-interface)))))) - (Fingering . ( @@ -630,7 +617,7 @@ (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) @@ -655,16 +642,6 @@ (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)) @@ -692,7 +669,6 @@ (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) @@ -734,20 +710,6 @@ 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) @@ -1039,7 +1001,6 @@ (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) @@ -1159,7 +1120,6 @@ (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) @@ -1278,7 +1238,6 @@ (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) @@ -1301,10 +1260,13 @@ . ( ;; 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) @@ -1352,7 +1314,7 @@ (meta . ((class . Spanner) (interfaces . (slur-interface)))))) - (SostenutoPedal + (SostenutoPedal . ( (stencil . ,ly:text-interface::print) (direction . ,RIGHT) @@ -1383,15 +1345,13 @@ (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 @@ -1457,7 +1417,6 @@ (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) @@ -1520,7 +1479,6 @@ (StringNumber . ( (stencil . ,print-circled-text-callback) - (text . ,string-number::calc-text) (padding . 0.5) (staff-padding . 0.5) (self-alignment-X . 0) @@ -1548,7 +1506,6 @@ (meta . ((class . Item) (interfaces . (piano-pedal-interface text-spanner-interface - line-spanner-interface text-interface self-alignment-interface font-interface)))))) @@ -1640,7 +1597,6 @@ . ( (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) @@ -1688,14 +1644,12 @@ (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) @@ -1718,7 +1672,6 @@ (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) @@ -1763,7 +1716,6 @@ (side-axis . ,Y) (meta . ((class . Spanner) (interfaces . (text-spanner-interface - line-spanner-interface side-position-interface font-interface)))))) @@ -1776,6 +1728,7 @@ (stencil . ,ly:accidental-interface::print) (meta . ((class . Item) (interfaces . (item-interface + accidental-interface side-position-interface font-interface)))))) @@ -1816,6 +1769,7 @@ (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) @@ -1829,7 +1783,6 @@ (TupletNumber . ( (stencil . ,ly:tuplet-number::print) - (text . ,tuplet-number::calc-denominator-text) (font-shape . italic) (font-size . -2) (avoid-slur . inside) @@ -1883,7 +1836,6 @@ (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)))))) @@ -1986,74 +1938,3 @@ (set! all-grob-descriptions (sort all-grob-descriptions alist +;;;; (c) 2000--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen @@ -126,7 +126,8 @@ circle of diameter 0 (ie sharp corners)." (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 @@ -330,10 +331,8 @@ gsave /ecrm10 findfont (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) @@ -466,9 +465,7 @@ determines the space between each markup in @var{args}." (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 @@ -1066,8 +1063,8 @@ See @usermanref{The Feta font} for a complete listing of the possible glyphs." (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)) diff --git a/scm/define-music-display-methods.scm b/scm/define-music-display-methods.scm index d884cc36c9..ad1dbf3de7 100644 --- a/scm/define-music-display-methods.scm +++ b/scm/define-music-display-methods.scm @@ -143,7 +143,7 @@ (define post-event? (make-music-type-predicate 'StringNumberEvent 'ArticulationEvent - 'FingeringEvent + 'FingerEvent 'TextScriptEvent 'MultiMeasureTextEvent 'HyphenEvent @@ -220,7 +220,7 @@ ((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 @@ -481,14 +481,11 @@ Otherwise, return #f." ;; 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))) @@ -550,7 +547,7 @@ Otherwise, return #f." (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) diff --git a/scm/define-music-properties.scm b/scm/define-music-properties.scm index 09f2a14b96..13a0da1f4e 100644 --- a/scm/define-music-properties.scm +++ b/scm/define-music-properties.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (music-property-description symbol type? description) @@ -16,8 +16,12 @@ (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? @@ -28,9 +32,6 @@ TODO: consider making type into symbol ") (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") @@ -39,48 +40,37 @@ here. TODO: use SpanEvents?") (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.") @@ -98,9 +88,6 @@ for the grob made of this event.") (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 @@ -124,5 +111,14 @@ translation property") (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.") ))) diff --git a/scm/define-music-types.scm b/scm/define-music-types.scm index fb0cc99d25..69c654b019 100644 --- a/scm/define-music-types.scm +++ b/scm/define-music-types.scm @@ -2,24 +2,11 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen ;; 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 @@ -49,7 +36,7 @@ arguments to func are 1. the grob, 2. the originating context, 3. context where FUNC is called. ") - (types . (general-music event apply-output-event)) + (types . (general-music event layout-instruction)) )) (ArpeggioEvent . ( @@ -103,11 +90,13 @@ Syntax for manual control: 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'. @@ -116,6 +105,12 @@ Syntax: (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. @@ -149,13 +144,13 @@ Syntax: @var{note}\\cr ... @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 @@ -165,12 +160,7 @@ Syntax: @var{note}\\cr (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.") @@ -180,8 +170,7 @@ Syntax: @var{note}\\cr (types . (general-music event-chord simultaneous-music)) )) - - (FingeringEvent + (FingerEvent . ( (description . "Specify what finger to use for this note.") (types . (general-music fingering-event event)) @@ -246,7 +235,7 @@ Syntax: @var{note}\\laissezVibrer.") (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 @@ -275,6 +264,11 @@ e.g. @code{\\mark \"A\"}.") (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. @@ -282,22 +276,26 @@ e.g. @code{\\mark \"A\"}.") 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 @@ -329,18 +327,18 @@ SYNTAX @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 . ( @@ -364,7 +362,7 @@ Syntax NOTE \\( and \\) NOTE") (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) )) @@ -372,7 +370,7 @@ Syntax: @code{\\property @var{context}.@var{prop} = @var{scheme-val}}.") . ( (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) )) @@ -416,6 +414,12 @@ goes down).") (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. @@ -430,7 +434,7 @@ Syntax @code{r4} for a quarter 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) )) @@ -442,8 +446,7 @@ Syntax \\sequential @{..@} or simply @{..@} .") (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)) )) @@ -451,18 +454,18 @@ Syntax \\sequential @{..@} or simply @{..@} .") . ( (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 . ( @@ -494,6 +497,13 @@ Syntax NOTE( and NOTE) ") (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.....|") @@ -529,10 +539,10 @@ Syntax @code{\\times @var{fraction} @var{music}}, e.g. (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 @@ -584,11 +594,6 @@ Syntax: @code{s}@var{duration}") (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.") @@ -599,19 +604,19 @@ Syntax: @code{s}@var{duration}") (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 @@ -623,6 +628,12 @@ Syntax: @code{\\@var{number}}.") (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 . "") diff --git a/scm/define-stencil-commands.scm b/scm/define-stencil-commands.scm index 9b0b9422d6..7a9740c76e 100644 --- a/scm/define-stencil-commands.scm +++ b/scm/define-stencil-commands.scm @@ -17,21 +17,20 @@ 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 diff --git a/scm/document-backend.scm b/scm/document-backend.scm index 6b22d7f300..f71689d3c0 100644 --- a/scm/document-backend.scm +++ b/scm/document-backend.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (interface-doc-string interface grob-description) diff --git a/scm/document-functions.scm b/scm/document-functions.scm index 5515b1312e..2c6bbfcd09 100644 --- a/scm/document-functions.scm +++ b/scm/document-functions.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (use-modules diff --git a/scm/document-markup.scm b/scm/document-markup.scm index c2257640a9..6837ba5c9d 100644 --- a/scm/document-markup.scm +++ b/scm/document-markup.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (doc-markup-function func) diff --git a/scm/document-music.scm b/scm/document-music.scm index d6bd4e1c59..6070cf7692 100644 --- a/scm/document-music.scm +++ b/scm/document-music.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (music-props-doc) diff --git a/scm/document-translation.scm b/scm/document-translation.scm index 4784872897..9b4d7a23f6 100644 --- a/scm/document-translation.scm +++ b/scm/document-translation.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (define (engraver-makes-grob? name-symbol grav) diff --git a/scm/documentation-generate.scm b/scm/documentation-generate.scm index 6143f60993..3e0d6e1be8 100644 --- a/scm/documentation-generate.scm +++ b/scm/documentation-generate.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen ;;; File entry point for generated documentation @@ -54,7 +54,7 @@ (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 diff --git a/scm/documentation-lib.scm b/scm/documentation-lib.scm index ce91651e77..5a62f9728c 100644 --- a/scm/documentation-lib.scm +++ b/scm/documentation-lib.scm @@ -3,7 +3,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (use-modules (oop goops) @@ -111,7 +111,7 @@ "\\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 "." diff --git a/scm/file-cache.scm b/scm/file-cache.scm index 332f9bab10..3868c40dd5 100644 --- a/scm/file-cache.scm +++ b/scm/file-cache.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2005--2006 Han-Wen Nienhuys +;;;; (c) 2005--2006 Han-Wen Nienhuys (define cache-hash-tab (make-hash-table 11)) diff --git a/scm/framework-eps.scm b/scm/framework-eps.scm index ad5125d3dd..930ac51bf1 100644 --- a/scm/framework-eps.scm +++ b/scm/framework-eps.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-module (scm framework-eps)) @@ -44,27 +44,21 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." )) 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))))) @@ -88,7 +82,7 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." \\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)) @@ -97,9 +91,9 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." (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))) @@ -107,7 +101,7 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." (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)) @@ -127,4 +121,3 @@ stencil, so LaTeX includegraphics doesn't fuck up the alignment." (define convert-to-tex convert-to-tex) (define convert-to-dvi convert-to-dvi) - diff --git a/scm/framework-gnome.scm b/scm/framework-gnome.scm index 9e8cf4510d..7243ccebbc 100644 --- a/scm/framework-gnome.scm +++ b/scm/framework-gnome.scm @@ -193,12 +193,12 @@ (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 # [and '()] + (music-origin (if (ly:music? cause) + (ly:music-property cause 'origin) + ;; How come # [and '()] ;; are #t? :-( #f))) (if (ly:input-location? music-origin) diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm index 10934b84e8..bf794c3a74 100644 --- a/scm/framework-ps.scm +++ b/scm/framework-ps.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-module (scm framework-ps)) @@ -115,8 +115,7 @@ "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")) @@ -409,7 +408,7 @@ (lambda (x y) (string 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)) @@ -616,13 +602,10 @@ (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) diff --git a/scm/framework-tex.scm b/scm/framework-tex.scm index 83c64820e5..27e7d66013 100644 --- a/scm/framework-tex.scm +++ b/scm/framework-tex.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-module (scm framework-tex) #:export (output-framework-tex @@ -290,27 +290,23 @@ (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) diff --git a/scm/framework-texstr.scm b/scm/framework-texstr.scm index 5078b35b9d..88bc25a228 100644 --- a/scm/framework-texstr.scm +++ b/scm/framework-texstr.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-module (scm framework-texstr) #:export (output-framework-tex diff --git a/scm/layout-page-dump.scm b/scm/layout-page-dump.scm deleted file mode 100644 index 50815ac2ef..0000000000 --- a/scm/layout-page-dump.scm +++ /dev/null @@ -1,148 +0,0 @@ -;;;; layout-page-tweaks.scm -- page breaking and page layout -;;;; -;;;; source file of the GNU LilyPond music typesetter -;;;; -;;;; (c) 2006 Han-Wen Nienhuys -;;;; 2006 Nicolas Sceaux - -(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))) diff --git a/scm/layout-page-layout.scm b/scm/layout-page-layout.scm index e370a17132..8a7628af85 100644 --- a/scm/layout-page-layout.scm +++ b/scm/layout-page-layout.scm @@ -1,219 +1,148 @@ -;;;; 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 -;;;; Han-Wen Nienhuys - -(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 + +(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. @@ -223,147 +152,309 @@ ;; - 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)) diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 492e38d5ec..d178c6926c 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -4,7 +4,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys (define-public X 0) @@ -383,43 +383,13 @@ found." (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." @@ -481,9 +451,6 @@ possibly turned off." 0 (if (< x 0) -1 1))) -(define-public (car< a b) (< (car a) (car b))) - - (define-public (symbolstring lst) (symbol->string r))) diff --git a/scm/lily.scm b/scm/lily.scm index 8385bbdd00..d3cc27af55 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -3,63 +3,45 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys (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") ))) @@ -238,13 +220,7 @@ The syntax is the same as `define*-public'." safe-objects)) ,safe-symbol))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; init pitch system - -(ly:set-default-scale (ly:make-scale #(0 2 4 5 7 9 11))) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; other files. @@ -287,6 +263,7 @@ The syntax is the same as `define*-public'." "define-grobs.scm" "define-grob-interfaces.scm" "define-stencil-commands.scm" + "layout-page-layout.scm" "titling.scm" "paper.scm" @@ -414,14 +391,6 @@ The syntax is the same as `define*-public'." (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 diff --git a/scm/ly-syntax-constructors.scm b/scm/ly-syntax-constructors.scm index 23befc939e..56322ff919 100644 --- a/scm/ly-syntax-constructors.scm +++ b/scm/ly-syntax-constructors.scm @@ -4,186 +4,22 @@ ;;;; ;;;; (c) 2006 Erik Sandberg -;; 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)))) diff --git a/scm/markup.scm b/scm/markup.scm index 268efaf879..a98ba122db 100644 --- a/scm/markup.scm +++ b/scm/markup.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2003--2006 Han-Wen Nienhuys +;;;; (c) 2003--2006 Han-Wen Nienhuys " Internally markup is stored as lists, whose head is a function. diff --git a/scm/music-functions.scm b/scm/music-functions.scm index 86d2f2e0dd..bc8dad2e44 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys ;; (use-modules (ice-9 optargs)) @@ -16,9 +16,6 @@ (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 @@ -199,6 +196,8 @@ Returns `obj'. (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)) @@ -387,19 +386,60 @@ i.e. this is not an override" ;; 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) @@ -433,23 +473,6 @@ OTTAVATION to `8va', or whatever appropriate." (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)) @@ -457,7 +480,7 @@ of beat groupings " (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))) @@ -811,6 +834,7 @@ if appropriate. (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) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index 93e61dd9d9..bf98dbab41 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -3,48 +3,14 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys +;;; 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 @@ -89,20 +55,59 @@ (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? @@ -154,9 +159,13 @@ centered, X==1 is at the right, X == -1 is at the left." '(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))) @@ -168,9 +177,7 @@ centered, X==1 is at the right, X == -1 is at the left." (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 @@ -199,7 +206,6 @@ centered, X==1 is at the right, X == -1 is at the left." (result (assoc glyph '((":|:" . (":|" . "|:")) ("||:" . ("||" . "|:")) - ("dashed" . ("dashed" . '())) ("|" . ("|" . ())) ("||:" . ("||" . "|:")) ("|s" . (() . "|")) @@ -237,20 +243,6 @@ centered, X==1 is at the right, X == -1 is at the left." (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 @@ -280,7 +272,8 @@ centered, X==1 is at the right, X == -1 is at the left." (define (parenthesize-elements grob . rest) (let* - ((refp (if (null? rest) + ( + (refp (if (null? rest) grob (car rest))) (elts (ly:grob-object grob 'elements)) @@ -290,7 +283,7 @@ centered, X==1 is at the right, X == -1 is at the left." (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)) @@ -330,97 +323,3 @@ centered, X==1 is at the right, X == -1 is at the left." 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 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 - )) diff --git a/scm/output-ps.scm b/scm/output-ps.scm index a50f82d639..2e8c78e2d5 100644 --- a/scm/output-ps.scm +++ b/scm/output-ps.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys ;;;; Note: currently misused as testbed for titles with markup, see ;;;; input/test/title-markup.ly @@ -33,10 +33,10 @@ polygon repeat-slash resetcolor - resetrotation + resetrotatino round-filled-box setcolor - setrotation + setrotation text zigzag-line)) @@ -112,16 +112,13 @@ "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) @@ -177,8 +174,8 @@ (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)) @@ -248,6 +245,15 @@ (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)) @@ -261,23 +267,16 @@ ;; 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)) @@ -323,32 +322,3 @@ (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) " "))) - diff --git a/scm/output-socket.scm b/scm/output-socket.scm index e992e7c74b..c8a0fac3c7 100644 --- a/scm/output-socket.scm +++ b/scm/output-socket.scm @@ -49,12 +49,12 @@ 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)))) @@ -83,9 +83,9 @@ (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)))) ) diff --git a/scm/output-svg.scm b/scm/output-svg.scm index 2e953a94b2..786a37ca17 100644 --- a/scm/output-svg.scm +++ b/scm/output-svg.scm @@ -24,7 +24,6 @@ (guile) (ice-9 regex) (lily) - (srfi srfi-1) (srfi srfi-13)) @@ -71,16 +70,6 @@ (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))) @@ -204,48 +193,13 @@ (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)))))) @@ -267,7 +221,7 @@ (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) diff --git a/scm/output-tex.scm b/scm/output-tex.scm index 3a3e023ebe..9068f5b937 100644 --- a/scm/output-tex.scm +++ b/scm/output-tex.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys ;; The public interface is tight. @@ -98,8 +98,8 @@ (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))) @@ -173,8 +173,8 @@ (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) diff --git a/scm/output-texstr.scm b/scm/output-texstr.scm index 81303dc0ca..35ed35e3b3 100644 --- a/scm/output-texstr.scm +++ b/scm/output-texstr.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-module (scm output-texstr)) (define this-module (current-module)) diff --git a/scm/page.scm b/scm/page.scm index 83bcb40097..041edd3a72 100644 --- a/scm/page.scm +++ b/scm/page.scm @@ -37,11 +37,10 @@ (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)) @@ -86,37 +85,43 @@ (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 @@ -163,7 +168,7 @@ ;; 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 @@ -194,9 +199,10 @@ (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)) ) @@ -240,19 +246,25 @@ ))) (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)) @@ -266,7 +278,10 @@ (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) @@ -277,7 +292,7 @@ (cons (+ system-xoffset x) (- 0 head-height y (prop 'top-margin))) - + ))))) (add-system (lambda (system) @@ -305,29 +320,25 @@ (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 @@ -359,10 +370,9 @@ ;; 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)) @@ -378,8 +388,11 @@ (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))) diff --git a/scm/paper-system.scm b/scm/paper-system.scm index d3a140531f..d414285d9d 100644 --- a/scm/paper-system.scm +++ b/scm/paper-system.scm @@ -49,105 +49,57 @@ 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) + ))) + + )) diff --git a/scm/paper.scm b/scm/paper.scm index 666745faf4..dae489f9b3 100644 --- a/scm/paper.scm +++ b/scm/paper.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (define-public (set-paper-dimension-variables mod) (module-define! mod 'dimension-variables @@ -120,10 +120,11 @@ (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 diff --git a/scm/parser-clef.scm b/scm/parser-clef.scm index 0095d29e81..66e2c12d45 100644 --- a/scm/parser-clef.scm +++ b/scm/parser-clef.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys ;; (name . (glyph clef-position octavation)) @@ -60,8 +60,6 @@ ("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)))) diff --git a/scm/parser-ly-from-scheme.scm b/scm/parser-ly-from-scheme.scm index 9d2b3b5d47..d7a83a1f4d 100644 --- a/scm/parser-ly-from-scheme.scm +++ b/scm/parser-ly-from-scheme.scm @@ -17,9 +17,8 @@ (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)) @@ -82,6 +81,6 @@ character." ,@(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) diff --git a/scm/part-combiner.scm b/scm/part-combiner.scm index 2fd78599ee..56b43892b9 100644 --- a/scm/part-combiner.scm +++ b/scm/part-combiner.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys ;; todo: figure out how to make module, ;; without breaking nested ly scopes @@ -30,7 +30,7 @@ (define-method (note-events (vs )) (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 )) @@ -116,20 +116,20 @@ Voice-state objects "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)) @@ -139,14 +139,14 @@ Voice-state objects (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) @@ -184,44 +184,7 @@ Voice-state objects (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 @@ -234,15 +197,16 @@ Voice-state objects (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) @@ -279,17 +243,17 @@ Only set if not set previously. (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 (length notes1) 1) (put 'apart)) @@ -363,8 +327,8 @@ Only set if not set previously. (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))) @@ -400,10 +364,7 @@ Only set if not set previously. (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))) @@ -419,7 +380,6 @@ the mark when there are no spanners active. 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 @@ -497,10 +457,13 @@ the mark when there are no spanners active. (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) '())))))) + diff --git a/scm/ps-to-png.scm b/scm/ps-to-png.scm index d76f926a90..50891e8f4b 100644 --- a/scm/ps-to-png.scm +++ b/scm/ps-to-png.scm @@ -129,13 +129,12 @@ (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")) @@ -149,7 +148,7 @@ ;; (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\ diff --git a/scm/safe-lily.scm b/scm/safe-lily.scm index 31161e25cf..b76b3bc2d5 100644 --- a/scm/safe-lily.scm +++ b/scm/safe-lily.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2006 Han-Wen Nienhuys +;;;; (c) 2004--2006 Han-Wen Nienhuys (map (lambda (sym) @@ -96,7 +96,6 @@ ly:output-def-scope ly:output-description ly:paper-book? - ly:prob-property ly:layout-def? ly:paper-get-font ly:paper-get-number diff --git a/scm/script.scm b/scm/script.scm index 6044f61a18..18f39cc7a5 100644 --- a/scm/script.scm +++ b/scm/script.scm @@ -2,51 +2,40 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2000--2006 Han-Wen Nienhuys +;;;; (c) 2000--2006 Han-Wen Nienhuys (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))) @@ -54,180 +43,140 @@ ((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) ) diff --git a/scm/standalone.scm b/scm/standalone.scm index 681a49d042..e7a1e2b290 100644 --- a/scm/standalone.scm +++ b/scm/standalone.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 1998--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys (define standalone (not (defined? 'ly:gulp-file))) ;;(write standalone (current-error-port)) diff --git a/scm/stencil.scm b/scm/stencil.scm index f39328984b..0169419571 100644 --- a/scm/stencil.scm +++ b/scm/stencil.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2003--2006 Han-Wen Nienhuys +;;;; (c) 2003--2006 Han-Wen Nienhuys (define-public (stack-stencils axis dir padding stils) "Stack stencils STILS in direction AXIS, DIR, using PADDING." @@ -179,48 +179,52 @@ encloses the contents. ;; 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)) @@ -279,7 +283,6 @@ grestore (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))) @@ -310,31 +313,30 @@ grestore 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)) @@ -346,12 +348,12 @@ grestore 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) @@ -381,8 +383,5 @@ grestore 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)))))) diff --git a/scm/titling.scm b/scm/titling.scm index 7eae28e66d..f6ac5f0b12 100644 --- a/scm/titling.scm +++ b/scm/titling.scm @@ -3,7 +3,7 @@ ;;;; source file of the GNU LilyPond music typesetter ;;;; ;;;; (c) 2004--2006 Jan Nieuwenhuizen -;;;; Han-Wen Nienhuys +;;;; Han-Wen Nienhuys (define-public (layout-extract-page-properties layout) (list (append `((line-width . ,(ly:paper-get-number diff --git a/scm/to-xml.scm b/scm/to-xml.scm index 5f2828a370..dd9e5bfca7 100644 --- a/scm/to-xml.scm +++ b/scm/to-xml.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2003--2006 Han-Wen Nienhuys +;;;; (c) 2003--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen (use-modules (ice-9 regex) diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm index 0bf05bca57..f3bd616382 100644 --- a/scm/translation-functions.scm +++ b/scm/translation-functions.scm @@ -2,15 +2,26 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 1998--2006 Han-Wen Nienhuys +;;;; (c) 1998--2006 Han-Wen Nienhuys ;;;; Jan Nieuwenhuizen +(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) @@ -61,7 +72,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (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 @@ -72,12 +83,12 @@ (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 @@ -87,7 +98,7 @@ (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)) diff --git a/scripts/abc2ly.py b/scripts/abc2ly.py index 91067a9e1a..6121e51c6a 100644 --- a/scripts/abc2ly.py +++ b/scripts/abc2ly.py @@ -77,16 +77,25 @@ import os 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._ @@ -617,7 +626,6 @@ def fix_lyric(str): 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 @@ -890,8 +898,6 @@ artic_tbl = { '~' : '^"~" ', 'J' : '', # ignore slide 'R' : '', # ignore roll - 'S' : '^\\segno', - 'O' : '^\\coda', 'v' : '^\\downbow' } @@ -1265,7 +1271,7 @@ def try_parse_comment (str): #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') diff --git a/scripts/convert-ly.py b/scripts/convert-ly.py index 1f0ef120f1..c4c1e74082 100644 --- a/scripts/convert-ly.py +++ b/scripts/convert-ly.py @@ -18,15 +18,23 @@ import re 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._ @@ -48,23 +56,25 @@ Examples: ''') copyright = ('Jan Nieuwenhuizen ', - 'Han-Wen Nienhuys ') + 'Han-Wen Nienhuys ') 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 @@ -79,212 +89,212 @@ Copyright (c) %s by 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 () diff --git a/scripts/etf2ly.py b/scripts/etf2ly.py index 0e85317a2e..a5291e92ad 100644 --- a/scripts/etf2ly.py +++ b/scripts/etf2ly.py @@ -43,22 +43,32 @@ if version == '@' + 'TOPLEVEL_VERSION' + '@': ################################################################ # 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 diff --git a/scripts/lilypond-book.py b/scripts/lilypond-book.py index 3f306560d6..486d21fedb 100644 --- a/scripts/lilypond-book.py +++ b/scripts/lilypond-book.py @@ -36,21 +36,40 @@ import os 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 /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) @@ -134,7 +153,6 @@ def get_option_parser (): 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', @@ -148,12 +166,6 @@ def get_option_parser (): 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''' @@ -538,6 +550,7 @@ output = { LATEX: { OUTPUT: r'''{%% \parindent 0pt%% +\catcode`\@=12%% \ifx\preLilyPondExample \undefined%% \relax%% \else%% @@ -630,7 +643,17 @@ if 0: 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 @@ -643,13 +666,13 @@ PREAMBLE_LY = '''%%%% Generated by %(program_name)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 } ''' @@ -829,9 +852,7 @@ class Lilypond_snippet (Snippet): 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 () @@ -845,7 +866,7 @@ class Lilypond_snippet (Snippet): 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: @@ -1146,7 +1167,7 @@ class Lilypond_snippet (Snippet): if VERBATIM in self.option_dict: verb = self.substring ('code') str += (output[LATEX][VERBATIM] % vars ()) - + str += (output[LATEX][OUTPUT] % vars ()) ## todo: maintain breaks @@ -1210,8 +1231,8 @@ class Lilypond_file_snippet (Lilypond_snippet): ## 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 = { @@ -1244,7 +1265,7 @@ def find_toplevel_snippets (s, types): 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 @@ -1366,11 +1387,11 @@ def process_snippets (cmd, ly_snippets, texstr_snippets, png_snippets): 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 @@ -1382,11 +1403,7 @@ def process_snippets (cmd, ly_snippets, texstr_snippets, png_snippets): 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 @@ -1480,13 +1497,15 @@ class Compile_error: 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') @@ -1703,31 +1722,14 @@ def main (): 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: @@ -1751,18 +1753,18 @@ def main (): 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 () diff --git a/scripts/midi2ly.py b/scripts/midi2ly.py index 4a0d956211..256063d679 100644 --- a/scripts/midi2ly.py +++ b/scripts/midi2ly.py @@ -28,17 +28,32 @@ import sys ################################################################ # 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 diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 4240b3aaae..5f25567c59 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -9,17 +9,28 @@ from gettext import gettext as _ -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 @@ -110,7 +121,7 @@ def musicxml_key_to_lily (attributes): try: (n,a) = { 'major' : (0,0), - 'minor' : (5,0), + 'minor' : (6,0), }[mode] start_pitch.step = n start_pitch.alteration = a @@ -124,6 +135,7 @@ def musicxml_key_to_lily (attributes): fifth.step *= -1 fifth.normalize () + start_pitch = musicexp.Pitch() for x in range (fifths): start_pitch = start_pitch.transposed (fifth) diff --git a/stepmake/aclocal.m4 b/stepmake/aclocal.m4 index 813b830977..5a9e739ad9 100644 --- a/stepmake/aclocal.m4 +++ b/stepmake/aclocal.m4 @@ -26,16 +26,14 @@ AC_DEFUN(STEPMAKE_GET_VERSION, [ ## -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\}' \ @@ -287,12 +285,10 @@ AC_DEFUN(STEPMAKE_DATADIR, [ 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}"]) diff --git a/stepmake/bin/add-html-footer.py b/stepmake/bin/add-html-footer.py index 7f2ef65dcd..1a5cbccfc0 100644 --- a/stepmake/bin/add-html-footer.py +++ b/stepmake/bin/add-html-footer.py @@ -47,7 +47,7 @@ default_footer = r"""
Please take me back to the index of @PACKAGE_NAME@ """ -built = r''' +built = r"""
%(wiki_string)s

@@ -58,10 +58,23 @@ This page is for %(package_name)s-%(package_version)s (%(branch_str)s).
Report errors to %(mail_address)s.

-''' - +""" +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 @@ -125,7 +138,7 @@ def set_gcos (): def compose (default, file): s = default if file: - s = open (file).read () + s = gulp_file (file) return s set_gcos () @@ -187,7 +200,7 @@ def remove_self_ref (s): return s def do_file (f): - s = open (f).read() + s = gulp_file (f) s = re.sub ('%', '%%', s) diff --git a/stepmake/stepmake/generic-targets.make b/stepmake/stepmake/generic-targets.make index 972d3fd671..ea288ca58c 100644 --- a/stepmake/stepmake/generic-targets.make +++ b/stepmake/stepmake/generic-targets.make @@ -69,7 +69,6 @@ Note that all commands recurse into subdirectories;\n\ 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) diff --git a/stepmake/stepmake/generic-vars.make b/stepmake/stepmake/generic-vars.make index c61fa5ec82..1607631205 100644 --- a/stepmake/stepmake/generic-vars.make +++ b/stepmake/stepmake/generic-vars.make @@ -29,7 +29,7 @@ endif 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) diff --git a/stepmake/stepmake/po-vars.make b/stepmake/stepmake/po-vars.make deleted file mode 100644 index 1bb8bf6d7f..0000000000 --- a/stepmake/stepmake/po-vars.make +++ /dev/null @@ -1 +0,0 @@ -# empty diff --git a/stepmake/stepmake/texinfo-rules.make b/stepmake/stepmake/texinfo-rules.make index 5cf8c2d011..5941224ed1 100644 --- a/stepmake/stepmake/texinfo-rules.make +++ b/stepmake/stepmake/texinfo-rules.make @@ -20,8 +20,9 @@ $(outdir)/%.ps.gz.omf: %.texi $(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) $( 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 }% } @@ -1246,10 +1238,9 @@ where each line of input produces a line of output.} \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 @@ -1257,8 +1248,8 @@ where each line of input produces a line of output.} \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 @@ -1481,7 +1472,6 @@ where each line of input produces a line of output.} % We don't need math for this font style. \def\ttsl{\setfontstyle{ttsl}} - % Default leading. \newdimen\textleading \textleading = 13.2pt @@ -1503,13 +1493,11 @@ where each line of input produces a line of output.} }% } - % 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. @@ -1533,10 +1521,6 @@ where each line of input produces a line of output.} \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} @@ -1650,165 +1634,6 @@ where each line of input produces a line of output.} \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 @@ -1919,7 +1744,7 @@ where each line of input produces a line of output.} % 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$} @@ -3403,39 +3228,12 @@ where each line of input produces a line of output.} \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 } @@ -4584,17 +4382,14 @@ where each line of input produces a line of output.} \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. @@ -4604,7 +4399,6 @@ where each line of input produces a line of output.} \else \setbox0 = \hbox{#3\enspace}% \def\toctype{numchap}% - \xdef\thischapternum{\the\chapno}% \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% \fi\fi\fi @@ -5268,7 +5062,7 @@ where each line of input produces a line of output.} % \maketwodispenvs {lisp}{example}{% \nonfillstart - \tt\quoteexpand + \tt \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. \gobble % eat return } @@ -5882,6 +5676,7 @@ where each line of input produces a line of output.} \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}% @@ -6148,11 +5943,11 @@ where each line of input produces a line of output.} % {. 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. -- 2.39.2