From: Han-Wen Nienhuys Date: Tue, 26 Oct 1999 20:10:16 +0000 (+0200) Subject: release: 1.3.0 X-Git-Tag: release/1.3.0 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=3a0e9efb7f067e5b334ba0596b95e15d96d7cc49;hp=8002fa018c81f70585c25232247c6dcba7f5cba0;p=lilypond.git release: 1.3.0 --- diff --git a/CHANGES b/CHANGES index 604f59c4aa..661f51cdb5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,257 +1,16 @@ -pl 15 (Oct 18) +1.3.0: -14.jcn1 - - Kludge for accented chars (thanks, Mats) - - bf: don't fail on error in doco package - - doco package: noarch - - bf: standchen: mutopia prep +pl 15.hwn2 + - loads of bfs. -14.hwn1 - - move some misc stuff into Documentation/misc/ - - cleanups: slur & beam. - - junked Encompass_info - - Smobs -- simplifies sc_elt memory management - - Timing_engraver collects bar reqs - - unfold all if doing MIDI. - - bfs: do something sensible if it doesn't fit. - - penalties for break stuff supported. +pl x.jcn3 + - another workaround: reset buffer state for scm_ftell () + - workaround for broken scm_ftell () -******* -13.jcn2,3 - - mutopia/J.S.Bach/Petites-Preludes: bf's and mutopia preraration - - separate documentation package +pl 15.hwn1 + - \properties are now SCM s, junk Scalar type + - use SCM for strings in parser. + - Moment derived from Rational. Moment may be smobified. -13.hwn2 - - mutopia: scs2, horn-concerto-3 - - junked Line_spacer baseclass. - - removed gourlay complications - - use force iso. energy for minimisation. Add uniformity term -to demerits. - -13.jcn1 - - bf: mudela-book - -******* -12.jcn1 - - auto-knees, input/test/auto-knee.ly - -pl 12.rrr2 - - voltaSpannerDuration may be a rational - - .ly files corrected, Voice.dynamicDir to Voice.dynamicDirection - -pl 12.rrr1 - - key (K:) with clef, bug fix for abc2ly - - voltaSpannerDuration code added to lilypond - -pl 12.hwn1 - - junked wordwrap - - bf: use position (not pitch) for autochange - - mudela-book fixes: --dependencies, --dep-prefix - - mudela.tely more updates. Now absorbed LilyPond manpage. - - BUGS now in INSTALL.texi - -******* -pl 11.uu1 - - changed debug init code. - -pl 11.jcn2 - - bf: LDFLAGS=foo CFLAGS=bar ./configure - - bf: configure (--disable-printing = default) -DNPRINT - - bf: mf-to-xpms / make -C mf xpms; feta-accordion is broken, - see mf/README - -pl 11.jcn1 - - gnossiene with new \autochange - -pl 11.jbr1 - - Tried to get rid of path and switch dependencies in mf - build process. - -pl 11.hwn1 - - doco reorganisation: folded glossary and tutorial into manual. - - move mudela-book-doc to texinfo - - feta.tex to mf/ - - release.py, package-diff.py now dump into out/ - - -**** -pl 10.hwn1 - - Auto_change_music, Auto_change_iterator: auto staff -switching. 2nd try. See input/test/auto-change.ly - -pl 10.uu1 - - doc restructure: hacking.texi - - make & install .pfas - - updates: faq.texi - - rpm fixes. - - Windows fixes (9.jbr) - -****** -pl 9.rrr1 - - abc2ly bug fixes and extensions - - volta spanner given height to avoid collisions - -pl 9.jcn2 - - 2.95 fixes - - input/test/different-time-signatures.ly (wasn't this in refman?) - -pl 9.hwn1 - - fixes for mi2mu - - bf: staff-side with empty parent. - - bf: -Hara_kiri_vertical_group_spanner::do_substitute_element_pointer has to -call Axis_group_spanner::do_substitute_element_pointer. Fixes -harakiri & barline problem. - - junk: Spring_spacer, Ineq_constrained_qp, Mixed_qp, -Active_constraints, Inactive_iter, Matrix, Vector, -Choleski_decomposition, Full_storage - - -pl 9.jcn1 - - included last Localisation.texi - - set-lily: de catalog too - -******* -pl 8.hwn1 - - Erwin Dieterich: german translation. - - dependency helper funcs simplified. - - junk breaking stats. - - cleanups: Line_of_score also is X_AXIS group. Score_columns -are put into Line_of_score of score. - -pl 8.jcn2 - - scripts/mudela-book.py: use hash of full .ly contents (by default) - - bf: footify html doc upon creation too - -pl 8.jcn1 - - Documentation/Localisation.texi: still some issues - - Uniformised locale strings - - marked some errors/warnings without _/_f markings - - added programming_warning (): not to be localised warnings - (none identified as yet) - - Update of po/nl.po - -******* -pl 7.hwn1 - - website fixes. - - spacer cleanups - - Simple_spacer: a simpler constraint solver. Enabled by default. -pl 7.jcn1 - - fixes to nl.po - -******** - -pl 6.uu1 - - website fixes. - -******* -pl 5.hwn1 - - more .texi; yodl completely removed. - - rm'd several doc stuff: engraving.yo, gnu-page.yo, translated blurbs (leave it to translation project) - - sm: help2man-*make - - mcgrain bib entry. - - debian updates. - - gcc 2.95 const fixes. (hopefully) - - sm: rm'd Documentation/tex/ directory. everything in stepmake/INSTALL.texi - -pl 5.jcn1 - - lily.scm: don't use regex-substitute/global - - website/doco fixes - - bf: package-diff.py - -************ - -pl 4.hwn1 - - bf: repeats. - - bf: mmrests - - bf: simpler guile detection. - - use texinfo for reference manual. - - inline lily.ps from lilypond. - - texi for doco: converted directory Documentation/tex/ - - -pl 3.hwn1 - - mudela-book tweaks for surviving texinfo - - include feta command seqs. in .tex - - guile 1.3.2 fixes. - - include config.h directly. - - bf: mudela-book. Now linear in size of document. - - scriptHorizontal property; more or less works. - - changes in Graphical_element, Graphical_axis_group -offset removed from public interface, now use relative_coordinate (). -extent () is given relative to this. - - removed Rhythmic_head::dots_i_ - - bf: Rhythmic_head::do_substitute_element_pointer () - - Direct access to dim_cache_ replaced by methods in -Graphical_element. - -********** - - -pl 2.mk1 - - bf, tie.cc: handle postbreak left align correctly -pl 2.lec1 - - abc2ly fixes. - -pl 2.hwn1 - - rewrite of mudela-book. Now uses chunks, and you can put -\input, \include and \mudelagraphics in verbatim sections. - - -pl 2.jcn2 - - bf: auto-beamer: don't junk beam if manual beam shows up - -pl 2.jcn1 - - add-html-footer.py, ls-latex.py .tely updates and fixes - - tely (texinfo-lily) rules and test Documentation/metadoc/foo.tely - -************* - -pl 1.uu2 - - complete rewrite of mudela-book. Much cleaner now. -Support for texinfo. - - convert-mudela now per file, add \version if not present. - -pl 1.uu1.jcn1 - - internationalization fixes for getopt-long help - -pl 1.uu1 - - rewrite --help messages for help2man: - * lilypond - * mi2mu - * mudela-book - * convert-mudela - - cleanup: mf-to-table.py - - Getopt_long: support for --help msg. - -pl 1.mb1 - - bf, scalar.cc: ".3" now detected as numerical - -******** - -pl 0.uu1 - - refman updates by Werner & Mats - - now use ChangeLog for changes. - -pl 0.jcn2 - - po fixes - -pl 0.jcn1 - - gcc-2.95 nitpicks - - added pointers to mailing lists in toplevel docs - -0.mb2 - - configure: more robust detection of Guile - - Midi_note_off: revert to fixed note-off velocity. Fixes - problem with notes that never stop. - - Decreased breakable_column_space_strength - - Added a few TODO - - bf: "harmonic" and "cross" note heads also for half and - whole notes. - - linewidth and textheight set independent of the font size. - - bf, titledefs.tex: opus and piece are not repeated for - every piece unless they are explicitly set again. - -0.mb1 - - Changed dynamicDir to dynamicDirection. - - refman and tutorial corrections. +pl 15.jcn4 + - direct #... to scm parser (Thanks to Gary Houston) diff --git a/Documentation/GNUmakefile b/Documentation/GNUmakefile index 1d6e86f54e..b3fda3a821 100644 --- a/Documentation/GNUmakefile +++ b/Documentation/GNUmakefile @@ -1,10 +1,10 @@ depth = .. NAME = documentation -SUBDIRS= user metadoc bibliography pictures topdocs ntweb misc +SUBDIRS= user programmer bibliography pictures topdocs ntweb misc STEPMAKE_TEMPLATES=documentation texinfo -README_TOP_FILES=NEWS DEDICATION CHANGES +README_TOP_FILES=NEWS DEDICATION CHANGES TODO EXTRA_DIST_FILES = include $(depth)/make/stepmake.make diff --git a/Documentation/bibliography/GNUmakefile b/Documentation/bibliography/GNUmakefile index 899251880a..ca0c7ae4a4 100644 --- a/Documentation/bibliography/GNUmakefile +++ b/Documentation/bibliography/GNUmakefile @@ -2,23 +2,9 @@ depth=../.. -DATA_FILES = $(wildcard *.data) -datafiles = $(addprefix $(outdir)/,$(DATA_FILES:.data=.html)) -TEX_FILES = $(wildcard *.tex) -DOC_FILES = $(wildcard *.doc) -DVI_FILES = $(addprefix $(outdir)/,$(DOC_FILES:.doc=.dvi) $(YO_FILES:.yo=.dvi)) OUT_BIB_FILES = $(addprefix $(outdir)/, $(BIB_FILES)) - -# just include me -YO_URG_FILES = $(wildcard *.yo-urg) - -OUTTEX_FILES = $(addprefix $(outdir)/, $(TEX_FILES)) -OUTDOC_FILES = $(addprefix $(outdir)/, $(DOC_FILES)) -EL_FILES = $(wildcard *.el) BIB_FILES= $(wildcard *.bib) -EXTRA_DIST_FILES= $(BIB_FILES) $(DOC_FILES) $(DATA_FILES) $(EL_FILES) $(YO_URG_FILES) $(TEX_FILES) $(wildcard *.sty) -HTML_FILES = $(addprefix $(outdir)/, $(YO_FILES:.yo=.html)) -PS_FILES = $(DVI_FILES:.dvi=.ps) +EXTRA_DIST_FILES= $(BIB_FILES) STEPMAKE_TEMPLATES=tex documentation LOCALSTEPMAKE_TEMPLATES=lilypond mudela @@ -26,12 +12,7 @@ LOCALSTEPMAKE_TEMPLATES=lilypond mudela export BIBINPUTS:=$(shell pwd)//$(PATHSEP)$(BIBINPUTS) include $(depth)/make/stepmake.make - - - - - -dvi: $(OUT_BIB_FILES) $(DVI_FILES) +dvi: $(DVI_FILES) $(OUT_BIB_FILES) ps: $(PS_FILES) @@ -41,18 +22,7 @@ default: GENHTMLS = engraving colorado computer-notation OUTGENHTMLS = $(addprefix $(outdir)/, $(GENHTMLS:%=%.html)) -#urg should generalise and move Lilypond -> StepMake -# URG. Lilypond specific. Move out. -$(outdir)/%.html: %.data $(depth)/VERSION - $(PYTHON) $(step-bindir)/table-to-html.py --columns=7 --linesep=' ' -o $@ $< - $(PYTHON) $(step-bindir)/add-html-footer.py $@ - -$(outdir)/%.tex: %.data $(depth)/VERSION - $(PYTHON) $(step-bindir)/table-to-html.py --columns=7 --linesep=' ' -o $@ --latex $< - - - -local-WWW: $(HTML_FILES) $(OUTTEX_FILES:.tex=.ps.gz) $(OUTYO_FILES:.yo=.latex) $(OUTYO_FILES:.yo=.ps.gz) $(addprefix $(outdir)/, $(BIB_FILES:.bib=.html)) $(datafiles) +local-WWW: $(addprefix $(outdir)/, $(BIB_FILES:.bib=.html)) $(PYTHON) $(step-bindir)/ls-latex.py --title 'References on Music Notation' \ $(YO_FILES) $(OUTYO_FILES:.yo=.latex) $(BIB_FILES) $(DOC_FILES) $(TEX_FILES) \ | sed "s!$(outdir)/!!g" > $(outdir)/index.html @@ -63,12 +33,7 @@ $(outdir)/%.bib: %.bib # ignore result since bib2html is nonstandard. Errors would halt the RPM build.j $(outdir)/%.html: %.bib -bib2html $< $@ +# $(footify) $@ -# Yeah right: -# make -k out/mudela.dvi => cp -f out/vocabulary.tex out/mudela.dvi - -#out/%: $(outdir)/% -# cp -f $< $@ - -locamlclean: +localclean: rm -f fonts.aux fonts.log feta*.tfm feta*.*pk diff --git a/Documentation/faq.texi b/Documentation/faq.texi index da64d5cc52..b8dbb30787 100644 --- a/Documentation/faq.texi +++ b/Documentation/faq.texi @@ -77,7 +77,7 @@ yourself: @subsubsection Some of your neat scripts fail, what directories do you use: -[This only applies if you don't do @code{make install}, and develop out +[This only applies if you don't do @code{make install}, and run out of the source directory] I have a directory which contains all our development projects @@ -100,16 +100,13 @@ which looks like @file{/usr/} @end example - - - -~/usr/src/bin is in the PATH, and contains symbolic links to the -compiled executables. +@file{~/usr/src/bin/} is in the variable PATH, and contains symbolic +links to the compiled executables. @subsubsection Is there an emacs mode? Yes. It is included with the source archive as mudela-mode.el. If -you have an rpm it is in /usr/doc/lilypond-X/. You have to install it +you have an rpm it is in @file{/usr/doc/lilypond-X/}. You have to install it yourself. @subsubsection How do I create the @file{.tfm} files? @@ -124,12 +121,12 @@ be used by LilyPond, not by any other programs. @subsubsection Why is the documentation/website/etc. so lousy? -LilyPond development is moving quite fast, documentation will often -lag a bit behind. We must always make a choice between writing more -doco, writing more code and answering email. +LilyPond development is moving quite fast, documentation will often lag +a bit behind. We must always make a choice between writing more +documentation, writing HTML, writing more code and answering email. -If you think you can make a correction, or devised a solution that -should be documented, please do so and send in a patch. +If you think you can make a correction, or devised a solution that +should be documented, please write it up, and us a diff. @node Language- mudela, Do you support -, Documentation, FAQ - GNU LilyPond FAQs @section Language: mudela @@ -195,20 +192,20 @@ notation. We would welcome anyone who could give this a try. @subsubsection Do you support TAB notation? -No. The same as for the previous subsubsection goes, but TAB is a lot -more work than diagrams (TAB needs modification of Parser, Lexer, -Staff, Notehead, Stem code and all the code that creates these graphic -elements.) +No. The same as for the previous subsubsection goes. + @subsubsection Do you support multiple staff-sizes? -Yes. At this time you can choose between 11, 13, 16, 19, 20, 23 and -20 pt staff-size. Use the staffLineLeading property for setting the -size of the staff, and fontSize for setting the size of the glyphs. +Yes. At this time you can choose between 11, 13, 16, 19, 20, 23 and 20 +pt staff-size. Use the @code{staffLineLeading} property for setting the +size of the staff, and @code{fontSize} for setting the size of the +glyphs. @subsubsection Do you support Gregorian chant notation? -No. Go ahead. +No. + @subsubsection Do you support grace notes? @@ -318,38 +315,34 @@ to get a bit less frivolous tagging. @subsubsection Could you implement feature XXXX? It is really easy, just extend the syntax to allow YYYY! -If it is reasonable, I'll add XXXX to the TODO list. In general -finding a cute syntax (such as YYYY) isn't very hard. The complicated -issue how to adapt the internals to do XXXX. The parser is really a -simple front end to the complicated internals. +In general finding a cute syntax (such as YYYY) isn't very hard. The +complicated issue how to adapt the internals to do XXXX. The parser is +really a simple front end to the complicated internals. @subsubsection Can I join in on LilyPond development? How do I do this? -LilyPond development is open for anyone who wants to join. We do -frequent releases, you are welcome to send in a patch or do suggestions. -Join the gnu-music-discuss mailing list to participate. +Yes, we do frequent releases, you are welcome to send in a patch or do +suggestions. Join the list @email{gnu-music-discuss@@gnu.org} to +participate. -@subsubsection I want to implement XXXX! Should I do this? - -Yes. - -But since there might be better ways of doing XXXX, so it's a good thing to -ask about this before you start hacking. If you want to keep in touch -with current developments, you should subscribe to the mailing list - @subsubsection Is there a GUI frontend? Should I start building one? -LilyPond currently has no graphical interface. The authors seriously -doubt if a simple-minded approach (dragging and dropping notes) is any -easier or quicker to use than mudela. But for composing a graphical -environment probably is indispensable. +LilyPond currently has no graphical interface. We (LilyPond authors) +don't feel the need to write a GUI, but several others do: Matthew Hiller has extended Midiscore and Koobase to handle mudela. -Check out @uref{http://zoo.cs.yale.edu/~meh25/}. +Check out @uref{http://zoo.cs.yale.edu/~meh25/}. He is now working on +`Denemo', a GTK based notation program (which is still being developed). -If you want to work on this, please send e-mail to the mailing list -@email{gnu-music-discuss@@gnu.org}. +Federico Mena-Quintero and Elliot Lee of RedHat Advanced Development +labs have plans to write a GNOME based Music notation program. However, +there is no code, only plans. + +Chris Cannam is working a rewrite of Rosegarden. The new design should +be more modular, and could conceivably be used to output +mudela. However, the not much seems to have happened the past year. See +@uref{http://www.all-day-breakfast.com/rosegarden/development.html}. @subsubsection I want to implement XXXX! How should I do this? @@ -360,32 +353,20 @@ Your best bet of getting us to include code, is to present it as a Please use the diff command to generate a patch, and don't send complete files, even if the diff is larger than the whole file. -Don't forget to put your name and e-mail address -in the @file{AUTHORS.pod} file, or you won't get credits :-] +Don't forget to put your name and e-mail address in the file +@file{Documentation/topdocs/AUTHORS.texi}, or you won't get credits +:-) @subsubsection Your make system does not adhere to GNU coding standards, could you please fix it? No. We have evaluated the standard GNU combination for compiling -programs (autoconf, automake, libtool) and found to be inadequate in -several respects. More detailed argumentation is included with -LilyPond's generic make package @code{StepMake} -(see @file{stepmake-x.x.x/Documentation/automake.urgh}) - -LilyPond already compiles into a different directory ((the different -directory is called out/, there is one in every source directory). -make distclean essentially reduces to @file{rm -f out/*} in every directory +programs (autoconf, automake, libtool) and found to be inadequate for +our needs. @subsubsection gdb crashes when I debug! -Upgrade to 4.17. - -@subsubsection Why do I need g++ >= 2.8 / EGCS-1.1 ? - -Supporting more compilers than EGCS/G++ 2.8 is unlikely to make -LilyPond run on more platforms. It would give us an enormous headache -in detecting and catering for every variant of every compiler: not -having to support other compilers saves us a @emph{lot} of trouble. +Upgrade/downgrade to 4.17. @node Running, Copyright, Development, FAQ - GNU LilyPond FAQs @section Running @@ -466,24 +447,6 @@ output, use TeX and @code{dvips}. The beams and slurs are done in PostScript. XDvi doesn't show PostScript in the magnifying glass. Complain to the XDvi maintainers. -@subsubsection I don't get midi-output, even if I use @strong{-m}! - -Your \score should include a \midi block, eg. -@example - - \score @{ - \melodic @{ c4 c g g @} - \paper @{@} - \midi @{ - output = "myfile.midi"; - \tempo 4=70; - @} - @} - -@end example - -The @strong{-m} option was added to LilyPond to suppress paper output, -because processing the \paper block is so slow. @subsubsection A lot of musical stuff doesn't make it to the MIDI file, eg. dynamics, articulation, etc. diff --git a/Documentation/footer.html.in b/Documentation/footer.html.in index 4b99be2c58..50bcaf5b2d 100644 --- a/Documentation/footer.html.in +++ b/Documentation/footer.html.in @@ -11,7 +11,7 @@ footer substitutions: * ENV:WEBMASTER, * ENV:WEBMASTER -> +-->
Go back to index of LilyPond. @@ -23,7 +23,7 @@ Please send GNU LilyPond questions and comments to gnu-music-discuss@gnu.org.

- Please send comments on these web pages to %s diff --git a/Documentation/index.texi b/Documentation/index.texi index 31afd58918..0187a0a409 100644 --- a/Documentation/index.texi +++ b/Documentation/index.texi @@ -21,13 +21,14 @@ @item @uref{faq.html,Frequently asked questions}, with answers @item @uref{programs.html,`Manual pages'} @item @uref{../user/out-www/index.html,User documentation} -@item @uref{../metadoc/out-www/index.html,Hacker documentation} -@item @uref{../bibliography/out-www/,Bibliography} +@item @uref{../programmer/out-www/index.html,Programmer's documentation} +@item @uref{../bibliography/out-www/index.html,Bibliography} @item @uref{../misc/out-www/index.html,Miscellaneous texts} @end itemize -@unnumberedsubsec{Status} +@unnumberedsubsec Status + @itemize @item @uref{TODO.txt, Thing to do} @item @uref{CHANGES.txt, Things recently done} @@ -43,7 +44,8 @@ @unnumberedsubsec Logo: @itemize @item @uref{../pictures/out-www/lelieblond.png, logo} in large size -@item @uref{../pictures/out-www/lelie_logo.png, logo} in medium size +@item @uref{../pictures/out-www/lelie-logo.png, logo} in medium size +@item @uref{../pictures/out-www/lelie-icon.png, logo} in small size @end itemize @bye diff --git a/Documentation/metadoc/GNUmakefile b/Documentation/metadoc/GNUmakefile deleted file mode 100644 index 25b42eea53..0000000000 --- a/Documentation/metadoc/GNUmakefile +++ /dev/null @@ -1,36 +0,0 @@ -# Documentation/tex/Makefile - -depth=../.. - -TEX_FILES = $(wildcard *.tex) -DOC_FILES = $(wildcard *.doc) -DVI_FILES = $(addprefix $(outdir)/,$(DOC_FILES:.doc=.dvi) $(TELY_FILES:.tely=.dvi)) - -OUTTEX_FILES = $(addprefix $(outdir)/, $(TEX_FILES)) -OUTDOC_FILES = $(addprefix $(outdir)/, $(DOC_FILES)) - -EXTRA_DIST_FILES= $(DOC_FILES) $(TEX_FILES) $(wildcard *.sty) -HTML_FILES = $(addprefix $(outdir)/, $(TEXI_FILES:.texi=.html) $(TELY_FILES:.tely=.html)) -PS_FILES = $(DVI_FILES:.dvi=.ps) - -STEPMAKE_TEMPLATES=tex documentation texinfo -LOCALSTEPMAKE_TEMPLATES=lilypond mudela - -export BIBINPUTS:=$(shell pwd)//$(PATHSEP)$(BIBINPUTS) -include $(depth)/make/stepmake.make - -dvi: $(DVI_FILES) - -ps: $(PS_FILES) - -# urg -default: - - -localclean: - rm -f fonts.aux fonts.log feta*.tfm feta*.*pk - -local-WWW: $(HTML_FILES) - $(PYTHON) $(step-bindir)/ls-latex.py --title 'Hacker documentation' \ - $(DOC_FILES) $(TEXI_FILES) $(TELY_FILES) \ - | sed "s!$(outdir)/!!g" > $(outdir)/index.html diff --git a/Documentation/metadoc/feta20.sty b/Documentation/metadoc/feta20.sty deleted file mode 100644 index 0dbfcf90cc..0000000000 --- a/Documentation/metadoc/feta20.sty +++ /dev/null @@ -1,146 +0,0 @@ -% Creator: mf-to-table.py version 0.7 -% Automatically generated on -% Do not edit -% input from out/feta20.log -% name -% rests -\fetdef\wholerest{0} -\fetdef\halfrest{1} -\fetdef\outsidewholerest{2} -\fetdef\outsidehalfrest{3} -\fetdef\breverest{4} -\fetdef\longarest{5} -\fetdef\multirest{6} -\fetdef\quartrest{7} -\fetdef\eighthrest{8} -\fetdef\sixteenthrest{9} -\fetdef\thirtysecondrest{10} -\fetdef\sixtyfourthrest{11} -\fetdef\hundredtwentyeighthrest{12} - -% accidentals -\fetdef\sharp{13} -\fetdef\natural{14} -\fetdef\flat{15} -\fetdef\flatflat{16} -\fetdef\sharpsharp{17} -\fetdef\rightparen{18} -\fetdef\leftparen{19} - -% dots -\fetdef\dot{20} -\fetdef\repeatcolon{21} - -% balls -\fetdef\brevisball{22} -\fetdef\brevisledger{23} -\fetdef\longaball{24} -\fetdef\longaledger{25} -\fetdef\wholeball{26} -\fetdef\wholeledger{27} -\fetdef\halfball{28} -\fetdef\halfledger{29} -\fetdef\quartball{30} -\fetdef\quartledger{31} - -% scripts -\fetdef\ufermata{32} -\fetdef\dfermata{33} -\fetdef\thumb{34} -\fetdef\sforzatoaccent{35} -\fetdef\staccato{36} -\fetdef\ustaccatissimo{37} -\fetdef\dstaccatissimo{38} -\fetdef\tenuto{39} -\fetdef\umarcato{40} -\fetdef\dmarcato{41} -\fetdef\ouvert{42} -\fetdef\plusstop{43} -\fetdef\upbow{44} -\fetdef\downbow{45} -\fetdef\reverseturn{46} -\fetdef\turn{47} -\fetdef\trill{48} -\fetdef\upedalheel{49} -\fetdef\dpedalheel{50} -\fetdef\upedaltoe{51} -\fetdef\dpedaltoe{52} -\fetdef\flageolet{53} -\fetdef\trilelement{54} -\fetdef\prall{55} -\fetdef\mordent{56} -\fetdef\prallprall{57} -\fetdef\prallmordent{58} -\fetdef\upprall{59} -\fetdef\downprall{60} -\fetdef\accDiscant{61} -\fetdef\accDiscantF{62} -\fetdef\accDiscantEh{63} -\fetdef\accDiscantE{64} -\fetdef\accDiscantFE{65} -\fetdef\accDiscantFEh{66} -\fetdef\accDiscantEE{67} -\fetdef\accDiscantFEE{68} -\fetdef\accDiscantEEE{69} -\fetdef\accDiscantFEEE{70} -\fetdef\accDiscantS{71} -\fetdef\accDiscantFS{72} -\fetdef\accDiscantES{73} -\fetdef\accDiscantEhS{74} -\fetdef\accDiscantFES{75} -\fetdef\accDiscantFEhS{76} -\fetdef\accDiscantEES{77} -\fetdef\accDiscantFEES{78} -\fetdef\accDiscantEEES{79} -\fetdef\accDiscantFEEES{80} -\fetdef\accDiscantSS{81} -\fetdef\accDiscantESS{82} -\fetdef\accDiscantEESS{83} -\fetdef\accDiscantEEESS{84} -\fetdef\accFreebass{85} -\fetdef\accFreebassF{86} -\fetdef\accFreebassE{87} -\fetdef\accFreebassFE{88} -\fetdef\accStdbass{89} -\fetdef\accStdbassM{90} -\fetdef\accStdbassBp{91} -\fetdef\accStdbassT{92} -\fetdef\accStdbassTp{93} -\fetdef\accBayanbass{94} -\fetdef\accBayanbassT{95} -\fetdef\accBayanbassE{96} -\fetdef\accBayanbassTE{97} -\fetdef\accBayanbassEE{98} -\fetdef\accBayanbassTEE{99} -\fetdef\accSB{100} -\fetdef\accBB{101} -\fetdef\accOldEE{102} -\fetdef\accOldEES{103} - -% flags -\fetdef\eighthflag{104} -\fetdef\sixteenthflag{105} -\fetdef\thirtysecondflag{106} -\fetdef\sixtyfourthflag{107} -\fetdef\deighthflag{108} -\fetdef\dsixteenthflag{109} -\fetdef\dthirtysecondflag{110} -\fetdef\dsixtyfourthflag{111} - -% clefs -\fetdef\altoclef{112} -\fetdef\caltoclef{113} -\fetdef\bassclef{114} -\fetdef\cbassclef{115} -\fetdef\trebleclef{116} -\fetdef\ctrebleclef{117} - -% timesig -\fetdef\fourfourmeter{118} -\fetdef\allabreve{119} -\fetdef\oldfourfourmeter{120} -\fetdef\oldallabreve{121} -\fetdef\oldthreetwometer{122} -\fetdef\oldsixfourmeter{123} -\fetdef\oldninefourmeter{124} - diff --git a/Documentation/metadoc/fonts.doc b/Documentation/metadoc/fonts.doc deleted file mode 100644 index 287dde49b1..0000000000 --- a/Documentation/metadoc/fonts.doc +++ /dev/null @@ -1,330 +0,0 @@ - - % -*-LaTeX-*- - -\documentclass{article} -\def\kdots{,\ldots,} -\title{Not the Font-En-Tja font} -\author{HWN \& JCN} -\def\preMudelaExample{} -\def\postMudelaExample{} -\begin{document} -\maketitle - - -\section{Introduction} - -This document are some design notes of the Feta font, and other -symbols related to LilyPond. Feta (not an abbreviation of -Font-En-Tja) is a font of music symbols. All MetaFont sources are -original. The symbols are modelled after various editions of music, -notably \begin{itemize} \item B\"arenreiter \item Hofmeister \item -Breitkopf \item Durand \& C'ie \end{itemize} - -The best references on Music engraving are Wanske\cite{wanske} and -Ross\cite{ross} some of their insights were used. Although it is a -matter of taste, I'd say that B\"arenreiter has the finest typography -of all. - - -\section{Bezier curves for slurs} - -Objective: slurs in music are curved objects designating that notes -should fluently bound. They are drawn as smooth curves, with their -center thicker and the endings tapered. - -There are some variants: the simplest slur shape only has the width as -parameter. Then we give some suggestions for tuning the shapes. The -simple slur algorithm is used for drawing ties as well. - - - -\subsection{Simple slurs} - -Long slurs are flat, whereas short slurs look like small circle arcs. -Details are given in Wanske\cite{ross} and Ross\cite{wanske}. The -shape of a slur can be given as a Bezier curve with four control -points: - -\begin{eqnarray*} - B(t) &=& (1-t)^3c_1 +3(1-t)^2tc_2 + 3(1-t)t^2c_3 + t^3c_4. -\end{eqnarray*} - -We will assume that the slur connects two notes of the same -pitch. Different slurs can be created by rotating the derived shape. -We will also assume that the slur has a vertical axis of symmetry -through its center. The left point will be the origin. So we have -the following equations for the control points $c_1\kdots c_4$. - -\begin{eqnarray*} -c_1&=& (0,0)\\ -c_2&=& (i, h)\\ -c_3&=& (b-i, h)\\ -c_4&=& (b, 0) -\end{eqnarray*} - -The quantity $b$ is given, it is the width of the slur. The -conditions on the shape of the slur for small and large $b$ transform -to -\begin{eqnarray*} - h \to h_{\infty} , &&\quad b \to \infty\\ - h \approx r_{0} b, &&\quad b \to 0. -\end{eqnarray*} -To tackle this, we will assume that $h = F(b)$, for some kind of -$F(\cdot)$. One function that satisfies the above conditions is -$$ -F(b) = h_{\infty} \frac{2}{\pi} \arctan \left( \frac{\pi r_0}{2 -h_{\infty}} b \right). -$$ - -For satisfying results we choose $h_{\infty} = 2\cdot \texttt{interline}$ -and $r_0 = \frac 13$. - -\subsection{Height correction} - -Aside from being a smooth curve, slurs should avoid crossing -enclosed notes and their stems. - -An easy way to achieve this is to extend the slur's height, -so that the slur will curve just above any disturbing notes. - -The parameter $i$ determines the flatness of the curve. Satisfying -results have been obtained with $i = h$. - -The formula can be generalised to allow for corrections in the shape, -\begin{eqnarray*} -c_1&=& (0,0)\\ -c_2&=& (i', h')\\ -c_3&=& (b-i', h')\\ -c_4&=& (b, 0) -\end{eqnarray*} -Where -$$ -i' = h(b) (1 + i_{corr}), \quad h' = h(b) (1 + h_{corr}). -$$ - -The default values for these corrections are $0$. A $h_{corr}$ that is -negative, makes the curve flatter in the center. A $h_{corr}$ that is -positive make the curve higher. - -At every encompassed note's x position the difference $\delta _y$ -between the slur's height and the note is calculated. The greatest -$\delta _y$ is used to calculate $h_{corr}$ is by lineair extrapolation. - -However, this simple method produces satisfactory results only for -small and symmetric disturbances. - - -\subsection{Tangent method correction} - -A somewhat more elaborate\footnote{While staying in the realm -of empiric computer science} way of having a slur avoid -disturbing notes is by first defining the slur's ideal shape -and then using the height correction. The ideal shape of a -slur can be guessed by calculating the tangents of the disturbing -notes: -% a picture wouldn't hurt... -\begin{eqnarray*} - y_{disturb,l} &=& \rm{rc}_l x\\ - y_{disturb,r} &=& \rm{rc}_r + c_{3,x}, -\end{eqnarray*} -where -\begin{eqnarray*} - \rm{rc}_l &=& \frac{y_{disturb,l} - y_{encompass,1}} - {x_{disturb,l} - x_{encompass,1}}\dot x\\ - \rm{rc}_r &=& \frac{y_{encompass,n} - y_{disturb,r}} - {x_{encompass,n} - x_{disturb,r}} \dot x + c_{3,x}. -\end{eqnarray*} - -We assume that having the control points $c_2$ and $c_3$ located -on tangent$_1$ and tangent$_2$ resp. -% t: tangent -\begin{eqnarray*} - y_{tangent,l} &=& \alpha \rm{rc}_l x\\ - y_{tangent,r} &=& \alpha \rm{rc}_r + c_{3,x}. -\end{eqnarray*} - -Beautiful slurs have rather strong curvature at the extreme -control points. That's why we'll have $\alpha > 1$. -Satisfactory resulsts have been obtained with -$$ - \alpha \approx 2.4. -$$ - -The positions of control points $c_2$ and $c_3$ are obtained -by solving with the height-line -\begin{eqnarray*} - y_h &=& \rm{rc}_h + c_h. -\end{eqnarray*} - -The top-line runs through the points disturb$_{left}$ and -disturb$_{right}$. In the case that -$$ -z_{disturb,l} = z_{disturb,r}, -$$ -we'll have -$$ - \angle(y_{tangent,l},y_h) = \angle(y_{tangent,r},y_h). -$$ - - - -\section{Sizes} - -Traditional engraving uses a set of 9 standardised sizes for Staffs -(running from 0 to 8). - -We have tried to measure these (helped by a magnifying glass), and -found the staffsizes in table~\ref{fonts:staff-size}. One should note that -these are estimates, so I think there could be a measuring error of ~ -.5 pt. Moreover [Ross] states that not all engravers use exactly -those sizes. - -\begin{table}[h] - \begin{center} - \begin{tabular}{lll} -Staffsize &Numbers &Name\\ -\hline\\ -26.2pt &No. 0\\ -22.6pt &No. 1 &Giant/English\\ -21.3pt &No. 2 &Giant/English\\ -19.9pt &No. 3 &Regular, Ordinary, Common\\ -19.1pt &No. 4 &Peter\\ -17.1pt &No. 5 &Large middle\\ -15.9pt &No. 6 &Small middle\\ -13.7pt &No. 7 &Cadenza\\ -11.1pt &No. 8 &Pearl\\ - \end{tabular} - \caption{Foo} - \label{fonts:staff-size} - \end{center} -\end{table} - - - - -\section{Beams} - -\subsection{Slope} - -Traditionally, beam slopes are computed by following a large and hairy -set of rules. Some of these are talked-about in Wanske, a more -recipy-like description can be found in Ross. - -There are some problems when trying to follow these rules: -\begin{itemize} - -\item the set is not complete - -\item they are not formulated as a general rule with exceptions, but -rather as a huge case of individual rules\cite{ross} - -\item in some cases, the result is wrong or ugly (or both) - -\item they try to solve a couple of problems at a time (e.g. Ross -handles ideal slope and slope-quantisation as a paired problem) -\end{itemize} -Reading Ross it is clear that the rules presented there are certainly -not the ultimate idea of what beam(slope)s should look like, but -rather a (very much) simplified hands-on recipy for a human engraver. - -There are good reasons not to follow those rules: - -\begin{itemize} -\item One cannot expect a human engraver to solve least-squares -problems for every beam - -\item A human engravers will allways trust themselves in judging the -outcome of the applied recipy. If, in a complicated case, the result -"doesn't look good", they will ignore the rules and draw their own -beams, based on experience. - -\item The exact rules probably don't "really exist" but in the minds - of good engravers, in the form of experience -\end{itemize} - -We'll propose to do a least-squares solve. This seems to be the best -way to calculate the slope for a computerised engraver such as Lily. - -It would be nice to have some rules to catch and handle "ugly" cases, -though. In general, the slope of the beam should mirror the pitches -of the notes. If this can't be done because there simply is no -uniform trend, it would probably be best to set the slope to zero. - - -\subsection{Quantising} - -The beams should be prevented to conflict with the stafflines, -especially at small slopes. Traditionally, poor printing techniques -imposed rather strict rules for quantisation. In modern (post 1955) -music printing we see that quality has improved substantially and -obsoleted the technical justification for following some of these -strict rules, notably the avoiding of so-called wedges. - - -\subsection{Thickness and spacing} - -The spacing of double and triple beams (sixteenth and thirtysecond beams) -is the same, quadruple and quintuple (thirtyfourth and hundredtwentyeighth -beams) is wider. -All beams are equally thick. Using the layout of triple beams and the -beam-thickness $bt$ we can calculate the inter-beam spacing $ib$. - -Three beams span two interlines, including stafflines: -\begin{eqnarray*} - 2 ib + bt &=& 2 il\\ - ib &=& (2 il - bt) / 2 -\end{eqnarray*} - -We choose -\begin{eqnarray*} - bt &=& 0.48(il - st) -\end{eqnarray*} - -\subsubsection{Quadruple beams} - -If we have more than three beams they must open-up -in order to not collide with staff lines. The only valid -position that remains is for the upper beam to hang. - -\begin{eqnarray*} - 3 ib_{4+} + bt &=& 3 il\\ - ib_{4+} &=& (3 il - bt) / 3 -\end{eqnarray*} - - -\section{Layout of the source files} - -The main font (with the fixed size music glyphs) uses a the \TeX\ -logfile as a communication device. Use the specialised macros to -create and export glyphs. - -\bibliographystyle{plain} -\bibliography{engraving} - - - -\end{document} - -\begin{verbatim} -Paul Terry writes: - -Ross states that the dies (the stamps to make the symbols) come in -12 different sizes. - ->Can you tell me how big rastrals are? - -According to the Score manual: - - Rastral Size Height in millimetres - - 0 9 mm - 1 8 mm - 2 7.5 mm - 3 7 mm - 4 6.5 mm - 5 6 mm - 6 5.5 mm - -I must say, despite having been a music setter for many years, I had to -look these up - none of the publishers I work for deal in Rastral sizes -these days (they all use millimetres). diff --git a/Documentation/metadoc/hacking.texi b/Documentation/metadoc/hacking.texi deleted file mode 100644 index 42bcbee28e..0000000000 --- a/Documentation/metadoc/hacking.texi +++ /dev/null @@ -1,829 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@setfilename internals.info -@settitle LilyPond internals - -@node Top, LilyPond internals, (dir), (dir) -@top - - -@menu -* LilyPond internals:: -* Overview:: -* mudela:: -* Request_engraver:: -* Graphic elements:: -* Score elements:: -* Items:: -* Spanners:: -* Future work:: -* Coding standards:: -* Making patches:: - -@end menu - -@node LilyPond internals, , Top, Top -@menu -* Overview:: Overview -* mudela:: mudela -* Request_engraver:: Request_engraver -@end menu - - -@chapter Help Needed! - -[Call for help] - -[List tasks: - -* Mutopia - -* Doco LilyPond - -* Straightforward extensions - -* GUI editors. - -] - -@chapter LilyPond internals - - -This documents some aspects of the internals of GNU LilyPond. Some of -this stuff comes from e-mail I wrote, some from e-mail others wrote, -some are large comments taken away from the headers. This page may be -a little incoherent. Unfortunately, it is also quite outdated. A -more thorough and understandable document is in the works. - -You should use @code{doc++} to take a peek at the sources. - -@node Overview, mudela, Top, Top -@section Overview - -GNU LilyPond is a "multi-pass" system. The different passes have been -created so that they do not depend on each other. In a later stage -some parts may be moved into libraries, or seperate programs, or they -might be integrated in larger systems. - -@table @samp - -@item Parsing: - -No difficult algorithms. The .ly file is read, and converted to a list -of @code{Scores}, which each contain @code{Music} and paper/midi-definitions. - -@item Interpreting music - -The music is walked through in time-order. The iterators which do the -walking report Music to Translators which use this information to -create elements, either MIDI or "visual" elements. The translators -form a hierarchy; the ones for paper output are Engravers, for MIDI -Performers. - -The translators swallow Music (mostly atomic gobs called Requests), -create elements, broadcast them to other translators on higher or same -level in the hierarchy: - -The stem of a voice A is broadcast to the staff which contains A, but -not to the stems, beams and noteheads of a different voice (say B) or -a different staff. The stem and noteheads of A are coupled, because -the the Note_heads_engraver broadcasts its heads, and the Stem_engraver catches -these. - -The engraver which agrees to handle a request decides whether to to -honor the request, ignore it, or merge it with other requests. Merging -of requests is preferably done with other requests done by members of -the same voicegroups (beams, brackets, stems). In this way you can put -the voices of 2 instruments in a conductor's score so they make chords -(the Beam requests of both instruments will be merged). - -@item Prebreaking - -Breakable stuff (eg. clefs and bars) are copied into pre and -postbreaks. - -@item Preprocessing - -Some dependencies are resolved, such as the direction of stems, beams, -and "horizontal" placement issues (the order of clefs, keys etc, -placement of chords in multi-voice music), - -@item Break calculation: - -The lines and horizontal positions of the columns are determined. - -@item Breaking - -Through some magical interactions with Line_of_score and Super_elem -(check out the source) the "lines" are produced. - -All other spanners can figure across which lines they are spread. If -applicable, they break themselves into pieces. After this, each piece -(or, if there are no pieces, the original spanner itself) throws out -any dependencies which are in the wrong line. - -@item Postprocesing: - -Some items and all spanners need computation after the Paper_column -positions are determined. Examples: slurs, vertical positions of -staffs. - -@item Output paper - -@end table - -@node mudela, Request_engraver, Overview, Top -@section mudela - -Most information is stored in the form of a request. In music -typesetting, the user might want to cram a lot more symbols on the -paper than actually fits. To reflect this idea (the user asks more -than we can do), the container for this data is called Request. - -In a lot of other formats this would be called an 'Event' - -@table @samp -@item @code{Barcheck_req} - Checks during music processing if start of this voice element - coincides with the start of a measure. Handy to check if you left out - some voice elts. -@item @code{Note_req} - LilyPond has to decide if the ball should be hanging left or - right. This influences the horizontal dimensions of a column, and this - is why request processing should be done before horizontal spacing. - Other voices' frivolities may cause the need for accidentals, so this - is also for the to decide. The engraver can decide on positioning based on - ottava commands and the appropriate clef. -@item @code{Rest_req} - Typeset a rest. -@item @code{Span_req} - This type of request typically results in the creation of a @code{Spanner} -@item @code{Beam_req} - Start/stop a beam. - Engraver has to combine this request with the stem_request, since the - number of flags that a stem wants to carry will determine the - number of beams. -@item @code{Dynamic} - Each dynamic is bound to one note (a crescendo spanning multiple - notes is thought to be made of two "dynamics": a start and a stop). - Dynamic changes can occur in a smaller time than the length of its - note, therefore fore each @code{Dynamic} request carries a time, measured - from the start of its note. -@end table - -@node Request_engraver, , mudela, Top -@section Request_engraver - -In the previous section the idea of Request has been explained, but -this only solves one half of the problem. The other half is deciding -which requests should be honored, which should merged with other -requests, and which should be ignored. Consider this input - -@example - - \type Staff < % chord - @{ \meter 2/4; [c8 c8] @} - @{\meter 2/4; [e8 e8] @} - > - -@end example - -Both the cs and es are part of a staff (they are in the same -Voice_group), so they should share meters, but the two [ ] pairs -should be merged. - -The judge in this "allocation" problem a set of brokers: the requests -are transmitted to so-called engravers which respond if they want to -accept a request eg, the @code{Notehead_engraver} will accept -@code{Note_req}s, and turn down @code{Slur_req}s. If the Music_iterator -cannot find a engraver that wants the request, it is junked (with a -warning message). - -After all requests have been either assigned, or junked, the Engraver -will process the requests (which usually means creating an @code{Item} -or @code{Spanner}). If a @code{Request_engraver} creates something, it -tells the enclosing context. If all items/spanners have been created, -then each Engraver is notified of any created Score_element, via a -broadcasting system. - -@unnumberedsubsec example: - -@example - - c4 - -@end example - -produces: - -@example - - Note_request (duration 1/4) - Stem_request (duration 1/4) - -@end example - -Note_request will be taken by a @code{Notehead_engraver}, stem_request -will be taken by a @code{Stem_beam_engraver}. @code{Notehead_engraver} -creates a @code{Notehead}, @code{Stem_beam_engraver} creates a -@code{Stem}. Both announce this to the Staff_engraver. Staff_engraver -will tell @code{Stem_beam_engraver} about the @code{Notehead}, which -will add the @code{Notehead} to the @code{Stem} it just created. - -To decide on merging, several engravers have been grouped. Please -check @file{init/engraver.ly}. - - - -@node Graphic elements, , , Top -@section Graphic elements - - -Music notation is composed of a sets of interrelated glyphs. In -Lilypond every glyph usually is represented by one object, a so-called -Graphic Object. The primary relations between graphic objects involve -positions: - -@itemize -@item consecutive notes are printed left to right, grouped in a staff -@item simultaneous notes are horizontally aligned (internally grouped in -a paper column). -@item the staccato mark is horizontally centered on the note it applies -to. -@end itemize - -The abstract encoding of such relations is done with the concept -@dfn{reference point}. The reference point (in X direction) of the -staccato mark is the note it applies to. The (X) position of the -staccato mark is stored relative to the position of the note head. This -means that the staccato will always maintain a fixed offset wrt to the -note head, whereever the head is moved to. - -In the same vein, all notes on a staff have their Y positions stored -relative to an abstract object called Axis_group_spanner. If the -Axis_group_spanner of one staff is moved, the absolute Y positions of -all objects in that spanner change along, in effect causing the staff -and all its contents to move as a whole. - -Each graphic object stores a pointer and an relative offset for each -direction: one for the X-axis, one for the Y-axis. For example, the X -parent of a Note_head usually is a Note_column. The X parent of a -Note_column usually is either a Collision or a Paper_column. The X -parent of a Collision usually is a Paper_column. If the Collision -moves, all Note_heads that have that Collision as parent also move, but -the absolute position of the Paper_column does not change. - -To build a graphical score with Graphic_elements, conceptually, one -needs to have one Root object (in Lilypond: Line_of_score), and -recursively attach objects to the Root. However, due to the nature -of the context selection mechanisms, it turns out to be more -advantageous to construct the tree the other way around: first small -trees (note heads, barlines etc.) are created, and these are -subsequently composed into larger trees, which are finally hung on a -Paper_column (in X direction) or Line_of_score (in Y direction). - -The structure of the X,Y parent relations are determined by the -engravers and notation contexts: - -The most important X-axis parent relation depends on the timing: notes -that come earlier are attached to Paper_column that will be positioned -more to the left. - -The most important Y-axis relation depends on containment of contexts: -notes (created in a Thread or Voice context) are put in the staff where -the originating context lives in. - -Graphical_axis_groups are special graphic objects, that are designed to -function as a parent. The size of a Graphical_axis_groups group is the -union of its children. - -@node Score elements, , , Top - -Besides relative positions there are lots of other relations between -elements. Lilypond does not contain other specialized relation -management (Like the relative positioning code). In stead, objects can -be connected through dependencies, which sets the order in which objects -are to be processed. - -Example: the direction of a beamed stem should equal the direction of -the beam. When the stem is a added to the beam, a dependency on the -beam is set in the stem: this means that @code{Beam::do_pre_processing -()} (which does various direction related things) will be called before -@code{Stem::do_pre_processing ()}. - -The code that manages dependencies resides in the class -@code{Score_element}, a derived class of @code{Graphical_element}. The -bulk of the code handles line breaking related issues. - -To sketch the problems with line breaking: suppose a slur spans a line -break, -@example - -c4( c'''' c | \break d d )d - -@end example -In this case, the slur will appear as two parts, the first part spanning -the first three notes (the @code{c}s), the second spanning the last -three (the @code{d}s). Within Lilypond this is modeled as breaking the -slur in parts: from the Original slur, two new clones of the old slur -are made. Initially both clones depend on the six notes. After the -hairy code in Score_element, Spanner and Item which does substitutions -in sets of dependencies, the first clone depends on the first three -notes, the second on the last three. - -The major derived classes of Score_element are Item and Spanner. -An item has one horizontal position. A spanner hangs on two items. - -@node Items, , , Top -@section Items - - - -An item is a score element that is associated with only one -Paper_column. Examples are note heads, clefs, sup and superscripts, etc. -Item is a derived class of Score_element. - -The shape of an item is known before the break calculations, and line -spacing depends on the size of items: very wide items need more space -than very small ones. - -An additional complication is the behavior of items at linebreaks. For -example, when you do a time signature change, you get only one symbol. -If it occurs at a linebreak, the new time signature must be printed both -before and after the linebreak. Other `breakable symbols' such as -clefs, and bar lines also exhibit this behavior. - -if a line of music is broken, the next line usually gets a clef. So in -TeX terms, the clef is a postbreak. The same thing happens with meter -signs: Normally the meter follows the bar. If a line is broken at that -bar, the bar along with the meter stays on the "last" line, but the next -line also gets a meter sign after the clef. To support this, -breakable items are generated in the three versions: original -(unbroken), left (before line break) and right (after line break). -During the line spacing, these versions are used to try how the spacing -of a line works out. - -Once the definitive spacing is determined, dependencies (and various -other pointers) are substituted such that all dependencies point at the -active items: either they point at the original, or they point at left -and right. - -@node Spanners, , , Top -@section Spanners - -Spanners are symbols that are of variable shape, eg. Slurs, beams, etc. -Spanners is a derived class of Score_element. - -The final shape can only be determined after the line breaking process. -All spanners are spanned on two items, called the left and right -boundary item. The X reference point is the left boundary item. - - -@node Future work, , , Top -@section Future work - -There are plans to unify Spanner and Item, so there will no longer be -such a clear distinction between the two. Right now, Score_elements are -always either Item or either Spanner. - -Most of the properties of a graphic object are now member variables of -the classes involved. To offer configurability, we want to move these -variables to scheme (GUILE) variables, and no longer use C++ code to -calculate them, but use Scheme functions. - -@node Coding standards, , , Top - -@chapter CodingStyle - standards while programming for GNU -LilyPond - -Functions and methods do not return errorcodes. - - -@unnumberedsubsec Languages - -C++ and Python are preferred. Perl is not. Python code should use an -indent of 8, using TAB characters. - -@unnumberedsubsec Filenames - -Definitions of classes that are only accessed via pointers -(*) or references (&) shall not be included as include files. - -filenames - -@example - ".hh" Include files - ".cc" Implementation files - ".icc" Inline definition files - ".tcc" non inline Template defs -@end example - -in emacs: - -@example - (setq auto-mode-alist - (append '(("\\.make$" . makefile-mode) - ("\\.cc$" . c++-mode) - ("\\.icc$" . c++-mode) - ("\\.tcc$" . c++-mode) - ("\\.hh$" . c++-mode) - ("\\.pod$" . text-mode) - ) - auto-mode-alist)) -@end example - - -The class Class_name_abbreviation is coded in @file{class-name-abbr.*} - -@unnumberedsubsec Indentation - -Standard GNU coding style is used. In emacs: - -@example - (add-hook 'c++-mode-hook - '(lambda() (c-set-style "gnu") - ) - ) -@end example - -If you like using font-lock, you can also add this to your @file{.emacs}: - -@example - (setq font-lock-maximum-decoration t) - (setq c++-font-lock-keywords-3 - (append - c++-font-lock-keywords-3 - '(("\\b\\([a-zA-Z_]+_\\)\\b" 1 font-lock-variable-name-face) - ("\\b\\([A-Z]+[a-z_]+\\)\\b" 1 font-lock-type-face)) - )) -@end example - -@unnumberedsubsec Classes and Types - -@example - This_is_a_class -@end example - -@unnumberedsubsec Members - -@example - Class::member () - Type Class::member_type_ - Type Class::member_type () -@end example - -the @code{type} is a Hungarian notation postfix for @code{Type}. See below - -@unnumberedsubsec Macros - -Macros should be written completely in uppercase - -The code should not be compilable if proper macro declarations are not -included. - -Don't laugh. It took us a whole evening/night to figure out one of -these bugs, because we had a macro that looked like -@code{DECLARE_VIRTUAL_FUNCTIONS ()}. - -@unnumberedsubsec Broken code - -Broken code (hardwired dependencies, hardwired constants, slow -algorithms and obvious limitations) should be marked as such: either -with a verbose TODO, or with a short "ugh" comment. - -@unnumberedsubsec Comments - -The source is commented in the DOC++ style. Check out doc++ at -@uref{http://www.zib.de/Visual/software/doc++/index.html} - -@example - - /* - C style comments for multiline comments. - They come before the thing to document. - [...] - */ - - /** - short description. - Long class documentation. - (Hungarian postfix) - - TODO Fix boring_member () - */ - class Class @{ - /** - short description. - long description - */ - - Data data_member_; - - /** - short memo. long doco of member () - @@param description of arguments - @@return Rettype - */ - Rettype member (Argtype); - - /// memo only - boring_member () @{ - data_member_ = 121; // ugh - @} - @}; - -@end example - - -Unfortunately most of the code isn't really documented that good. - -@unnumberedsubsec Members (2) - -Standard methods: - -@example - - ///check that *this satisfies its invariants, abort if not. - void OK () const - - /// print *this (and substructures) to debugging log - void print () const - - /** - protected member. Usually invoked by non-virtual XXXX () - */ - virtual do_XXXX () - - /**add some data to *this. - Presence of these methods usually imply that it is not feasible to this - via a constructor - */ - add (..) - - /// replace some data of *this - set (..) - -@end example - -@unnumberedsubsec Constructor - -Every class should have a default constructor. - -Don't use non-default constructors if this can be avoided: - -@example - - Foo f(1) - -@end example - -is less readable than - -@example - - Foo f; - f.x = 1 - -@end example - -or - -@example - - Foo f(Foo_convert::int_to_foo (1)) - -@end example - -@unnumberedsec Hungarian notation naming convention - -Proposed is a naming convention derived from the so-called -@emph{Hungarian Notation}. Macros, @code{enum}s and @code{const}s are all -uppercase, with the parts of the names separated by underscores. - -The hungarian notation is to be used when variables are not declared -near usage (mostly in member variables and functions). - -@unnumberedsubsec Types - -@table @samp -@item @code{byte} - unsigned char. (The postfix _by is ambiguous) -@item @code{b} - bool -@item @code{bi} - bit -@item @code{ch} - char -@item @code{f} - float -@item @code{i} - signed integer -@item @code{str} - string class -@item @code{sz} - Zero terminated c string -@item @code{u} - unsigned integer -@end table - -@unnumberedsubsec User defined types - -@example - - /** Slur blah. blah. - (slur) - */ - class Slur @{@}; - Slur* slur_p = new Slur; - -@end example - -@unnumberedsubsec Modifiers - -The following types modify the meaning of the prefix. -These are preceded by the prefixes: - -@table @samp -@item @code{a} - array -@item @code{array} - user built array. -@item @code{c} - const. Note that the proper order is @code{Type const} - i.s.o. @code{const Type} -@item @code{C} - A const pointer. This would be equivalent to @code{_c_l}, but since any - "const" pointer has to be a link (you can't delete a const pointer), - it is superfluous. -@item @code{l} - temporary pointer to object (link) -@item @code{p} - pointer to newed object -@item @code{r} - reference -@end table - -@unnumberedsubsec Adjective - -Adjectives such as global and static should be spelled out in full. -They come before the noun that they refer to, just as in normal english. - -@example - -foo_global_i: a global variable of type int commonly called "foo". - -@end example - -static class members do not need the static_ prefix in the name (the -Class::var notation usually makes it clear that it is static) - -@table @samp -@item @code{loop_i} - Variable loop: an integer -@item @code{u} - Temporary variable: an unsigned integer -@item @code{test_ch} - Variable test: a character -@item @code{first_name_str} - Variable first_name: a String class object -@item @code{last_name_ch_a} - Variable last_name: a @code{char} array -@item @code{foo_i_p} - Variable foo: an @code{Int*} that you must delete -@item @code{bar_i_l} - Variable bar: an @code{Int*} that you must not delete -@end table - -Generally default arguments are taboo, except for nil pointers. - -The naming convention can be quite conveniently memorised, by -expressing the type in english, and abbreviating it - -@example - - static Array foo - -@end example - -@code{foo} can be described as "the static int-pointer user-array", so you get - -@example - - foo_static_l_arr - -@end example - - -@unnumberedsec Miscellaneous - -For some tasks, some scripts are supplied, notably creating patches, a -mirror of the website, generating the header to put over cc and hh -files, doing a release. - -Use them. - -@node Making patches, , , Top - - -@unnumberedsec name - - -PATCHES - track and distribute your code changes - -This page documents how to distribute your changes to GNU lilypond - -We would like to have unified context diffs with full pathnames. A -script automating supplied with Lily. - -Distributing a change normally goes like this: - -@itemize @bullet -@item make your fix/add your code -@item Add changes to CHANGES, and add yourself to Documentation/topdocs/AUTHORS.texi -@item generate a patch, -@item e-mail your patch to one of the mailing lists - gnu-music-discuss@@gnu.org or bug-gnu-music@@gnu.org -@end itemize - -Please do not send entire files, even if the patch is bigger than the -original. A patch makes it clear what is changed, and it won't -overwrite previous (not yet released) changes. - -@unnumberedsec Generating a patch - -Simple version: run - -@example - make -C lilypond-x.y.z/ distclean - make -C lilypond-x.y.z.NEW/ distclean - diff -urN lilypond-x.y.z/ lilypond-x.y.z.NEW/ -@end example - -Complicated (but automated) version: - -In @file{VERSION}, set MY_PATCH_LEVEL: - -@example - - VERSION: - ... - MY_PATCH_LEVEL=jcn1 - -@end example - -In @file{CHANGES}, enter a summary of changes: - -@example - pl 0.1.73.jcn1 - - added PATCHES.texi -@end example - -Then, from the top of Lily's source tree, type - -@example - make release -@end example - -These handy python scripts assume a directory structure which looks -like: - -@example - - lilypond -> lilypond-x.y.z # symlink to development directory - lilypond-x.y.z/ # current development - patches/ # patches between different releases - releases/ # .tar.gz releases - -@end example - -(Some scripts also assume this lives in @file{$HOME/usr/src}). - - -@unnumberedsec Applying patches - - -If you're following LilyPond development regularly, you probably want to -download just the patch for each subsequent release. -After downloading the patch (into the patches directory, of course), simply -apply it: - -@example - - gzip -dc ../patches/lilypond-0.1.74.diff.gz | patch -p1 -E - -@end example - -and don't forget to make automatically generated files: - -@example - - autoconf footnote(patches don't include automatically generated files, - i.e. file(configure) and files generated by file(configure).) - - configure - -@end example - - -@bye - - diff --git a/Documentation/metadoc/lilypond-overview.doc b/Documentation/metadoc/lilypond-overview.doc deleted file mode 100644 index a408a9e8eb..0000000000 --- a/Documentation/metadoc/lilypond-overview.doc +++ /dev/null @@ -1,743 +0,0 @@ -%-*-LaTeX-*- - -\documentclass{article} -\usepackage{a4} -\def\postMudelaExample{\setlength{\parindent}{1em}} -\title{LilyPond, a Music Typesetter} -\author{HWN} -\usepackage{musicnotes} -\usepackage{graphics} - - -\begin{document} -\maketitle - -[THIS IS WORK IN PROGRESS. THIS IS NOT FINISHED] - -% -*-LaTeX-*- -\section{Introduction} - -The Internet has become a popular medium for collaborative work on -information. Its success is partly due to its use of simple, text-based -formats. Examples of these formats are HTML and \LaTeX. Anyone can -produce or modify such files using nothing but a text editor, they are -easily processed with run-of-the-mill text tools, and they can be -integrated into other text-based formats. - -Software for processing this information and presenting these formats -in an elegant form is available freely (Netscape, \LaTeX, etc.). -Ubiquitousness of the software and simplicity of the formats have -revolutionised the way people publish text-based information -nowadays. - -In the field of performed music, where the presentation takes the form -of sheet music, such a revolution has not started yet. Let us review -some alternatives that have been available for transmitting sheet -music until now: -\begin{itemize} -\item MIDI\cite{midi}. This format was designed for interchanging performances - of music; one should think of it as a glorified tape recorder - format. It needs dedicated editors, since it is binary. It does - not provide enough information for producing musical scores: some of - the abstract musical content of what is performed is thrown away. - -\item PostScript\cite{Postscript}. This format is a printer control - language. Printed musical scores can be transmitted in PostScript, - but once a score is converted to PostScript, it is virtually - impossible to modify the score in a meaningful way. - -\item Formats for various notation programs. Notation programs either - work with binary formats (e.g., NIFF\cite{niff-web}), need specific - platforms (e.g., Sibelius\cite{sibelius}), are proprietary or - non-portable tools themselves (idem), produce inadequate output - (e.g., MUP\cite{mup}), are based on graphical content (e.g., - MusixTeX\cite{musixtex1}), limit themselves to specific subdomains - (e.g., ABC\cite{abc2mtex}), or require considerable skill and - knowledge to use (e.g., SCORE\cite{score}) - -\item SMDL\cite{smdl-web}. This is a very rich ASCII format, that is - designed for storing many types of music. Unfortunately, there is - no implementation of a program to print music from SMDL available. - Moreover, SMDL is so verbose, that it is not suitable for human - production. - -\item TAB\cite{tablature-web}. Tab (short for tablature) is a popular - format, for interchanging music over e-mail, but it can only be used - for guitar music. -\end{itemize} - -In summary, sheet music is not published and edited on a wide scale -across the internet because no format for music -interchange exists that is: -\begin{itemize} -\item open, i.e., with publically available specifications. -\item based on ASCII, and therefore suitable for human consumption and - production. -\item rich enough for producing publication quality sheet music from - it. -\item based on musical content (unlike, for example, PostScript), and - therefore suitable for making modifications. -\item accompanied by tools for processing it that are freely available - across multiple platforms. -\end{itemize} - - -With the creation of LilyPond, we have tried to create both a -convenient format for storing sheet music, and a portable, -high-quality implementation of a compiler, that compiles the input -into a printable score. You can find a small example of LilyPond -input along with output in Figure~\ref{fig:intro-fig}. -% -\begin{figure}[htbp] - \begin{center} -\begin[verbatim]{mudela} - \score { - \notes - \context GrandStaff < - \transpose c'' { c4 c4 g4 g4 a4 a4 g2 } - { \clef "bass"; c4 c'4 - \context Staff f'4 c'4 e'4 c'4 } - > - \paper { - linewidth = -1.0\cm ; - } - } -\end{mudela} - \caption{A small example of LilyPond input} - \label{fig:intro-fig} - \end{center} -\end{figure} -% - - -The input language encodes musical events (such as notes and rests) on -the basis of their time-ordering. For example, the grammar includes -constructs that specify that notes start simultaneous and that notes -are to be played in sequence. In this encoding some context that is -present in sheet music is lost. - -The compiler reconstructs the notation from the encoded music. Its -operation comprises four different steps (see -Figure~\ref{fig:intro-steps}). - -\begin{description} -\item[Parsing] During parsing, the input is converted in a syntax tree. - -\item[Interpreting] In the \emph{interpreting} step, it is determined - which symbols have to be printed. Objects that correspond to - notation (\emph{Graphical objects}) are created from the syntax tree - in this phase. Generally speaking, for every symbol printed there is - one graphical object. These objects are incomplete: their position - and their final shape is unknown. - - The context that was lost by encoding the input in a language is - reconstructed during this conversion. -\item[Formatting] The next step is determing where symbols are to be - placed, this is called \emph{formatting}. -\item[Outputting] - Finally, all Graphical objects are outputted as PostScript or \TeX\ code. -\end{description} - -\def\staffsym{\vbox to 16pt{ - \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip - \vfil - \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip - \vfil - \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip - \vfil - \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip - \vfil - \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip -}} - -\def\vspacer{\vbox to 20pt{\vss}} -\begin{figure}[h] -\def\spacedhbox#1{\hbox{\ #1\ }} -\begin{eqnarray*} - {\spacedhbox{Input}\atop \hbox{\texttt{\{c8 c8\}}}} {\spacedhbox{Parsing}\atop\longrightarrow} - {\spacedhbox{Syntax tree}\atop\spacedhbox{\textsf{Sequential(Note,Note)}}} - {\spacedhbox{Interpreting}\atop\longrightarrow}\\ - \vspacer\\ - {\spacedhbox{Graphic objects}\atop\spacedhbox{\texttrebleclef \textquarterhead\texteighthflag\textquarterhead\texteighthflag \staffsym }} - {\spacedhbox{Formatting}\atop\longrightarrow} - {\spacedhbox{Formatted objects}\atop\hbox{ - \mudela{c''8 c''8} - }}\\ -\vspacer\\ - {\spacedhbox{Outputting}\atop\longrightarrow} - {\spacedhbox{PostScript code}\atop\hbox{\texttt{\%!PS-Adobe}\ldots}} -\end{eqnarray*} - \caption{Parsing, Interpreting, Formatting and Outputting} - \label{fig:intro-steps} -\end{figure} - - -The second step, the interpretation phase of the compiler, can be -manipulated as a separate entity: the interpretation process is -composed of many separate modules, and the behaviour of the modules is -parameterised. By recombining these interpretation modules, -and changing parameter settings, the same piece of music can be -printed differently, as is shown in Figure~\ref{fig:intro-interpret}. - -This makes it easy to extend the program. Moreover, this enables the -same music to be printed in different versions, e.g., in a conductors -score and in extracted parts. - - -\begin{figure}[h] - \begin{center} - \begin{mudela} - \score { - \notes - \context GrandStaff < - \transpose c'' { c4 c4 g4 g4 a4 a4 g2 } - { \clef "bass"; c4 c'4 - \context Staff f'4 c'4 e'4 c'4 } - > - \paper { - linewidth = -1.0\cm ; - \translator { - \VoiceContext - \remove "Stem_engraver"; - } - \translator { - \StaffContext - numberOfStaffLines = 3; - } - } - } - \end{mudela} - \caption{The interpretation phase can be manipulated: the same - music as in Figure~\ref{fig:intro-fig} is interpreted - differently: three staff lines and no stems.} - \label{fig:intro-interpret} - \end{center} -\end{figure} - - - -\section{Preliminaries} - -To understand the rest of the article, it is necessary to know -something about music notation and music typography. Since both -communicate music, we will explain some characteristics of instruments -and western music that motivate some notational constructs. - -\subsection{Music} - -Music notation is meant to be read by human performers. They sing or -play instruments that can produce sounds of different pitches. These -sounds are called \emph{notes}. Additionally, the sounds can be -articulated in differents ways, e.g., staccato (short and separated) -or legato (fluently bound together). The loudness of the notes can -also be varied. Changes in loudness are called \emph{dynamics}. - -Silence is also an element of music. The musical terminology for -silence within music is \emph{rest}. - -The basic unit of pitch is the \emph{octave}. The octave corresponds -to a frequency ratio of 1:2. For example the pitch denoted by a' -(frequency: 440 hertz) is one octave lower than a'' (frequency: 880 -hertz). Various instruments have a limited \emph{pitch range}, for -example, a trumpet has a range of about 2.5 octaves. Not all -instruments have ranges in the same register: a tuba also has a range -of 2.5 octaves, but the range of the tuba is much lower. - -Musicology has a confusing mix of relative and absolute measures for -pitches: the term `octave' refers to both a difference between two -pitches (the frequency ratio of 1:2), and to a range of pitches. For -example, the term `[eengestreept] octave' refers to the pitch range -between 261.6 Hz and 523.3 Hz. - - -The octave is divided into smaller pitch steps. In modern western -music, every octave is divided into twelve approximately equidistant -pitch steps, and each step is called a \emph{semitone}. Usually, the -pitches in a musical piece come from a smaller subset of these twelve -possible pitches. This smaller subset along with the musical -functions fo the pitches is called the -\emph{tonality}\footnote{Tonality also refers to the relations between - and functions of certain pitches. Since these do not have any - impact on notation, we ignore this} of the piece. - - -The standard tonality that forms the basis of music notation -(the key of C major) is a set of seven pitches within every octave. -Each of these seven is denoted by a name. In English, these are names -are (in rising pitch) denoted by c, d, e, f, g, a and b. Pitches that -are a semitone higher or lower than one of these seven can be -represented by suffixing the name with `sharp' or `flat' -respectively (this is called an \emph{chromatic alteration}). - -A pitch therefore can be fully specified by a combination of the -octave number, the note name and a chromatic alteration. -Figure~\ref{fig:intro-pitches} shows the relation between names and -frequencies. - - - - -\begin{figure}[h] - \begin{center} - [te doen] - \end{center} - \caption{Pitches in western music. The octave number is denoted - by a superscript.} - \label{fig:intro-pitches} -\end{figure} - - -Many instruments can produce more than one note at the same time, e.g. -pianos and guitars. When more notes are played simultaneously, they -form a so-called \emph{chord}. - -The unit of duration is the \emph{beat}. When playing, the tempo is -determined by setting the number of beats per minute. In western -music, beats are often stressed in a regular pattern: for example -Waltzes have a stress pattern that is strong-weak-weak, i.e. every -note that starts on a `strong' beat is louder and has more pronounced -articulation. This stress pattern is called \emph{meter}. - -\subsection{Music notation} - -Music notation is a system that tries to represent musical ideas -through printed symbols. Music notation has no precise definition, -but most conventions have described in reference manuals on music -notation\cite{read-notation}. - -In music notation, sounds and silences are represented by symbols that -are called note and rest respectively.\footnote{These names serve a - double purpose: the same terms are used to denote the musical - concepts.} The shape of notes and rests indicates their duration -(See figure~\ref{noteshapes}) relative to the whole note. - - -\begin{figure}[h] - \begin{center} -\begin{mudela} - \score { - \notes \transpose c''{ c\longa*1/4 c\breve*1/2 c1 c2 c4 c8 c16 c32 c64 } - \paper { - \translator { - \StaffContext - \remove "Staff_symbol_engraver"; - \remove "Time_signature_engraver"; -% \remove "Bar_engraver"; - \remove "Clef_engraver"; - } -linewidth = -1.; - } -} -\end{mudela} -\begin{mudela} - \score { - \notes \transpose c''\context Staff { r\longa*1/4 r\breve*1/2 r1 r2 r4 r8 r16 r32 r64 } - \paper { - \translator { - \StaffContext - \remove "Staff_symbol_engraver"; - \remove "Time_signature_engraver"; -% \remove "Bar_engraver"; - \remove "Clef_engraver"; - } - linewidth = -1.; - } -} -\end{mudela} - \caption{Note and rest shapes encode the length. At the top notes - are shown, at the bottom rests. From left to right a quadruple - note (\emph{longa}), double (\emph{breve}), whole, half, - quarter, eigth, sixteenth, thirtysecond and sixtyfourth. Each - note has half of the duration of its predecessor.} - \label{fig:noteshapes} -\end{center} -\end{figure} - - -Notes are printed in a grid of horizontal lines called \emph{staff} to -denote their pitch: each line represents the pitch of from the -standard scale (c, d, e, f, g, a, b). The reference point is the -\emph{clef}, eg., the treble clef marks the location of the $g^1$ -pitch. The notes are printed in their time order, from left to right. - - -\begin{figure}[h] - \begin{center} - \begin{mudela} - \score { \notes { - a4 b c d e f g a \clef bass; - a4 b c d e f g a \clef alto; - a4 b c d e f g a \clef treble; - } - \paper { linewidth = 15.\cm; } - } - \end{mudela} - \caption{Pitches ranging from $a, b, c',\ldots a'$, in different - clefs. From left right the bass, alto and treble clef are - featured.} - \label{fig:pitches} - \end{center} -\end{figure} - -The chromatic alterations are indicated by printing a flat sign or a -sharp sign in front of the note head. If these chromatic alterations -occur systematically (if they are part of the tonality of the piece), -then this indicated with a \emph{key signature}. This is a list of -sharp/flat signs which is printed next to the clef. - -Articulation is notated by marking the note shapes wedges, hats and -dots all indicate specific articulations. If the notes are to be -bound fluently (legato), the note shapes are encompassed by a smooth -curve called \emph{slur}, - -\begin{figure}[h] - \begin{center} - \begin{mudela} - c'4-> c'4-. g'4 ( b'4 ) g''4 - \end{mudela} - \caption{Some articulations. From left to right: extra stress - (\emph{marcato}), short (staccato), slurred notes (legato).} - \label{fig:articulation} - \end{center} -\end{figure} - - - -Dynamics are notated in two ways: absolute dynamics are indicated by -letters: \textbf{f} (from Italian ``forte'') stands for loud, -\textbf{p} (from Italian ``piano'') means soft. Gradual changes in -loudness are notated by (de)crescendos. These are hairpin like shapes -below the staff. - -\begin{figure}[h] - \begin{center} - \begin{mudela} - g'4\pp \< g'4 \! g'4 \ff \> g'4 g' \! g'\ppp - \end{mudela} - \caption{Dynamics: start very soft (pp), grow to loud (ff) and - decrease to extremely soft (ppp)} - \label{fig:dynamics} - \end{center} -\end{figure} - - -The meter is indicated by barlines: every start of the stress pattern -is preceded by a vertical line, the \emph{bar line}. The space -between two bar lines is called measure. It is therefore the unit of -the rhythmic pattern. - -The time signature also indicates what kind of rhythmic pattern is -desired. The time signature takes the form of two numbers stacked -vertically. The top number is the number of beats in one measure, the -bottom number is the duration (relative to the whole note) of the note -that takes one beat. Example: 2/4 time signature means ``two beats -per measure, and a quarter note takes one beat'' - -Chords are written by attaching multiple note heads to one stem. When -the composer wants to emphasize the horizontal relationships between -notes, the simultaneous notes can be written as voices (where every -note head has its own stem). A small example is given in -Figure~\ref{fig:simultaneous}. - -\begin{figure}[h] - \begin{center} - \begin{mudela} - \relative c'' {\time 2/4; - \context Staff < \context Voice = VA{ - \stemdown - c4 d - b16 b b b b b b b } - \context Voice = VB { - \stemup e4 f g8 g4 g8 } > - } - \end{mudela} - \caption{Notes sounding together. Chord notation (left, before - the bar line) emphasizes vertical relations, voice notation - emphasizes horizontal relations. Separate voices needn't have - synchronous rhythms (third measure). - } - \label{fig:simultaneous} - \end{center} -\end{figure} - -Separate voices do not have to share one rhythmic pattern---this is -also demonstrated in Figure~\ref{fig:simultaneous}--- they are in a sense%vaag -independent. A different way to express this in notation, is by -printing each voice on a different staff. This is customary when -writing for piano (both left and right hand have a staff of their own) -and for ensemble (every instrument has a staff of its own). - - - -\subsection{Music typography} - -Music typography is the art of placing symbols in esthetically -pleasing configuration. Little is explicitly known about music -typography. There are only a few reference works -available\cite{ross,wanske}. Most of the knowledge of this art has -been transmitted verbally, and was subsequently lost. - -The motivation behind choices in typography is to represent the idea -as clearly as possible. Among others, this results in the following -guidelines: -\begin{itemize} -\item The printed score should use visual hints to accentuate the - musical content -\item The printed score should not contain distracting elements, such - as large empty regions or blotted regions. -\end{itemize} - -An example of the first guideline in action is the horizontal spacing. -The amount of space following a note should reflect the duration of -that note: short notes get a small amount of space, long notes larger -amounts. Such spacing constraints can be subtle, for the -``amount of space'' is only the impression that should be conveyed; there -has to be some correction for optical illusions. See -Figure~\ref{fig:spacing}. - -\begin{figure}[h] - \begin{center} - \begin{mudela} - \relative c'' { \time 3/4; c16 c c c c8 c8 | f4 f, f' } - \end{mudela} - \caption{Spacing conveys information about duration. Sixteenth - notes at the left get less space than quarter notes in the - middle. Spacing is ``visual'', there should be more space - after the first note of the last measure, and less after second. } - \label{fig:spacing} - \end{center} -\end{figure} - -Another example of music typography is clearly visible in collisions. -When chords or separate voices are printed, the notes that start at -the same time should be printed aligned (ie., with the same $x$ -position). If the pitches are close to each other, the note heads -would collide. To prevent this, some notes (or note heads) have to be -shifted horizontally. An example of this is given in -Figure~\ref{fig:collision}. -\begin{figure}[h] - \begin{center} - [todo] - \caption{Collisions} - \label{fig:collision} - \end{center} -\end{figure} - -\bibliographystyle{hw-plain} -\bibliography{engraving,boeken,colorado,computer-notation,other-packages} - -\section{Requirements} - - -\section{Approach} - -\subsection{Input} - -The input format consists of combining a symbolic representation of -music with style sheet that describes how the symbolic presentation -can converted to notation. The symbolic representation is based on a -context free language called \textsf{music}. Music is a recursively -defined construction in the input language. It can be constructed by -combining lists of \textsf{music} sequentially or parallel or from -terminals like notes or lyrics. - -The grammar for \textsf{music} is listed below. It has been edited to -leave out the syntactic and ergonomic details. - -\begin{center} - \begin{tabular}{ll} -Music: & SimpleMusic\\ - & $|$ REPEATED int Music ALTERNATIVE MusicList\\ - & $|$ SIMULTANEOUS MusicList\\ - & $|$ SEQUENTIAL MusicList\\ - & $|$ CONTEXT STRING '=' STRING Music\\ - & $|$ TIMES int int Music \\ - & $|$ TRANSPOSE PITCH Music \\ -SimpleMusic: & $|$ Note\\ - & $|$ Lyric\\ - & $|$ Rest\\ - & $|$ Chord\\ - & $|$ Command\\ -Command: & METERCHANGE\\ - & $|$ CLEFCHANGE\\ - &$|$ PROPERTY STRING '=' STRING\\ -Chord: &PitchList DURATION\\ -Rest: &REST DURATION\\ -Lyric: &STRING DURATION\\ -Note: &PITCH DURATION\\ -\end{tabular} -\end{center} - -The terminals are both purely musical concepts that have a duration, -and take a non-zero amount of musical time, like notes and lyrics, and -commands that behave as if they have no duration.\footnote{The - PROPERTY command is a generic mechanism for controlling the - interpretation, i.e. the musical style sheets. See [forward ref]} - -The nonterminal productions can -\begin{itemize} -\item Some productions combine multiple elements: one can specify that - element are to be played in sequence, simultaneously or repetitively. -\item There are productions for transposing music, and for dilating - durations of music: the TIMES production can be used to encode a - triplet.\footnote{A triplet is a group of three notes marked by a - bracket, that are played 3/2 times faster.} -\item - There are productions that give directions to the interpretation - engine (the CONTEXT production) -\end{itemize} - - -\section{Context in notation} - -Music notation relies heavily on context. Notational symbols do not -have meaning if they are not surrounded by other context elements. In -this section we give some examples how the reader uses this context do -derive meaning of a piece of notation. We will focus on the prime -example of context: the staff. - -A staff is the grid of five horizontal lines, but it contains more components : -\begin{itemize} -\item A staff can have a key signature (printed at the left) -\item A staff can have a time signature (printed at the left) -\item A staff has bar lines -\item A staff has a clef (printed at the left) -\end{itemize} - -It is still possible to print notes without these components, but one -cannot determine the meaning of the notes. -\begin{mudela} -\score{ -\notes \relative c' { \time 2/4; g'4 c,4 a'4 f4 e c d2 } -\paper { - linewidth = -1.; - \translator { - \StaffContext - \remove "Time_signature_engraver"; -% \remove "Bar_engraver"; - \remove "Staff_symbol_engraver"; - \remove "Clef_engraver"; - \remove "Key_engraver"; - } - } -} -\end{mudela} - -As you can see, you can still make out the general form of the melody -and the rhythm that is to be played, but the notation is difficult to -read and the musical information is not complete. The stress -pattern in the notes can't be deduced from this output. For this, we -need a time signature. Adding barlines helps with finding the strong -and weak beats. -\begin{mudela} -\score { - \notes \relative c' { \time 2/4; g'4 c,4 a'4 f4 e c d2 } - \paper{ - linewidth = -1.; -\translator{ - \StaffContext - \remove "Staff_symbol_engraver"; - \remove "Clef_engraver"; - \remove "Key_engraver";} - } - } -\end{mudela} - -It is impossible to deduce the exact pitch of the notes. One needs a -clef to do so. Staff lines help the eye in determining the vertical -position of a note wrt. to the clef. -\begin{mudela} -\score { - \notes \relative c' {\clef alto; \time 2/4; g'4 c,4 a'4 f4 e c d2 } - \paper { - linewidth = -1.; - } -} -\end{mudela} - -Now you know the pitch of the notes: you look at the start of the line -and see a clef, and with this clef, you can determine the notated pitches. -You have found the em(context) in which the notation is to be -interpreted! - - -\section{Interpretation context} - -Context (clef, time signature etc.) determines the relationship -between musical and its notation in notes. Because LilyPond writes -notation, context works the other way around for LilyPond: with -context a piece of music can be converted to notation. - -A reader remembers this context while reading the notation from left -to right. By analogy, LilyPond constructs this context while -constructing notes from left to right. This is what happens in the -``Interpretation'' phase from~\ref{fig:intro-fig}. In LilyPond, the -state of this context is a set of variables with their values; A staff -context contains variables like - -\begin{itemize} -\item current clef -\item current time signature -\item current key -\end{itemize} - -These variables determine when and how clefs, time signatures, bar -lines and accidentals are printed. - - -Staff is not the only form of context in notation. In polyphonic -music, the stem direction shows which notes form a voice: all notes of -the same voice have stems pointing in the same direction. The value -of this variable determines the appearance of the printed stems. - -In LilyPond ``Notation context'' is abstracted to a data structure -that is used, constructed and modified during the interpretation -phase. It contains context properties, and is responsible for -creating notational elements: the staff context creates symbols for -clefs, time signatures and key signatures. The Voice context creates -stems, note heads. - -For the fragment of polyphonic music below, -\begin{mudela} - \context Staff { c'4 < { \stemup c'4 } \context Voice = VB { \stemdown a4 } > } -\end{mudela} -A staff context is created. Within this staff context (which printed -the clef), a Voice context is created, which prints the first note. -Then, a second Voice context is created, with stem direction set to -``up'', and the direction for the other is set to down. Both Voice -contexts are still part of the same Staff context. - -In the same way, multiple staff scores are created: within the score -context, multiple staff contexts are created. Every staff context -creates the notation associated with a staff. - -\section{Discussion} - - - -\end{document} - -The complexity of music notation was tackled by adopting a modular -design: both the formatting system (which encodes the esthetic rules of -notation), and the interpretation system (which encodes the semantic -rules) are highly modular. - - -The difficulty in creating a format for music notation is rooted in -the fact that music is multi dimensional: each sound has its own -duration, pitch, loudness and articulation. Additionally, multiple -sounds may be played simultaneously. Because of this, there is no -obvious way to ``flatten'' music into a context-free language. - -The difficulty in creating a printing engine is rooted in the fact -that music notation complicated: it is very large graphical -``language'' with many arbitrary esthetic and semantic conventions. -Building a system that formats full fledged musical notation is a -challenge in itself, regardless of whether it is part of a compiler or -an editor. - -The fact that music and its notation are of a different nature, -implies that the conversion between input notation is non-trivial. - -In LilyPond we solved the above problem in the following way: - diff --git a/Documentation/metadoc/musicnotes.sty b/Documentation/metadoc/musicnotes.sty deleted file mode 100644 index 31d2f83a9c..0000000000 --- a/Documentation/metadoc/musicnotes.sty +++ /dev/null @@ -1,43 +0,0 @@ - -\input lilyponddefs - -\def\fetdef#1#2{% - \def#1{\hbox{\char#2}}} - -% huh? from where -\input feta20.sty - -\font\fetasixteenfont=feta16 -\font\fetaelevenfont=feta11 -\def\fetafont{\fetasixteenfont} - -\newdimen\ild -\ild=4pt -\newdimen\stemthick -\stemthick=0.4pt - -\def\eighthstem{{\fetafont\vrule height 3.5ex width \stemthick depth0pt\raise - 3.5ex\hbox{\eighthflag}}} -\def\texteighthflag{{\fetafont\raise 0ex\hbox{\fetafont\eighthflag}}} -\def\textdeighthflag{{\fetafont\raise 0ex\hbox{\deighthflag}}} - -\def\texteighthnote{{\hbox{\hbox{\fetafont\quartball}\kern - -0.5\stemthick\eighthstem}}} -\def\quarterstem{{\fetafont\vrule height 3.5ex width \stemthick depth0pt}} -\def\textquarterstem{\quarterstem} -\def\textchord{{\hbox{\fetafont\lower.5ex\hbox to - 0pt{\textquarterhead}\raise.5ex\hbox{\textquarterhead}\kern - -0.5\stemthick\eighthstem}}} -\def\textbassclef{\hbox{\fetafont\bassclef}} -\def\texttrebleclef{\hbox{\fetafont\trebleclef}} -\def\textslur{\embeddedps{9.378744 -3.171539 3.923099 -3.171539 0.000000 0.000000 12.800000 0.000000 3.672177 -3.672177 9.127823 -3.672177 12.800000 0.000000 0.000000 0.000000 draw_slur}} - -\def\textmarcato{{\fetafont\raise 1ex\hbox{\hskip 1ex\sforzatoaccent}}} - - -\def\textquarterhead{\hbox{\fetafont\raise 2.5pt\hbox{\quartball}}} -\def\texteighthstem{\hbox{\lower 5pt\hbox{\eighthstem}}} -\def\texthalfnote{{\hbox{\hbox{\fetafont\halfball}\kern -0.5\stemthick\quarterstem}}} -\def\textquarternote{{\hbox{\hbox{\fetafont\quartball}\kern -0.5\stemthick\quarterstem}}} -\def\textflat{{\fetafont\raise 1ex\hbox{\flat}}} -\def\textsharp{{\fetafont\raise1ex\hbox{\sharp}}} diff --git a/Documentation/metadoc/regression-test.tely b/Documentation/metadoc/regression-test.tely deleted file mode 100644 index 24e4d58902..0000000000 --- a/Documentation/metadoc/regression-test.tely +++ /dev/null @@ -1,312 +0,0 @@ -\input texinfo @c -*-texinfo-*- vim:tw=72 -@setfilename regression-test.info -@settitle LilyPond Regression test - -@c fool ls-latex -@ignore -@author Han-Wen Nienhuys and Jan Nieuwenhuizen -@title LilyPond Regression test -@end ignore - -@node Top, , , - -@section Introduction - -This document tries give an brief overview of LilyPond features. When -the text correspond with the shown notation, we consider LilyPond -Officially BugFree (tm). This document is intended for finding bugs, -and documenting bugfixes. - -@section Notes and rests - -Rests. Note that the dot of 8th, 16th and 32nd rests rest should be -next to the top of the rest. All rests except the whole rest are -centered on the middle staff line. - -@mudelafile{rest.fly} - -Note head shapes are settable. The stem endings should be adjusted -per note head. If you want different note head styles on one stem, -you must create a special context called Thread. - -@mudelafile{noteheadstyle.ly} - -Noteheads can have dots, and ---although this is bad style in duple -meters--- rests can too. Augmentation dots should never be printed on -a staff line, but rather be shifted vertically. They should go up, but -in case of multiple parts, the down stems have down shifted dots. -(Wanske p. 186) In case of chords, all dots should be in a column. -The dots go along as rests are shifted to avoid collisions. - -@mudelafile{dots.fly} - -Multiple measure rests do not collide with barlines and clefs. They -are not expanded when you set @code{Score.SkipBars}. Although the -multi-measure-rest is a Spanner, minimum distances are set to keep it -colliding from barlines. - -@mudelafile{multi-measure-rest.ly} - -@section Stems - -Stem tremolos (official naming?) or rolls are tremolo signs that look -like beam segments crossing stems. If the stem is in a beam, the -tremolo must be parallel to the beam. If the stem is invisible -(eg. on a whole note), the tremolo must be centered on the note. - -@mudelafile{stem-tremolo.ly} - -Chord tremolos look like beams, but are a kind of repeat symbol. -To avoid confusion, chord tremolo beams do not reach the stems, but -leave a gap. Chord tremolo beams on half notes are not ambiguous, -as half notes cannot appear in a regular beam, and should reach the -stems. - -@mudelafile{chord-tremolo.sly} - -Beams, stems and noteheads often have communication troubles, since -the two systems for y dimensions (1 unit = staffspace, 1 unit = 1 -point) are mixed. - -Stems, beams, ties and slurs should behave similarly, when placed -on the middle staff line. Of course stem-direction is down for high -notes, and up for low notes. - -@mudelafile{stem-direction.sly} - -Similarly, if @code{stem_default_neutral_direction} is set to @code{-1}. - -@mudelafile{stem-direction-down.ly} - -@section Scripts - -The staccato dot (and all scripts with follow-into-staff set), must -not be on staff lines. - -@mudelafile{staccato-pos.sly} - -@section Grace notes - -Grace notes are typeset as an encapsulated piece of music. You can -have beams, notes, chords, stems etc. within a @code{\grace} section. -Slurs that start within a grace section, but aren't ended are attached -to the next normal note. Grace notes have zero duration. If there -are tuplets, the grace notes won't be under the brace. Grace notes -can have accidentals, but they are (currently) spaced at a fixed -distance. Grace notes (of course) come before the accidentals of the -main note. Grace notes can also be positioned after the main note. - -@mudelafile{grace.ly} - - -@section Beams, slurs and other spanners - -Beaming is generated automatically. Beams may cross bar lines. In that -case, line breaks are forbidden. Yet clef and key signatures are -hidden just as with breakable bar lines. - -@mudelafile{beaming.ly} - -Beams should behave reasonably well, even under extreme circumstances. -Stems may be short, but noteheads should never touch the beam. - -@mudelafile{beam-extreme.ly} - -Beams should always reach the middle staff line, the second beam -counting from the note head side, should never be lower than the -second staff line. This does not hold for grace note beams. - -@mudelafile{beam-position.sly} - -Slurs should look nice and symmetric. The curvature may increase -only to avoid noteheads, and as little as possible. - -@mudelafile{slur-symmetry.ly} -@mudelafile{slur-symmetry-1.ly} - -Ties are strictly horizontal. They are placed in between note heads. -The horizontal middle should not overlap with a staffline. - -@mudelafile{tie.ly} - -Beams can be typeset over fixed distance aligned staffs, beam -beautification doesn't really work, but knees do. Beams should be -behave well, wherever the switching point is. - -@mudelafile{beam-interstaff.ly} - -The same goes for slurs. They behave decently when broken across -linebreak. - -@mudelafile{slur-interstaff.ly} - -Tuplets are indicated by a bracket with a number. There should be no -bracket if there is one beam that matches the length of the tuplet. -The bracket does not interfere with the stafflines, and the number is -centered in the gap in the bracket. - -@mudelafile{tup.ly} - -@section Repeats - -LilyPond has three modes for repeats: folded, unfolded and -semi-unfolded. Unfolded repeats are fully written out. Semi unfolded -repeats have the body written and all alternatives sequentially. -Folded repeats have the body written and all alternatives -simultaneously. If the number of alternatives is larger than the -repeat count, the excess alternatives are ignored. If the number of -alternatives is smaller, the first alternative is multiplied to get to -the number of repeats. - -Unfolded behavior: - -@mudelafile{repeat-unfold.ly} - -Volta (Semi folded) behavior. Voltas can start on non-barline moments. -If they don't barlines should still be shown. - -@mudelafile{repeat-volta.ly} - -Folded. This doesn't make sense without alternatives, but it works. - -@mudelafile{repeat-fold.ly} - -@section Lyrics - -Lyrics can be set to a melody automatically. Excess lyrics will be -dumped. Lyrics will not be set over rests. You can have melismata -either by setting a property melismaBusy, or by setting -automaticMelismas (which will set melismas during slurs and ties). If -you want a different order than first Music, then Lyrics, you must -precook a chord of staffs/lyrics and label those. Of course -@code{\rhythm} ignores any other rhythms in the piece. Hyphens and -extenders do not assume anything about lyric lengths, so they continue -to work. - -@mudelafile{lyric-combine.ly} - -@section Multiple notes - -Rests should not collide with beams, stems and noteheads. Rests may -be under beams. Rests should be move by integral number of spaces -inside the staff, and by half spaces outside. Notice that the half -and whole rests just outside the staff get ledger lines in different -cases. - -@mudelafile{rest-collision.ly} - -Normal collisions. We have support for polyphony, where the -middle voices are horizontally shifted. - -@mudelafile{collisions.ly} - -The number of stafflines of a staff can be set with the property -numberOfStaffLines. Ledger lines both on note heads and rests are -adjusted. Barlines also are adjusted. - - -@mudelafile{number-staff-lines.fly} - -@section Spacing - -In a limited number of cases, LilyPond corrects for optical spacing -effects. In this example, space for opposite pointed stems is adjusted - -@mudelafile{stem-spacing.sly} - -If there are accidentals in the music, we add space, but the space -between note and accidentals is less than between the notes with the -same value. Clef changes also get extra space, but not as much as -barlines. - - -Even if a line is very tightly spaced, there will still be room -between prefatory matter and the following notes. The space after the -prefatory is very rigid. In contrast, the space before the barline -must stretch like the space within the measure. - -Tight: - -@mudelafile{spacing-tight.ly} - -Natural: - -@mudelafile{spacing-natural.ly} - -Loose: - -@mudelafile{spacing-loose.ly} - -Adding a @code{Bar_engraver} to the LyricsVoice context makes sure that -lyrics don't collide with barlines. - -@mudelafile{lyrics-bar.ly} - -@section Global stuff - -Breaks can be encouraged and discouraged using @code{\break} and -@code{\nobreak}. They are abbrevs for @code{\penalty} commands. - -@mudelafile{break.ly} - - -Markings that are attached to (invisible) barlines are -delicate: the are attached to the rest of the score without the score -knowing it. Consequently, they fall over often. - -@mudelafile{bar-scripts.ly} - -Staff margins are also markings attached to barlines. They should be -left of the staff, and be centered vertically wrt the staff. They may -be on normal staffs, but also on compound staffs, like the PianoStaff - -@mudelafile{staff-margin.ly} - -Breathing signs, also used for phrasing, do normally not influence -global spacing -- only if space gets tight, notes are shifted to make -room for the breathing sign. Breathing signs break beams running -through their voice. In the following example, the notes in the first -two measures all have the same distance from each other: - -@mudelafile{breathing-sign.ly} - -Fonts are available in a default set of sizes: 11, 13, 16, 20, 23 and -26pt staffheight. Sizes of the text fonts and symbol fonts are made -to match the staff dimensions. - -@mudelafile[nofly]{size11.ly} - -@mudelafile[nofly]{size13.ly} - -@mudelafile[nofly]{size16.ly} - -@mudelafile[nofly]{size20.ly} - -@mudelafile[nofly]{size23.ly} - -@mudelafile[nofly]{size26.ly} - - -@section Clefs and Time Signatures - -The transparent clef should not occupy any space and with style -@code{fullSizeChanges}, the changing clef should be typeset in full -size. For octaviated clefs, the ``8'' should appear closely above or -below the clef respectively. The ``8'' is processed in a convoluted -way, so this is fragile as well. - -@mudelafile{clefs.ly} - -@ignore -@c the input file is too long and does not test for specific bugs -By default, time signatures are written with two numbers. With style -``C'', 4/4 and 2/2 are written with their corresponding symbols and -with style ``old'', 2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8 and -9/8 are typeset with symbols, all other signatures retain the default -layout. The style ``1'', gives single number signatures for all -signatures. -% -\mu delafile{time.fly} -@end ignore - -@bye diff --git a/Documentation/misc/CHANGES-1.2 b/Documentation/misc/CHANGES-1.2 new file mode 100644 index 0000000000..7bb36d49aa --- /dev/null +++ b/Documentation/misc/CHANGES-1.2 @@ -0,0 +1,287 @@ + +pl 15.hwn1 + - reverted MIDI unfold patches. + - bf: cross staff beam, cross staff slur (2x) + - doco updates: + * metadoc/ -> programmer/ , + * FAQ + * hacking + * index with logo + +pl 15.jcn3 + - bf: smob fix + - mutopia/doc target 'local-web': + shorthand for 'CONFIGSUFFIX=www local-WWW' + +pl 15.lu2 + - bf: close comments in website footer + - error messages for release didn't make it into .lu1? +pl 15.jcn2 + - small website fixes +pl 15.jcn1 + - bfs: initialise members of Column-x-positions and Break_node + - bf: Documentation/misc: don't include backups + - bf: .gdbinit +pl 15.lu1 + - error messages for failing diff/release + - \property noStemExtend: don't extend normal or beamed stems to + middle staff line: input/test/no-stem-extend.fly + +****** +pl 15 (Oct 18) + +14.jcn1 + - Kludge for accented chars (thanks, Mats) + - bf: don't fail on error in doco package + - doco package: noarch + - bf: standchen: mutopia prep + +14.hwn1 + - move some misc stuff into Documentation/misc/ + - cleanups: slur & beam. + - junked Encompass_info + - Smobs -- simplifies sc_elt memory management + - Timing_engraver collects bar reqs + - unfold all if doing MIDI. + - bfs: do something sensible if it doesn't fit. + - penalties for break stuff supported. + +******* +13.jcn2,3 + - mutopia/J.S.Bach/Petites-Preludes: bf's and mutopia preraration + - separate documentation package + +13.hwn2 + - mutopia: scs2, horn-concerto-3 + - junked Line_spacer baseclass. + - removed gourlay complications + - use force iso. energy for minimisation. Add uniformity term +to demerits. + +13.jcn1 + - bf: mudela-book + +******* +12.jcn1 + - auto-knees, input/test/auto-knee.ly + +pl 12.rrr2 + - voltaSpannerDuration may be a rational + - .ly files corrected, Voice.dynamicDir to Voice.dynamicDirection + +pl 12.rrr1 + - key (K:) with clef, bug fix for abc2ly + - voltaSpannerDuration code added to lilypond + +pl 12.hwn1 + - junked wordwrap + - bf: use position (not pitch) for autochange + - mudela-book fixes: --dependencies, --dep-prefix + - mudela.tely more updates. Now absorbed LilyPond manpage. + - BUGS now in INSTALL.texi + +******* +pl 11.uu1 + - changed debug init code. + +pl 11.jcn2 + - bf: LDFLAGS=foo CFLAGS=bar ./configure + - bf: configure (--disable-printing = default) -DNPRINT + - bf: mf-to-xpms / make -C mf xpms; feta-accordion is broken, + see mf/README + +pl 11.jcn1 + - gnossiene with new \autochange + +pl 11.jbr1 + - Tried to get rid of path and switch dependencies in mf + build process. + +pl 11.hwn1 + - doco reorganisation: folded glossary and tutorial into manual. + - move mudela-book-doc to texinfo + - feta.tex to mf/ + - release.py, package-diff.py now dump into out/ + + +**** +pl 10.hwn1 + - Auto_change_music, Auto_change_iterator: auto staff +switching. 2nd try. See input/test/auto-change.ly + +pl 10.uu1 + - doc restructure: hacking.texi + - make & install .pfas + - updates: faq.texi + - rpm fixes. + - Windows fixes (9.jbr) + +****** +pl 9.rrr1 + - abc2ly bug fixes and extensions + - volta spanner given height to avoid collisions + +pl 9.jcn2 + - 2.95 fixes + - input/test/different-time-signatures.ly (wasn't this in refman?) + +pl 9.hwn1 + - fixes for mi2mu + - bf: staff-side with empty parent. + - bf: +Hara_kiri_vertical_group_spanner::do_substitute_element_pointer has to +call Axis_group_spanner::do_substitute_element_pointer. Fixes +harakiri & barline problem. + - junk: Spring_spacer, Ineq_constrained_qp, Mixed_qp, +Active_constraints, Inactive_iter, Matrix, Vector, +Choleski_decomposition, Full_storage + + +pl 9.jcn1 + - included last Localisation.texi + - set-lily: de catalog too + +******* +pl 8.hwn1 + - Erwin Dieterich: german translation. + - dependency helper funcs simplified. + - junk breaking stats. + - cleanups: Line_of_score also is X_AXIS group. Score_columns +are put into Line_of_score of score. + +pl 8.jcn2 + - scripts/mudela-book.py: use hash of full .ly contents (by default) + - bf: footify html doc upon creation too + +pl 8.jcn1 + - Documentation/Localisation.texi: still some issues + - Uniformised locale strings + - marked some errors/warnings without _/_f markings + - added programming_warning (): not to be localised warnings + (none identified as yet) + - Update of po/nl.po + +******* +pl 7.hwn1 + - website fixes. + - spacer cleanups + - Simple_spacer: a simpler constraint solver. Enabled by default. +pl 7.jcn1 + - fixes to nl.po + +******** + +pl 6.uu1 + - website fixes. + +******* +pl 5.hwn1 + - more .texi; yodl completely removed. + - rm'd several doc stuff: engraving.yo, gnu-page.yo, translated blurbs (leave it to translation project) + - sm: help2man-*make + - mcgrain bib entry. + - debian updates. + - gcc 2.95 const fixes. (hopefully) + - sm: rm'd Documentation/tex/ directory. everything in stepmake/INSTALL.texi + +pl 5.jcn1 + - lily.scm: don't use regex-substitute/global + - website/doco fixes + - bf: package-diff.py + +************ + +pl 4.hwn1 + - bf: repeats. + - bf: mmrests + - bf: simpler guile detection. + - use texinfo for reference manual. + - inline lily.ps from lilypond. + - texi for doco: converted directory Documentation/tex/ + + +pl 3.hwn1 + - mudela-book tweaks for surviving texinfo + - include feta command seqs. in .tex + - guile 1.3.2 fixes. + - include config.h directly. + - bf: mudela-book. Now linear in size of document. + - scriptHorizontal property; more or less works. + - changes in Graphical_element, Graphical_axis_group +offset removed from public interface, now use relative_coordinate (). +extent () is given relative to this. + - removed Rhythmic_head::dots_i_ + - bf: Rhythmic_head::do_substitute_element_pointer () + - Direct access to dim_cache_ replaced by methods in +Graphical_element. + +********** + + +pl 2.mk1 + - bf, tie.cc: handle postbreak left align correctly +pl 2.lec1 + - abc2ly fixes. + +pl 2.hwn1 + - rewrite of mudela-book. Now uses chunks, and you can put +\input, \include and \mudelagraphics in verbatim sections. + + +pl 2.jcn2 + - bf: auto-beamer: don't junk beam if manual beam shows up + +pl 2.jcn1 + - add-html-footer.py, ls-latex.py .tely updates and fixes + - tely (texinfo-lily) rules and test Documentation/metadoc/foo.tely + +************* + +pl 1.uu2 + - complete rewrite of mudela-book. Much cleaner now. +Support for texinfo. + - convert-mudela now per file, add \version if not present. + +pl 1.uu1.jcn1 + - internationalization fixes for getopt-long help + +pl 1.uu1 + - rewrite --help messages for help2man: + * lilypond + * mi2mu + * mudela-book + * convert-mudela + - cleanup: mf-to-table.py + - Getopt_long: support for --help msg. + +pl 1.mb1 + - bf, scalar.cc: ".3" now detected as numerical + +******** + +pl 0.uu1 + - refman updates by Werner & Mats + - now use ChangeLog for changes. + +pl 0.jcn2 + - po fixes + +pl 0.jcn1 + - gcc-2.95 nitpicks + - added pointers to mailing lists in toplevel docs + +0.mb2 + - configure: more robust detection of Guile + - Midi_note_off: revert to fixed note-off velocity. Fixes + problem with notes that never stop. + - Decreased breakable_column_space_strength + - Added a few TODO + - bf: "harmonic" and "cross" note heads also for half and + whole notes. + - linewidth and textheight set independent of the font size. + - bf, titledefs.tex: opus and piece are not repeated for + every piece unless they are explicitly set again. + +0.mb1 + - Changed dynamicDir to dynamicDirection. + - refman and tutorial corrections. diff --git a/Documentation/misc/GNUmakefile b/Documentation/misc/GNUmakefile index 55a1efe7ed..d9b79c0e6e 100644 --- a/Documentation/misc/GNUmakefile +++ b/Documentation/misc/GNUmakefile @@ -4,10 +4,9 @@ NAME = documentation STEPMAKE_TEMPLATES=documentation texinfo -TEXTS =AIMS $(wildcard CHANGES-*) $(wildcard ANNOUNCE-*) $(wildcard NEWS-*) interview +TEXTS =AIMS $(wildcard CHANGES-*[0-9]) $(wildcard ANNOUNCE-*[0-9]) $(wildcard NEWS-*[0-9]) interview EXTRA_DIST_FILES = $(TEXTS) - include $(depth)/make/stepmake.make default: do-doc diff --git a/Documentation/misc/NEWS-1.2 b/Documentation/misc/NEWS-1.2 index d3499b3490..bc03e6e5a0 100644 --- a/Documentation/misc/NEWS-1.2 +++ b/Documentation/misc/NEWS-1.2 @@ -1,3 +1,12 @@ +WHAT'S NEW SINCE 1.2.0 + +* Much faster spacing engine. + +* Features: automatic staff switching + +* Documentation now all is in texinfo. + + WHAT'S NEW SINCE 1.0.17 * Large cleanups, enhanced design and GUILE integration for smaller diff --git a/Documentation/misc/NEWS-1.2~ b/Documentation/misc/NEWS-1.2~ deleted file mode 100644 index d3499b3490..0000000000 --- a/Documentation/misc/NEWS-1.2~ +++ /dev/null @@ -1,25 +0,0 @@ -WHAT'S NEW SINCE 1.0.17 - -* Large cleanups, enhanced design and GUILE integration for smaller - memory footprint and more flexible code. - -* Direct output to PostScript (optional), PDFTeX or as GUILE script - (default output still to plain TeX). - -* Convertors for ABC and MUP formats. - -* Font: now available as scalable PostScript. New glyphs: time - signature, more note heads. - -* Enhanced input: semi-automatic beaming, (nested) tuplets, (nested) - repeats, chordnames, automatic Lyrics durations. - -* Grace notes, volta brackets, multiple styles for note heads and - time signatures, breathing signs, lyric extenders, cross staff - beaming and slurring. - -* --safe option for the paranoid. - -* More elegant spacing. Text is spaced exactly. - -* Lots of bugfixes. diff --git a/Documentation/pictures/lelie-icon.xpm b/Documentation/pictures/lelie-icon.xpm new file mode 100644 index 0000000000..0ad7f75dc1 --- /dev/null +++ b/Documentation/pictures/lelie-icon.xpm @@ -0,0 +1,141 @@ +/* XPM */ +static char *noname[] = { +/* width height ncolors chars_per_pixel */ +"50 71 63 2", +/* colors */ +"`` c #666664", +"`a c #F2F2F4", +"`b c #5E5E5C", +"`c c #EAEAEC", +"`d c #565654", +"`e c #E2E2E4", +"`f c #4E4E4C", +"`g c #DADADC", +"`h c #464644", +"`i c #D2D2D4", +"`j c #3E3E3C", +"`k c #CACACC", +"`l c #363634", +"`m c #C2C2C4", +"`n c #2E2E2C", +"`o c #BABABC", +"`p c #262624", +"`q c #B2B2B4", +"`r c #1E1E1C", +"`s c #AAAAAC", +"`t c #161614", +"`u c #A2A2A4", +"`v c #0E0E0C", +"`w c #9A9A9C", +"`x c #060604", +"`y c #929294", +"`z c #8A8A8C", +"a` c #828284", +"aa c #7A7A7C", +"ab c #727274", +"ac c #6A6A6C", +"ad c #626264", +"ae c #5A5A5C", +"af c #525254", +"ag c #4A4A4C", +"ah c #424244", +"ai c #3A3A3C", +"aj c #323234", +"ak c #2A2A2C", +"al c #FEFEFC", +"am c #222224", +"an c #F6F6F4", +"ao c #1A1A1C", +"ap c #EEEEEC", +"aq c #121214", +"ar c #E6E6E4", +"as c #0A0A0C", +"at c #DEDEDC", +"au c #D6D6D4", +"av c #CECECC", +"aw c #C6C6C4", +"ax c #BEBEBC", +"ay c #B6B6B4", +"az c #AEAEAC", +"b` c #A6A6A4", +"ba c #9E9E9C", +"bb c #969694", +"bc c #8E8E8C", +"bd c #868684", +"be c #7E7E7C", +"bf c #767674", +"bg c #6E6E6C", +"bh c #FAFAFC", +/* pixels */ +"alalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalal", +"alalbhbhalalbhalalbhalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalalal", +"alalalbhbhalalbhalalalalalalalalalalalalalalalalalal`o`ya``s`wbhalalalalalalalalalalalalalalalalalal", +"bhalalalalalbhalalalalalalalalalalalalalalalalalal`a`malalalap`obb`malalalalal`cax`galalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalalalalalbcalbhalalalalalax`ialalal`gauav`u`ealalalalalalal", +"alalalalalalalbhalalalalalalalalalalalalalalalalawar`ialalalalalalalaxapalalbaacat`i`oalalalalalalal", +"alalbhalalalalbhalalalalalalalalalalalalalalalalazal`sbhalalalalalalalayalbh`eba`iapavalalalalalalal", +"albhalbhalalalalalalalalalalalalalalalalalalalal`oatalb``aalalalalalal`oanazazanbhayalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalalanawal`salalbaalalalalalalalazaa`cav`oalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalapawalalaranal`i`qalalalalalalbeayazbcbcalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalal`g`oapalalalalal`yalalalalal`gbbabbhapalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalal`sanalalalalalbdalalalalalbc`obbalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalapaaanalalalalal`qatan`ealax`sbbazalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalal`kab`oalalalalalau`uaw`salbb`ua`bcalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalalalayalalalalalalan`ea`axax`oba`oazaxaralalalalalalalalalalal", +"alalalalalalalalalalapbhalalalalalalalalalaybhalalalalan`s`sazav`gaz`qbdalalazalalalalalalalalalalal", +"alalalalalalalalalalax`u`aalalalalalalalalaraw`o`c`c`aaxaw`g`kav`sayb`ayalal`m`calalalalalalalalalal", +"alalalalalalalalalalal`c`sbhalalalalalalalalalal`c`jb`albh`yavapazay`w`ialalalay`aalalalalalalalalal", +"alalalalalalalalalalalalar`qbhalalalalalalalalalal`v`sav`abcaubbaw`u`salalalalalayapalalalalalalalal", +"alalalalalalalalalalalalal`i`kalalalalalalalalalal`l`way`uau`cazazazbc`q`ialalalal`galalalalalalalal", +"alalalalalalalalalalalalalalaw`galalalalalalan`i`m`hbe`q`oap`w`m`uax`ialax`salalalalalalalalalalalal", +"alalalalalalalalalalalalalalal`oatalalalbh`kbaadagad```oav`i`mb`ba`ualalal`i`oalalalalalalalalalalal", +"alalalalalalalalalalalalalalalanaz`aalanaz`nag`ian`w`k`iar`waw`o`o`ialalalalau`ialalalalalalalalalal", +"alalalalalalalalalalalalalalalalapba`c`zakac`aalau`calapaz`gbabb`qbhalalalalal`ualalalalalalalalalal", +"alalalalalalalalalalalalalalalalal`ibdambd`c`aalalalal`a`yax`kb``u`aalalalalal`e`kalalalalalalalalal", +"alalalalalalalalalalalalalalalalarbcajbf`q`kalalalalal`w`c`sbc`k`e`kalalalalalal`salalalalalalalalal", +"alalalalalalalalalalalalalalalalawaoaibbaw`kalalalalapbaaw`gb`baalaualalalalalal`salalalalalalalalal", +"alalalalalalalalalalalalalalal`cbgaq`y`q`o`ialalalal`wbh`sba`g`oalaralalalalalal`ualalalalalalalalal", +"alalalalalalalbhbhalalalalalalar`v`lbfazap`qapalal`gaz`k`e`y`u`galbhalalalalalalb`alalalalalalalalal", +"alalalalalalalalalalalalalalalbb`x`l`qayalap`u`aala`al`u`q`ebebhalbhalalalalalalb`alalalalalalalalal", +"alalalalalalalalalalalalalalal`gao`hayazalalapb``kax`iaubeaybaalalalalalalalalalbaalalalalalalalalal", +"alalalalalalalalalalalalalalalalbdahba`galalalatbcalbb`maxbeatalalalalalalalalalbaalalalalalalalalal", +"alalalalalalalalalalalalalalalalau`jb``calbhalal`k`oaw`zapbfalalalalanalalalalal`salalalalalalalalal", +"alalalalalalalalalalalalalalalal`aad`malalbbalalal`o`kbb`y`ialalalal`walalalalal`qalalalalalalalalal", +"alalalalalalalalalalalalalalalalalbebaalapbfalalalbhbb`c`dalalalalalagalalalalap`oalalalalalalalalal", +"alalalalalalalalalalalalalalalalalbb`ialalajalalalalap`w`walalalalaxaaalalalal`qalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalazalalalbf`aalalalalbaayanalalalbg`ealalalbh`qalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalaxalalalbebhalalal`c`s`saxalalal``alalalalaybhalalalalalalalalalal", +"alalalalalalalalalalalalalalalalal`oalalal`ealalalalbb`eaw`uawalalawalbhalataualalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalanalalalalalalalal`wb`alayb``malalal`sal`oalalalalalalalalalalalal", +"alalalalalalalalalalalalalalalalalalalal`galalalal`q`g`wauaraz`yalalaxapalbhalalalalalalalalalalalal", +"alalalalbhalalalalbhalalalalbhbhalalbhal`salalalal`waw`kay`kapb`al`k`galalalbhbhbhbhbhalalalalalalal", +"albhbhalbhalalalalbhalalalalalbhalalal`i`malalbhar`sbdal`q`oalalal`walalbhalalalalalbhalalalalalalal", +"bhalalalalalalalalalalalbhalalal`ialalanavalalalbcalbbat`g`qalbhar`qalalalalalalalalalbhbhbhbhbhbhal", +"alalalalbhbhbhalalbhbhalalalal`mbealbhalawalalalbd`iat`oaratalal`yalbhalalalalalalalalalalalalalbhal", +"alalbhalalalalbhalalalalbhbhal`najalal`aarbhal`s`eazalazazalal`cb`alalalbhbhbhbhbhalalalalalalalalal", +"bhalbhalalalalbhalalalalalalbbas`naralalalalal`yalazarauayalalbaa`albhalalalalalbhalalalalalalalbhal", +"alalalalalalalalalalbhalal`aaq`r`hbdalalalalaraz`m`aazan`mal`ebd`jalalalalalalalalbhbhbhbhbhbhalalal", +"alalbhbhbhalalbhbhalalalalaa`vah`d`d`calbhalbaal`qal`o`obhalbhbd`ray`i`gbhalalalalalalalalalbhalbhal", +"bhalalalalbhalalalalbhalal`v`t`lah```ualalalbaan`q`cavaxalalatbeai`hauaw`waz`kav`ialalalalalalalalal", +"bhalalalalbhalalalalal`aap`x`tahafbb`ybdalavat`sbh`sal`qalal`c`qafam`faab`axauav`i`s`oaualalbhalbhal", +"alalalalalalalanaxax`s`q`gasao`pbebabb`ubd`walb`al`oavapalalbhaybeagaq`n`sauaw`i`iapat`kayauapalalal", +"bhbhbhalalav`kazarauayay`sad`r`facae`mazaubgb``sbh`m`oalalalalavbbaeai`j`oav`g`oatau`c`g`a`eb`azanal", +"alalalat`o`e`mavayavauarawayaq`lbf`yb``e`zap`yawbd`qayalalalap`ibcad`j`jbb`i`gapal`cal`iatau`gar`o`c", +"alal`eavalbh`g`g`g`ialanaral`b`vabbd`u`ibd`e`ual`o`ea`bbbdbcb`arb````la``uap`i`cavapalarav`catav`c`q", +"al`eavar`aanar`gavatayavaranatasae`wbcawax`iaval`calalalalalalaybcaf`hbb`garan`g`c`g`i`eatauatau`oap", +"al`s`a`carau`capanal`gapanbhal`s`ragbc`e`k`walalalalalalal`cap`oa`bfbgarauauan`g`i`e`c`c`a`g`cauatal", +"al`e`qay`s`i`eanarau`matau`cauau`s`ta`bd`sawalbhalalbhalapatav`s`f`baxalanat`aananan`eawat`max`aalal", +"bhalbhawavbh`aavar`e`gawawau`k`i`c`i`h`d`y`ealalbhalalalalapauaxb`avan`carbhan`gau`aan`iax`ebhalalal", +"alalalalan`uawawal`g`e`e`oatavat`q`ganbb`babbhalalap`ubbb`bb`z`u`gaparbhbhalanaw`iavax`cbhalalalbhal", +"albhalbhalalbhanax`oaw`m`i`m`m`kbhalalalap`obaavalbhan`aan`aalalalalapaxawaw`oapanbhalalalalalalbhal", +"alalalalalalalalalalananbhanbhalalalalalalalan`gb``qawavaxau`m`o`o`s`eananalalalalalalalalalalalalal", +"alalalalalalbhbhbhalalalalalalalalbhalbhalalalalalalbhbhanbhalalalalalalalalalalalalalalalbhalalalal", +"albhalalalbhalalalalalalalalbhbhbhalalalbhalbhalalalalalalalbhalalalalalalalalalbhalalalbhalalalbhal", +"alalbhbhalalalalalbhalbhalalalalalalalalbhalalbhalalalalbhalalalbhalalbhbhbhalalbhbhbhalalbhalalbhal", +"albhalalalalalalbhalbhalbhalalalalbhalalalalbhalalalalalalalalbhalbhalalalalbhalalal`aalalalbhalalal", +"alalalalbhbhbhalalalalalalalalbhalbhalalalalalbhbhbhbhalalbhalalalbhalalalalalap`qbb`salalalalalbhal", +"alalalbhalalalalalalalalbhbhbhalalalbhalbhalalalalalalalbhalalalalalalalalalalae`uav`calalalbhalalal", +"bhbhalalalalalbhalbhalalalalalalalalbhalalbhalalalalbhalalalbhalalbhbhbhalalalalalaralalalalbhalbhal" +}; diff --git a/Documentation/pictures/lelie-logo.xpm b/Documentation/pictures/lelie-logo.xpm new file mode 100644 index 0000000000..15408fb2ef --- /dev/null +++ b/Documentation/pictures/lelie-logo.xpm @@ -0,0 +1,215 @@ +/* XPM */ +static char *noname[] = { +/* width height ncolors chars_per_pixel */ +"100 143 65 1", +/* colors */ +" c #ADADAD", +". c #A5A5A5", +"X c #9D9D9D", +"o c #959595", +"O c #8D8D8D", +"+ c #858585", +"@ c #7D7D7D", +"# c #757575", +"$ c #6D6D6D", +"% c #656565", +"& c #5D5D5D", +"* c #555555", +"= c #4D4D4D", +"- c #FCFCFC", +"; c #FAFAFA", +": c #454545", +"> c #F2F2F2", +", c #3D3D3D", +"< c #EAEAEA", +"1 c #353535", +"2 c #E2E2E2", +"3 c #2D2D2D", +"4 c #DADADA", +"5 c #252525", +"6 c #D2D2D2", +"7 c #1D1D1D", +"8 c #CACACA", +"9 c #151515", +"0 c #C2C2C2", +"q c #0D0D0D", +"w c #BABABA", +"e c #050505", +"r c #B2B2B2", +"t c #AAAAAA", +"y c #A2A2A2", +"u c #9A9A9A", +"i c #929292", +"p c #8A8A8A", +"a c #828282", +"s c #7A7A7A", +"d c #727272", +"f c #6A6A6A", +"g c #626262", +"h c #5A5A5A", +"j c #525252", +"k c #FDFDFD", +"l c #4A4A4A", +"z c #F5F5F5", +"x c #424242", +"c c #EDEDED", +"v c #3A3A3A", +"b c #E5E5E5", +"n c #323232", +"m c #DDDDDD", +"M c #2A2A2A", +"N c #D5D5D5", +"B c #222222", +"V c #CDCDCD", +"C c #1A1A1A", +"Z c #C5C5C5", +"A c #121212", +"S c #BDBDBD", +"D c #0A0A0A", +"F c #B5B5B5", +"G c #020202", +/* pixels */ +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkk;kkkkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkk;kkkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkk;kkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.lexGGj*9jkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkhkkkkkkkkwhs+kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk6 kkkkkkkkkkkVeCkkkkkkkkkkkkrsspkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOkkkkkkkkkkkkkk2G2kkkkkkkkkdkkkkekkkkkkkkkkkkkkkk", +"k;kkkk;kkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.Gkkkckkkkkkkkkkkk@kkkkkkkkskk:kkdokkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkw2rkkkkkkkkkkkkkkkkk1kkkkkkkdkGykuk@kkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkskk*kkkkkkkkkkkkkkkkrZkkkkkkGGtkm k%kkkkkkkkkkkkkkk", +"kkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjkkk$kkkkkkkkkkkkkkkkk=kkkkkkwniw kk@kkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk&kkkk3kkkkkkkkkkkkkkkkw6kkkkkk>X6kk4rkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkakkkkk=kkkkkkkkkkkkkkkk=kkkw:vNkkkk$kkkkkkkkkkkkkkkk", +"kkkkkkkkkkk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk&k06kkkvckkkkkkkkkkkkkk+zkkqkkkkkk&kkkkkkkkkkkkkkkkk", +"kk;;kk;kkkkkkk;kk;kkkkkkkkkkkkkkkkkkkkkkkkkkkkkukkk+kkkk,kkkkkkkkkkkkkkk%kMkkkkk.ykkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkX8kky+kkkkk:kkkkkkkkkkkkkk$kGZk2Fwykkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkNikkkkk+mkkkknckkkkkkkkkkkkk@l*kZM@vGkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk4okkkkkkkkkkkkkGkkkkkkkkkkkkkZfikXkc$Ckkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjkkkkkkkkkkkkkkGkkkkkkkkkkkkk9ry,>kktkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk% Zkkkkkkkkkkky.kkkkkkkkkkkXu6f$kkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkokpkknk*kh%kkkkkki4kkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkaikkkkkkkkkkkkkkkkkkkkkkk4rqZFskkk>kgk0>k%z44hk=kkkkkkk:kkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkk+ikkkkkkkkkkkkkkkkkkkkkkkkGhFFkkkk>Akskkvk*kxmZkkkkkkkkdkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkiikkkkkkkkkkkkkkkkkkkkkkk7D+0kkkk*FbNk,kkp.k*kkkkkkkkkzlkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkk>u.kkkkkkkkkkkkkkkkkkkkkkGGrF$;kkGkOkk7knkvkdkkkkkkkkkkzdkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkZoZkkkkkkkkkkkkkkkkkkkkkMM8$skk*zwkk:kkoNS@@kkkkkkkkkkkzMkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkSybkkkkkkkkkkkkkkkkkkkkfDO *kk=kwk>,kvk3kn>g$0kkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkku kkkkkkkkkkkkkkkkkkkV+G%uXkGkykk3kkfk+kjkkk*Mkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkO.kkkkkkkkkkkkkkk4o4k.G@&FS46;k4gkvkvk1gkkkkkG>kkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkiukkkkkkkkkkkkmSkSGG&GtrMFktkk9kk%kqkGckkkkkkGkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkcX kkkkkkkkkkukgGGG+;GMxZkOkkutkvk$k#xkkkkkkkk5kkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkNoVkkkkkkktjdGGsikkkGGVk+kmkBkkdkMkGhkkkkkkkkkjkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk X>kkyakk;;kyk7kkxkGkGykkkkkkkkkkkMkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkphk6k9Gqx1kkkkNSkkkkkSk,kk:k2skGmkkkkkkkkkkkb&kkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk+ukGG&=kkkkkkkkkkkkzakkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.;G6i>kkkkkkkkkk+tkkjkh;kGpkkskkkkkkkkkkkkwrkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk6kG77n:VOk#kkkkkkkkkkkGkkskkqkjx6k; kkkkkkkkkkkkk&kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk lGGxX,koykkkkkkkkkkkgbkk3k+tkGkkk$kkkkkkkkkkkkkk3kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk6kGGGFXdkbyukkkkkkkkkkCkkf;kGk41kkkpkkkkkkkkkkkkk=kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk4rGG1nyjm%kkkOakkkkkkDkkknkk1koGtkkkkokkkkkkkkkkkkkjkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk ,GC,5 cZ6kkkkO@kkkk.gkkONk1kkGZkkkk+kkkkkkkkkkkkkk=kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOyGG=l#;%2kkkkkOakkkGkkknkkGkkCfkkkk;kkkkkkkkkkkkkkjkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk4GG:*OV@Zkkkkkkpiktpkk 8k56kv9;kkkkkkkkkkkkkkkkkkk,kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkcGG#s>ykkkkkkk>obGkkk7kkGkkq8kkkkkkkkkkkkkkkkkkkk7kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk2CGp*0rkkkkkkkk .akkurkp+kbqokkkkkkkkkkkkkkkkkkkkjkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkm#Gpd;bkkkkkkkkktukkDkkGkkxu>kkkkkkkkkkkkkkkkkkkk=kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkNGgCkFkkkkkkkkkkpXmik<,kkGSkkkkkkkkkkkkkkkkkkkkk&kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkktyGtVkkkkNkkkkkkkovkkGkkdd4kkkkkkkkNkkkkkkkkkkkkfkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkSGk.kkkkGkkkkkkk;o0kGkk9rkkkkkkkkkGkkkkkkkkkkkw8kkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkbAhkkkkkGkkkkkkkk2t3wkwx;kkkkkkkkkG2kkkkkkkkkkMkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk83MkkkkFGkkkkkkkkkuokkA*kkkkkkkkkkG&kkkkkkkkkkhkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkA=kkkkkGVkkkkkkkkkd.kGbkkkkkkkkkkGZkkkkkkkkk$;kkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk5ykkkkkGGkkkkkkkkkkfdnzkkkkkkkkkaGkkkkkkkkkkgkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjkkkkkkrGkkkkkkkkkkkdikkkkkkkkkkGDkkkkkkkkkkkkkkkkkkN&wukkkkkkkkkkkkkkGkkkkkkkkObkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkhkkkkkkkkkkkkkkkkkkGkkgkk9ykkkkkkpkkkkkkk2.kkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkykkkkkkkkkkkkkkkkk2gkjzkXkyskkkkkkkkkbkkkhkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkvkkxkk&k4@#kkkkkkkm5kk*kkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk7kkgkkfk&koZkkkkkk%kk;0kkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk2kkkkkkkkkf8k1kktNkjkiXkkkkkhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk:kkkkkkkkkekk7kk$kkhk@akkkkfkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkobkkkkkkkk4#kr+kkjkOkkXhkkk ykkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk5kkkkkkkkkCkkGkk6Zk%kkkkkkk7kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkik kkkkkkkkCkkGkkgkk%kkkkkk8pkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkpkskkkkkkkgbkOrkkgkV8kkkkkk9kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk2NkkkkkkkGkkGkkNXkhkkkkkkk3kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkGkkkkkkkukkkkkkk4&kkfkk$kk$kkkkkk$kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkFGkkkkkkk+kkkkkkkqkkFSkkfkz kkkkkkqkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkGGckkkkkkukkkkkkkDkkjkk>ykdkkkkkkk7kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkhGGdkkkkkNSkkkkkk=4kkjkk*kk*kkkkkkk%kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkGGCGkkkkkkkkkkkkkGkka;kk=kk&kkkkkawikkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkAGG%Gkkkkkkkkkkkk4&kkjkkkukXckkkkmn$.kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkk>G3Gnv%kkkkkkkkkkkCkkk&kk%kk=kkkkkkg3Xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkkGGe91gGkkkkkkkkkkkCkkpkkkjkk$kkkbS.99@kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkk GGA$B%pskkkkkkkkkd4kk=kkkdkVZkkkkbbdG3kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkkGGAG$Gi$v;kkkkkkkk7kk>skk+kk%kkkkkk0OG,okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkktGBqCaha9dXkkkkkkkk&kkhkkkhkk$kkkkk<#BvG9mpsfN>kkkkkkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkGGGeD=,Chtswkkkkkk1kkkjkkkskk+kkkk6mX@:BC:kNrm3$fwitkkkkkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkGGGj5*gl$12=kkkkkk1kkNokkozkskkkkkk0y&%1GtFkykkF$kckdpftkkkkkkkkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkkkkkkkkkGAG5en#Dwyk+7kkkkZ kkjkkkxkkgkkkkkkkF hCnGlgO.xz>4b+dyikkkkkkkkkkkk", +"kkkkkkkkkkkkkkkkkkbot&h akGGG5GG*@syi06.Gkkhkkrwkk bkF2kkkkkkkwp +*=DGGjokkSjNXk tkkkk2ud$2kkkkkkkkk", +"kkkkkkkkkkkkkkk6p3$48wNckknGG=*MfNSt.a*c#*Akkk3kkk*kk&kkkkkkkkkX@loD=Ge$apykkkNkkkm2mVVkkk8sXkkkkkkk", +"kkkkkkkkkkkkkXi4k>0NsZk+sSrGB,Cs,lMAX46fkkGlak&kkk&kk&kkkkkkkkkpt$$,%MGh%>kkkbFrwm2k4>kbkkmkN9#kkkkk", +"kkkkkkkkkkNvy6%SkkkbN8awiSkGeDBpl0Fdc0.k0Si;8G&kk4VkkS2uk", +"kkkkkk%zkkkk<800840kkkkkkkkkFGDG:O aOOkVoa.k%kkkbSk>Gn&GGBnD9uVwkzkkNZ4kkk6VSkkkGGCps&$k$gkDk4k5kkkgkk>kkkkkkkkkkkz0bd#vGvbFkkkk4mkkZNkkkkt6kkzrkkFpNkk>owbkkkrNkmw;y mk", +"kkk$kkkbkykkAkkkkkkkkkkkkkkkkkkkwoZ+$3orkkkkkk4 Zkkkkk.0kkkbkk4kbukkk", +"kkkhkk8Nkkb8>zckkckkbFVkkkkkGBGOj%r;#k2+kkkkkkkkkkkkkkkyww02k.wkkkk", +"kkkXscihna6kwkbzkkk0iVz0y8kckVykkGC7oZGky8,kkkkkkkkkkkkkkwZkkFuh=jll3kkkkkkkk<2kkkkkkkkVw;k ;hckkkkk", +"kkkkklkkk>wr6kkk>opkk.0k2kFkO;ZbkkqGxdM8Fpkkkkkkkkkkkkkkkkk FVkNn%F5kkkkkk2tcckkkk2kVtiukSwyokkkkkkk", +"kkkkkkXOkkkkkkkyVkkkkVSZZ kFNF48Nkk8Gl5FiakkkkkkkkkkkkkkkkkV0 dpka&kkkkkkkkkkkkwyF4kkzzkruykkkkkkkkk", +"kkkkkkkzsykkkNpkkm4wF2w2N8 $(outdir)/index.html diff --git a/Documentation/programmer/feta20.sty b/Documentation/programmer/feta20.sty new file mode 100644 index 0000000000..0dbfcf90cc --- /dev/null +++ b/Documentation/programmer/feta20.sty @@ -0,0 +1,146 @@ +% Creator: mf-to-table.py version 0.7 +% Automatically generated on +% Do not edit +% input from out/feta20.log +% name +% rests +\fetdef\wholerest{0} +\fetdef\halfrest{1} +\fetdef\outsidewholerest{2} +\fetdef\outsidehalfrest{3} +\fetdef\breverest{4} +\fetdef\longarest{5} +\fetdef\multirest{6} +\fetdef\quartrest{7} +\fetdef\eighthrest{8} +\fetdef\sixteenthrest{9} +\fetdef\thirtysecondrest{10} +\fetdef\sixtyfourthrest{11} +\fetdef\hundredtwentyeighthrest{12} + +% accidentals +\fetdef\sharp{13} +\fetdef\natural{14} +\fetdef\flat{15} +\fetdef\flatflat{16} +\fetdef\sharpsharp{17} +\fetdef\rightparen{18} +\fetdef\leftparen{19} + +% dots +\fetdef\dot{20} +\fetdef\repeatcolon{21} + +% balls +\fetdef\brevisball{22} +\fetdef\brevisledger{23} +\fetdef\longaball{24} +\fetdef\longaledger{25} +\fetdef\wholeball{26} +\fetdef\wholeledger{27} +\fetdef\halfball{28} +\fetdef\halfledger{29} +\fetdef\quartball{30} +\fetdef\quartledger{31} + +% scripts +\fetdef\ufermata{32} +\fetdef\dfermata{33} +\fetdef\thumb{34} +\fetdef\sforzatoaccent{35} +\fetdef\staccato{36} +\fetdef\ustaccatissimo{37} +\fetdef\dstaccatissimo{38} +\fetdef\tenuto{39} +\fetdef\umarcato{40} +\fetdef\dmarcato{41} +\fetdef\ouvert{42} +\fetdef\plusstop{43} +\fetdef\upbow{44} +\fetdef\downbow{45} +\fetdef\reverseturn{46} +\fetdef\turn{47} +\fetdef\trill{48} +\fetdef\upedalheel{49} +\fetdef\dpedalheel{50} +\fetdef\upedaltoe{51} +\fetdef\dpedaltoe{52} +\fetdef\flageolet{53} +\fetdef\trilelement{54} +\fetdef\prall{55} +\fetdef\mordent{56} +\fetdef\prallprall{57} +\fetdef\prallmordent{58} +\fetdef\upprall{59} +\fetdef\downprall{60} +\fetdef\accDiscant{61} +\fetdef\accDiscantF{62} +\fetdef\accDiscantEh{63} +\fetdef\accDiscantE{64} +\fetdef\accDiscantFE{65} +\fetdef\accDiscantFEh{66} +\fetdef\accDiscantEE{67} +\fetdef\accDiscantFEE{68} +\fetdef\accDiscantEEE{69} +\fetdef\accDiscantFEEE{70} +\fetdef\accDiscantS{71} +\fetdef\accDiscantFS{72} +\fetdef\accDiscantES{73} +\fetdef\accDiscantEhS{74} +\fetdef\accDiscantFES{75} +\fetdef\accDiscantFEhS{76} +\fetdef\accDiscantEES{77} +\fetdef\accDiscantFEES{78} +\fetdef\accDiscantEEES{79} +\fetdef\accDiscantFEEES{80} +\fetdef\accDiscantSS{81} +\fetdef\accDiscantESS{82} +\fetdef\accDiscantEESS{83} +\fetdef\accDiscantEEESS{84} +\fetdef\accFreebass{85} +\fetdef\accFreebassF{86} +\fetdef\accFreebassE{87} +\fetdef\accFreebassFE{88} +\fetdef\accStdbass{89} +\fetdef\accStdbassM{90} +\fetdef\accStdbassBp{91} +\fetdef\accStdbassT{92} +\fetdef\accStdbassTp{93} +\fetdef\accBayanbass{94} +\fetdef\accBayanbassT{95} +\fetdef\accBayanbassE{96} +\fetdef\accBayanbassTE{97} +\fetdef\accBayanbassEE{98} +\fetdef\accBayanbassTEE{99} +\fetdef\accSB{100} +\fetdef\accBB{101} +\fetdef\accOldEE{102} +\fetdef\accOldEES{103} + +% flags +\fetdef\eighthflag{104} +\fetdef\sixteenthflag{105} +\fetdef\thirtysecondflag{106} +\fetdef\sixtyfourthflag{107} +\fetdef\deighthflag{108} +\fetdef\dsixteenthflag{109} +\fetdef\dthirtysecondflag{110} +\fetdef\dsixtyfourthflag{111} + +% clefs +\fetdef\altoclef{112} +\fetdef\caltoclef{113} +\fetdef\bassclef{114} +\fetdef\cbassclef{115} +\fetdef\trebleclef{116} +\fetdef\ctrebleclef{117} + +% timesig +\fetdef\fourfourmeter{118} +\fetdef\allabreve{119} +\fetdef\oldfourfourmeter{120} +\fetdef\oldallabreve{121} +\fetdef\oldthreetwometer{122} +\fetdef\oldsixfourmeter{123} +\fetdef\oldninefourmeter{124} + diff --git a/Documentation/programmer/fonts.doc b/Documentation/programmer/fonts.doc new file mode 100644 index 0000000000..287dde49b1 --- /dev/null +++ b/Documentation/programmer/fonts.doc @@ -0,0 +1,330 @@ + + % -*-LaTeX-*- + +\documentclass{article} +\def\kdots{,\ldots,} +\title{Not the Font-En-Tja font} +\author{HWN \& JCN} +\def\preMudelaExample{} +\def\postMudelaExample{} +\begin{document} +\maketitle + + +\section{Introduction} + +This document are some design notes of the Feta font, and other +symbols related to LilyPond. Feta (not an abbreviation of +Font-En-Tja) is a font of music symbols. All MetaFont sources are +original. The symbols are modelled after various editions of music, +notably \begin{itemize} \item B\"arenreiter \item Hofmeister \item +Breitkopf \item Durand \& C'ie \end{itemize} + +The best references on Music engraving are Wanske\cite{wanske} and +Ross\cite{ross} some of their insights were used. Although it is a +matter of taste, I'd say that B\"arenreiter has the finest typography +of all. + + +\section{Bezier curves for slurs} + +Objective: slurs in music are curved objects designating that notes +should fluently bound. They are drawn as smooth curves, with their +center thicker and the endings tapered. + +There are some variants: the simplest slur shape only has the width as +parameter. Then we give some suggestions for tuning the shapes. The +simple slur algorithm is used for drawing ties as well. + + + +\subsection{Simple slurs} + +Long slurs are flat, whereas short slurs look like small circle arcs. +Details are given in Wanske\cite{ross} and Ross\cite{wanske}. The +shape of a slur can be given as a Bezier curve with four control +points: + +\begin{eqnarray*} + B(t) &=& (1-t)^3c_1 +3(1-t)^2tc_2 + 3(1-t)t^2c_3 + t^3c_4. +\end{eqnarray*} + +We will assume that the slur connects two notes of the same +pitch. Different slurs can be created by rotating the derived shape. +We will also assume that the slur has a vertical axis of symmetry +through its center. The left point will be the origin. So we have +the following equations for the control points $c_1\kdots c_4$. + +\begin{eqnarray*} +c_1&=& (0,0)\\ +c_2&=& (i, h)\\ +c_3&=& (b-i, h)\\ +c_4&=& (b, 0) +\end{eqnarray*} + +The quantity $b$ is given, it is the width of the slur. The +conditions on the shape of the slur for small and large $b$ transform +to +\begin{eqnarray*} + h \to h_{\infty} , &&\quad b \to \infty\\ + h \approx r_{0} b, &&\quad b \to 0. +\end{eqnarray*} +To tackle this, we will assume that $h = F(b)$, for some kind of +$F(\cdot)$. One function that satisfies the above conditions is +$$ +F(b) = h_{\infty} \frac{2}{\pi} \arctan \left( \frac{\pi r_0}{2 +h_{\infty}} b \right). +$$ + +For satisfying results we choose $h_{\infty} = 2\cdot \texttt{interline}$ +and $r_0 = \frac 13$. + +\subsection{Height correction} + +Aside from being a smooth curve, slurs should avoid crossing +enclosed notes and their stems. + +An easy way to achieve this is to extend the slur's height, +so that the slur will curve just above any disturbing notes. + +The parameter $i$ determines the flatness of the curve. Satisfying +results have been obtained with $i = h$. + +The formula can be generalised to allow for corrections in the shape, +\begin{eqnarray*} +c_1&=& (0,0)\\ +c_2&=& (i', h')\\ +c_3&=& (b-i', h')\\ +c_4&=& (b, 0) +\end{eqnarray*} +Where +$$ +i' = h(b) (1 + i_{corr}), \quad h' = h(b) (1 + h_{corr}). +$$ + +The default values for these corrections are $0$. A $h_{corr}$ that is +negative, makes the curve flatter in the center. A $h_{corr}$ that is +positive make the curve higher. + +At every encompassed note's x position the difference $\delta _y$ +between the slur's height and the note is calculated. The greatest +$\delta _y$ is used to calculate $h_{corr}$ is by lineair extrapolation. + +However, this simple method produces satisfactory results only for +small and symmetric disturbances. + + +\subsection{Tangent method correction} + +A somewhat more elaborate\footnote{While staying in the realm +of empiric computer science} way of having a slur avoid +disturbing notes is by first defining the slur's ideal shape +and then using the height correction. The ideal shape of a +slur can be guessed by calculating the tangents of the disturbing +notes: +% a picture wouldn't hurt... +\begin{eqnarray*} + y_{disturb,l} &=& \rm{rc}_l x\\ + y_{disturb,r} &=& \rm{rc}_r + c_{3,x}, +\end{eqnarray*} +where +\begin{eqnarray*} + \rm{rc}_l &=& \frac{y_{disturb,l} - y_{encompass,1}} + {x_{disturb,l} - x_{encompass,1}}\dot x\\ + \rm{rc}_r &=& \frac{y_{encompass,n} - y_{disturb,r}} + {x_{encompass,n} - x_{disturb,r}} \dot x + c_{3,x}. +\end{eqnarray*} + +We assume that having the control points $c_2$ and $c_3$ located +on tangent$_1$ and tangent$_2$ resp. +% t: tangent +\begin{eqnarray*} + y_{tangent,l} &=& \alpha \rm{rc}_l x\\ + y_{tangent,r} &=& \alpha \rm{rc}_r + c_{3,x}. +\end{eqnarray*} + +Beautiful slurs have rather strong curvature at the extreme +control points. That's why we'll have $\alpha > 1$. +Satisfactory resulsts have been obtained with +$$ + \alpha \approx 2.4. +$$ + +The positions of control points $c_2$ and $c_3$ are obtained +by solving with the height-line +\begin{eqnarray*} + y_h &=& \rm{rc}_h + c_h. +\end{eqnarray*} + +The top-line runs through the points disturb$_{left}$ and +disturb$_{right}$. In the case that +$$ +z_{disturb,l} = z_{disturb,r}, +$$ +we'll have +$$ + \angle(y_{tangent,l},y_h) = \angle(y_{tangent,r},y_h). +$$ + + + +\section{Sizes} + +Traditional engraving uses a set of 9 standardised sizes for Staffs +(running from 0 to 8). + +We have tried to measure these (helped by a magnifying glass), and +found the staffsizes in table~\ref{fonts:staff-size}. One should note that +these are estimates, so I think there could be a measuring error of ~ +.5 pt. Moreover [Ross] states that not all engravers use exactly +those sizes. + +\begin{table}[h] + \begin{center} + \begin{tabular}{lll} +Staffsize &Numbers &Name\\ +\hline\\ +26.2pt &No. 0\\ +22.6pt &No. 1 &Giant/English\\ +21.3pt &No. 2 &Giant/English\\ +19.9pt &No. 3 &Regular, Ordinary, Common\\ +19.1pt &No. 4 &Peter\\ +17.1pt &No. 5 &Large middle\\ +15.9pt &No. 6 &Small middle\\ +13.7pt &No. 7 &Cadenza\\ +11.1pt &No. 8 &Pearl\\ + \end{tabular} + \caption{Foo} + \label{fonts:staff-size} + \end{center} +\end{table} + + + + +\section{Beams} + +\subsection{Slope} + +Traditionally, beam slopes are computed by following a large and hairy +set of rules. Some of these are talked-about in Wanske, a more +recipy-like description can be found in Ross. + +There are some problems when trying to follow these rules: +\begin{itemize} + +\item the set is not complete + +\item they are not formulated as a general rule with exceptions, but +rather as a huge case of individual rules\cite{ross} + +\item in some cases, the result is wrong or ugly (or both) + +\item they try to solve a couple of problems at a time (e.g. Ross +handles ideal slope and slope-quantisation as a paired problem) +\end{itemize} +Reading Ross it is clear that the rules presented there are certainly +not the ultimate idea of what beam(slope)s should look like, but +rather a (very much) simplified hands-on recipy for a human engraver. + +There are good reasons not to follow those rules: + +\begin{itemize} +\item One cannot expect a human engraver to solve least-squares +problems for every beam + +\item A human engravers will allways trust themselves in judging the +outcome of the applied recipy. If, in a complicated case, the result +"doesn't look good", they will ignore the rules and draw their own +beams, based on experience. + +\item The exact rules probably don't "really exist" but in the minds + of good engravers, in the form of experience +\end{itemize} + +We'll propose to do a least-squares solve. This seems to be the best +way to calculate the slope for a computerised engraver such as Lily. + +It would be nice to have some rules to catch and handle "ugly" cases, +though. In general, the slope of the beam should mirror the pitches +of the notes. If this can't be done because there simply is no +uniform trend, it would probably be best to set the slope to zero. + + +\subsection{Quantising} + +The beams should be prevented to conflict with the stafflines, +especially at small slopes. Traditionally, poor printing techniques +imposed rather strict rules for quantisation. In modern (post 1955) +music printing we see that quality has improved substantially and +obsoleted the technical justification for following some of these +strict rules, notably the avoiding of so-called wedges. + + +\subsection{Thickness and spacing} + +The spacing of double and triple beams (sixteenth and thirtysecond beams) +is the same, quadruple and quintuple (thirtyfourth and hundredtwentyeighth +beams) is wider. +All beams are equally thick. Using the layout of triple beams and the +beam-thickness $bt$ we can calculate the inter-beam spacing $ib$. + +Three beams span two interlines, including stafflines: +\begin{eqnarray*} + 2 ib + bt &=& 2 il\\ + ib &=& (2 il - bt) / 2 +\end{eqnarray*} + +We choose +\begin{eqnarray*} + bt &=& 0.48(il - st) +\end{eqnarray*} + +\subsubsection{Quadruple beams} + +If we have more than three beams they must open-up +in order to not collide with staff lines. The only valid +position that remains is for the upper beam to hang. + +\begin{eqnarray*} + 3 ib_{4+} + bt &=& 3 il\\ + ib_{4+} &=& (3 il - bt) / 3 +\end{eqnarray*} + + +\section{Layout of the source files} + +The main font (with the fixed size music glyphs) uses a the \TeX\ +logfile as a communication device. Use the specialised macros to +create and export glyphs. + +\bibliographystyle{plain} +\bibliography{engraving} + + + +\end{document} + +\begin{verbatim} +Paul Terry writes: + +Ross states that the dies (the stamps to make the symbols) come in +12 different sizes. + +>Can you tell me how big rastrals are? + +According to the Score manual: + + Rastral Size Height in millimetres + + 0 9 mm + 1 8 mm + 2 7.5 mm + 3 7 mm + 4 6.5 mm + 5 6 mm + 6 5.5 mm + +I must say, despite having been a music setter for many years, I had to +look these up - none of the publishers I work for deal in Rastral sizes +these days (they all use millimetres). diff --git a/Documentation/programmer/hacking.texi b/Documentation/programmer/hacking.texi new file mode 100644 index 0000000000..233c800216 --- /dev/null +++ b/Documentation/programmer/hacking.texi @@ -0,0 +1,851 @@ +\input texinfo @c -*-texinfo-*- +@setfilename internals.info +@settitle LilyPond internals + +@node Top, LilyPond internals, (dir), (dir) +@top + + +@menu +* LilyPond internals:: +* Overview:: +* mudela:: +* Request_engraver:: +* Graphic elements:: +* Score elements:: +* Items:: +* Spanners:: +* Future work:: +* Coding standards:: +* Making patches:: + +@end menu + +@node LilyPond internals, , Top, Top +@menu +* Overview:: Overview +* mudela:: mudela +* Request_engraver:: Request_engraver +@end menu + + +@chapter Getting involved + +Please help us make LilyPond a better program. You can help LilyPond in +several ways. Not all tasks requiring programming or understanding the +full source code. You can write to the mailing list +(@email{gnu-music-discuss@@gnu.org} for more information) + +@unnumberedsubsec Users + +Mutopia needs your help. The mutopia project is a collection of public +domain sheet music. You can help the project by entering music and +submitting. Point your browser to the +@uref{http://sca.uwaterloo.ca/Mutopia, Mutopia webpage} + +@unnumberedsubsec Font designers + +Our set of glyphs (the Feta font) is far from complete. If you know a +little MetaFont you can contribute a glyph + +@unnumberedsubsec Writers + +The documentation of LilyPond and related utilities needs a lot of work. + +@unnumberedsubsec Translators + +LilyPond is completely ready for internationalized messages, but there +are only three translations so far. + +@unnumberedsubsec Hackers + + +There are lots of possibilities of improving the program itself. There are +both small projects and big ones. Most of them are listed in the TODO +file. A interesting and very big project is writing a GUI frontend to +LilyPond. + + + +@chapter LilyPond internals + + +This documents some aspects of the internals of GNU LilyPond. Some of +this stuff comes from e-mail I wrote, some from e-mail others wrote, +some are large comments taken away from the headers. This page may be +a little incoherent. Unfortunately, it is also quite outdated. A +more thorough and understandable document is in the works. + +You should use @code{doc++} to take a peek at the sources. + +@node Overview, mudela, Top, Top +@section Overview + +GNU LilyPond is a "multi-pass" system. The different passes have been +created so that they do not depend on each other. In a later stage +some parts may be moved into libraries, or seperate programs, or they +might be integrated in larger systems. + +@table @samp + +@item Parsing: + +No difficult algorithms. The .ly file is read, and converted to a list +of @code{Scores}, which each contain @code{Music} and paper/midi-definitions. + +@item Interpreting music + +The music is walked through in time-order. The iterators which do the +walking report Music to Translators which use this information to +create elements, either MIDI or "visual" elements. The translators +form a hierarchy; the ones for paper output are Engravers, for MIDI +Performers. + +The translators swallow Music (mostly atomic gobs called Requests), +create elements, broadcast them to other translators on higher or same +level in the hierarchy: + +The stem of a voice A is broadcast to the staff which contains A, but +not to the stems, beams and noteheads of a different voice (say B) or +a different staff. The stem and noteheads of A are coupled, because +the the Note_heads_engraver broadcasts its heads, and the Stem_engraver catches +these. + +The engraver which agrees to handle a request decides whether to to +honor the request, ignore it, or merge it with other requests. Merging +of requests is preferably done with other requests done by members of +the same voicegroups (beams, brackets, stems). In this way you can put +the voices of 2 instruments in a conductor's score so they make chords +(the Beam requests of both instruments will be merged). + +@item Prebreaking + +Breakable stuff (eg. clefs and bars) are copied into pre and +postbreaks. + +@item Preprocessing + +Some dependencies are resolved, such as the direction of stems, beams, +and "horizontal" placement issues (the order of clefs, keys etc, +placement of chords in multi-voice music), + +@item Break calculation: + +The lines and horizontal positions of the columns are determined. + +@item Breaking + +Through some magical interactions with Line_of_score and Super_elem +(check out the source) the "lines" are produced. + +All other spanners can figure across which lines they are spread. If +applicable, they break themselves into pieces. After this, each piece +(or, if there are no pieces, the original spanner itself) throws out +any dependencies which are in the wrong line. + +@item Postprocesing: + +Some items and all spanners need computation after the Paper_column +positions are determined. Examples: slurs, vertical positions of +staffs. + +@item Output paper + +@end table + +@node mudela, Request_engraver, Overview, Top +@section mudela + +Most information is stored in the form of a request. In music +typesetting, the user might want to cram a lot more symbols on the +paper than actually fits. To reflect this idea (the user asks more +than we can do), the container for this data is called Request. + +In a lot of other formats this would be called an 'Event' + +@table @samp +@item @code{Barcheck_req} + Checks during music processing if start of this voice element + coincides with the start of a measure. Handy to check if you left out + some voice elts. +@item @code{Note_req} + LilyPond has to decide if the ball should be hanging left or + right. This influences the horizontal dimensions of a column, and this + is why request processing should be done before horizontal spacing. + Other voices' frivolities may cause the need for accidentals, so this + is also for the to decide. The engraver can decide on positioning based on + ottava commands and the appropriate clef. +@item @code{Rest_req} + Typeset a rest. +@item @code{Span_req} + This type of request typically results in the creation of a @code{Spanner} +@item @code{Beam_req} + Start/stop a beam. + Engraver has to combine this request with the stem_request, since the + number of flags that a stem wants to carry will determine the + number of beams. +@item @code{Dynamic} + Each dynamic is bound to one note (a crescendo spanning multiple + notes is thought to be made of two "dynamics": a start and a stop). + Dynamic changes can occur in a smaller time than the length of its + note, therefore fore each @code{Dynamic} request carries a time, measured + from the start of its note. +@end table + +@node Request_engraver, , mudela, Top +@section Request_engraver + +In the previous section the idea of Request has been explained, but +this only solves one half of the problem. The other half is deciding +which requests should be honored, which should merged with other +requests, and which should be ignored. Consider this input + +@example + + \type Staff < % chord + @{ \meter 2/4; [c8 c8] @} + @{\meter 2/4; [e8 e8] @} + > + +@end example + +Both the cs and es are part of a staff (they are in the same +Voice_group), so they should share meters, but the two [ ] pairs +should be merged. + +The judge in this "allocation" problem a set of brokers: the requests +are transmitted to so-called engravers which respond if they want to +accept a request eg, the @code{Notehead_engraver} will accept +@code{Note_req}s, and turn down @code{Slur_req}s. If the Music_iterator +cannot find a engraver that wants the request, it is junked (with a +warning message). + +After all requests have been either assigned, or junked, the Engraver +will process the requests (which usually means creating an @code{Item} +or @code{Spanner}). If a @code{Request_engraver} creates something, it +tells the enclosing context. If all items/spanners have been created, +then each Engraver is notified of any created Score_element, via a +broadcasting system. + +@unnumberedsubsec example: + +@example + + c4 + +@end example + +produces: + +@example + + Note_request (duration 1/4) + Stem_request (duration 1/4) + +@end example + +Note_request will be taken by a @code{Notehead_engraver}, stem_request +will be taken by a @code{Stem_beam_engraver}. @code{Notehead_engraver} +creates a @code{Notehead}, @code{Stem_beam_engraver} creates a +@code{Stem}. Both announce this to the Staff_engraver. Staff_engraver +will tell @code{Stem_beam_engraver} about the @code{Notehead}, which +will add the @code{Notehead} to the @code{Stem} it just created. + +To decide on merging, several engravers have been grouped. Please +check @file{init/engraver.ly}. + + + +@node Graphic elements, , , Top +@section Graphic elements + + +Music notation is composed of a sets of interrelated glyphs. In +Lilypond every glyph usually is represented by one object, a so-called +Graphic Object. The primary relations between graphic objects involve +positions: + +@itemize +@item consecutive notes are printed left to right, grouped in a staff +@item simultaneous notes are horizontally aligned (internally grouped in +a paper column). +@item the staccato mark is horizontally centered on the note it applies +to. +@end itemize + +The abstract encoding of such relations is done with the concept +@dfn{reference point}. The reference point (in X direction) of the +staccato mark is the note it applies to. The (X) position of the +staccato mark is stored relative to the position of the note head. This +means that the staccato will always maintain a fixed offset wrt to the +note head, whereever the head is moved to. + +In the same vein, all notes on a staff have their Y positions stored +relative to an abstract object called Axis_group_spanner. If the +Axis_group_spanner of one staff is moved, the absolute Y positions of +all objects in that spanner change along, in effect causing the staff +and all its contents to move as a whole. + +Each graphic object stores a pointer and an relative offset for each +direction: one for the X-axis, one for the Y-axis. For example, the X +parent of a Note_head usually is a Note_column. The X parent of a +Note_column usually is either a Collision or a Paper_column. The X +parent of a Collision usually is a Paper_column. If the Collision +moves, all Note_heads that have that Collision as parent also move, but +the absolute position of the Paper_column does not change. + +To build a graphical score with Graphic_elements, conceptually, one +needs to have one Root object (in Lilypond: Line_of_score), and +recursively attach objects to the Root. However, due to the nature +of the context selection mechanisms, it turns out to be more +advantageous to construct the tree the other way around: first small +trees (note heads, barlines etc.) are created, and these are +subsequently composed into larger trees, which are finally hung on a +Paper_column (in X direction) or Line_of_score (in Y direction). + +The structure of the X,Y parent relations are determined by the +engravers and notation contexts: + +The most important X-axis parent relation depends on the timing: notes +that come earlier are attached to Paper_column that will be positioned +more to the left. + +The most important Y-axis relation depends on containment of contexts: +notes (created in a Thread or Voice context) are put in the staff where +the originating context lives in. + +Graphical_axis_groups are special graphic objects, that are designed to +function as a parent. The size of a Graphical_axis_groups group is the +union of its children. + +@node Score elements, , , Top + +Besides relative positions there are lots of other relations between +elements. Lilypond does not contain other specialized relation +management (Like the relative positioning code). In stead, objects can +be connected through dependencies, which sets the order in which objects +are to be processed. + +Example: the direction of a beamed stem should equal the direction of +the beam. When the stem is a added to the beam, a dependency on the +beam is set in the stem: this means that @code{Beam::do_pre_processing +()} (which does various direction related things) will be called before +@code{Stem::do_pre_processing ()}. + +The code that manages dependencies resides in the class +@code{Score_element}, a derived class of @code{Graphical_element}. The +bulk of the code handles line breaking related issues. + +To sketch the problems with line breaking: suppose a slur spans a line +break, +@example + +c4( c'''' c | \break d d )d + +@end example +In this case, the slur will appear as two parts, the first part spanning +the first three notes (the @code{c}s), the second spanning the last +three (the @code{d}s). Within Lilypond this is modeled as breaking the +slur in parts: from the Original slur, two new clones of the old slur +are made. Initially both clones depend on the six notes. After the +hairy code in Score_element, Spanner and Item which does substitutions +in sets of dependencies, the first clone depends on the first three +notes, the second on the last three. + +The major derived classes of Score_element are Item and Spanner. +An item has one horizontal position. A spanner hangs on two items. + +@node Items, , , Top +@section Items + + + +An item is a score element that is associated with only one +Paper_column. Examples are note heads, clefs, sup and superscripts, etc. +Item is a derived class of Score_element. + +The shape of an item is known before the break calculations, and line +spacing depends on the size of items: very wide items need more space +than very small ones. + +An additional complication is the behavior of items at linebreaks. For +example, when you do a time signature change, you get only one symbol. +If it occurs at a linebreak, the new time signature must be printed both +before and after the linebreak. Other `breakable symbols' such as +clefs, and bar lines also exhibit this behavior. + +if a line of music is broken, the next line usually gets a clef. So in +TeX terms, the clef is a postbreak. The same thing happens with meter +signs: Normally the meter follows the bar. If a line is broken at that +bar, the bar along with the meter stays on the "last" line, but the next +line also gets a meter sign after the clef. To support this, +breakable items are generated in the three versions: original +(unbroken), left (before line break) and right (after line break). +During the line spacing, these versions are used to try how the spacing +of a line works out. + +Once the definitive spacing is determined, dependencies (and various +other pointers) are substituted such that all dependencies point at the +active items: either they point at the original, or they point at left +and right. + +@node Spanners, , , Top +@section Spanners + +Spanners are symbols that are of variable shape, eg. Slurs, beams, etc. +Spanners is a derived class of Score_element. + +The final shape can only be determined after the line breaking process. +All spanners are spanned on two items, called the left and right +boundary item. The X reference point is the left boundary item. + + +@node Future work, , , Top +@section Future work + +There are plans to unify Spanner and Item, so there will no longer be +such a clear distinction between the two. Right now, Score_elements are +always either Item or either Spanner. + +Most of the properties of a graphic object are now member variables of +the classes involved. To offer configurability, we want to move these +variables to scheme (GUILE) variables, and no longer use C++ code to +calculate them, but use Scheme functions. + +@node Coding standards, , , Top + +@chapter CodingStyle - standards while programming for GNU +LilyPond + +Functions and methods do not return errorcodes. + + +@unnumberedsubsec Languages + +C++ and Python are preferred. Perl is not. Python code should use an +indent of 8, using TAB characters. + +@unnumberedsubsec Filenames + +Definitions of classes that are only accessed via pointers +(*) or references (&) shall not be included as include files. + +filenames + +@example + ".hh" Include files + ".cc" Implementation files + ".icc" Inline definition files + ".tcc" non inline Template defs +@end example + +in emacs: + +@example + (setq auto-mode-alist + (append '(("\\.make$" . makefile-mode) + ("\\.cc$" . c++-mode) + ("\\.icc$" . c++-mode) + ("\\.tcc$" . c++-mode) + ("\\.hh$" . c++-mode) + ("\\.pod$" . text-mode) + ) + auto-mode-alist)) +@end example + + +The class Class_name_abbreviation is coded in @file{class-name-abbr.*} + +@unnumberedsubsec Indentation + +Standard GNU coding style is used. In emacs: + +@example + (add-hook 'c++-mode-hook + '(lambda() (c-set-style "gnu") + ) + ) +@end example + +If you like using font-lock, you can also add this to your @file{.emacs}: + +@example + (setq font-lock-maximum-decoration t) + (setq c++-font-lock-keywords-3 + (append + c++-font-lock-keywords-3 + '(("\\b\\([a-zA-Z_]+_\\)\\b" 1 font-lock-variable-name-face) + ("\\b\\([A-Z]+[a-z_]+\\)\\b" 1 font-lock-type-face)) + )) +@end example + +@unnumberedsubsec Classes and Types + +@example + This_is_a_class +@end example + +@unnumberedsubsec Members + +@example + Class::member () + Type Class::member_type_ + Type Class::member_type () +@end example + +the @code{type} is a Hungarian notation postfix for @code{Type}. See below + +@unnumberedsubsec Macros + +Macros should be written completely in uppercase + +The code should not be compilable if proper macro declarations are not +included. + +Don't laugh. It took us a whole evening/night to figure out one of +these bugs, because we had a macro that looked like +@code{DECLARE_VIRTUAL_FUNCTIONS ()}. + +@unnumberedsubsec Broken code + +Broken code (hardwired dependencies, hardwired constants, slow +algorithms and obvious limitations) should be marked as such: either +with a verbose TODO, or with a short "ugh" comment. + +@unnumberedsubsec Comments + +The source is commented in the DOC++ style. Check out doc++ at +@uref{http://www.zib.de/Visual/software/doc++/index.html} + +@example + + /* + C style comments for multiline comments. + They come before the thing to document. + [...] + */ + + /** + short description. + Long class documentation. + (Hungarian postfix) + + TODO Fix boring_member () + */ + class Class @{ + /** + short description. + long description + */ + + Data data_member_; + + /** + short memo. long doco of member () + @@param description of arguments + @@return Rettype + */ + Rettype member (Argtype); + + /// memo only + boring_member () @{ + data_member_ = 121; // ugh + @} + @}; + +@end example + + +Unfortunately most of the code isn't really documented that good. + +@unnumberedsubsec Members (2) + +Standard methods: + +@example + + ///check that *this satisfies its invariants, abort if not. + void OK () const + + /// print *this (and substructures) to debugging log + void print () const + + /** + protected member. Usually invoked by non-virtual XXXX () + */ + virtual do_XXXX () + + /**add some data to *this. + Presence of these methods usually imply that it is not feasible to this + via a constructor + */ + add (..) + + /// replace some data of *this + set (..) + +@end example + +@unnumberedsubsec Constructor + +Every class should have a default constructor. + +Don't use non-default constructors if this can be avoided: + +@example + + Foo f(1) + +@end example + +is less readable than + +@example + + Foo f; + f.x = 1 + +@end example + +or + +@example + + Foo f(Foo_convert::int_to_foo (1)) + +@end example + +@unnumberedsec Hungarian notation naming convention + +Proposed is a naming convention derived from the so-called +@emph{Hungarian Notation}. Macros, @code{enum}s and @code{const}s are all +uppercase, with the parts of the names separated by underscores. + +The hungarian notation is to be used when variables are not declared +near usage (mostly in member variables and functions). + +@unnumberedsubsec Types + +@table @samp +@item @code{byte} + unsigned char. (The postfix _by is ambiguous) +@item @code{b} + bool +@item @code{bi} + bit +@item @code{ch} + char +@item @code{f} + float +@item @code{i} + signed integer +@item @code{str} + string class +@item @code{sz} + Zero terminated c string +@item @code{u} + unsigned integer +@end table + +@unnumberedsubsec User defined types + +@example + + /** Slur blah. blah. + (slur) + */ + class Slur @{@}; + Slur* slur_p = new Slur; + +@end example + +@unnumberedsubsec Modifiers + +The following types modify the meaning of the prefix. +These are preceded by the prefixes: + +@table @samp +@item @code{a} + array +@item @code{array} + user built array. +@item @code{c} + const. Note that the proper order is @code{Type const} + i.s.o. @code{const Type} +@item @code{C} + A const pointer. This would be equivalent to @code{_c_l}, but since any + "const" pointer has to be a link (you can't delete a const pointer), + it is superfluous. +@item @code{l} + temporary pointer to object (link) +@item @code{p} + pointer to newed object +@item @code{r} + reference +@end table + +@unnumberedsubsec Adjective + +Adjectives such as global and static should be spelled out in full. +They come before the noun that they refer to, just as in normal english. + +@example + +foo_global_i: a global variable of type int commonly called "foo". + +@end example + +static class members do not need the static_ prefix in the name (the +Class::var notation usually makes it clear that it is static) + +@table @samp +@item @code{loop_i} + Variable loop: an integer +@item @code{u} + Temporary variable: an unsigned integer +@item @code{test_ch} + Variable test: a character +@item @code{first_name_str} + Variable first_name: a String class object +@item @code{last_name_ch_a} + Variable last_name: a @code{char} array +@item @code{foo_i_p} + Variable foo: an @code{Int*} that you must delete +@item @code{bar_i_l} + Variable bar: an @code{Int*} that you must not delete +@end table + +Generally default arguments are taboo, except for nil pointers. + +The naming convention can be quite conveniently memorised, by +expressing the type in english, and abbreviating it + +@example + + static Array foo + +@end example + +@code{foo} can be described as "the static int-pointer user-array", so you get + +@example + + foo_static_l_arr + +@end example + + +@unnumberedsec Miscellaneous + +For some tasks, some scripts are supplied, notably creating patches, a +mirror of the website, generating the header to put over cc and hh +files, doing a release. + +Use them. + +@node Making patches, , , Top + + +@unnumberedsec name + + +PATCHES - track and distribute your code changes + +This page documents how to distribute your changes to GNU lilypond + +We would like to have unified context diffs with full pathnames. A +script automating supplied with Lily. + +Distributing a change normally goes like this: + +@itemize @bullet +@item make your fix/add your code +@item Add changes to CHANGES, and add yourself to Documentation/topdocs/AUTHORS.texi +@item generate a patch, +@item e-mail your patch to one of the mailing lists + gnu-music-discuss@@gnu.org or bug-gnu-music@@gnu.org +@end itemize + +Please do not send entire files, even if the patch is bigger than the +original. A patch makes it clear what is changed, and it won't +overwrite previous (not yet released) changes. + +@unnumberedsec Generating a patch + +Simple version: run + +@example + make -C lilypond-x.y.z/ distclean + make -C lilypond-x.y.z.NEW/ distclean + diff -urN lilypond-x.y.z/ lilypond-x.y.z.NEW/ +@end example + +Complicated (but automated) version: + +In @file{VERSION}, set MY_PATCH_LEVEL: + +@example + + VERSION: + ... + MY_PATCH_LEVEL=jcn1 + +@end example + +In @file{CHANGES}, enter a summary of changes: + +@example + pl 0.1.73.jcn1 + - added PATCHES.texi +@end example + +Then, from the top of Lily's source tree, type + +@example + make release +@end example + +These handy python scripts assume a directory structure which looks +like: + +@example + + lilypond -> lilypond-x.y.z # symlink to development directory + lilypond-x.y.z/ # current development + patches/ # patches between different releases + releases/ # .tar.gz releases + +@end example + +(Some scripts also assume this lives in @file{$HOME/usr/src}). + + +@unnumberedsec Applying patches + + +If you're following LilyPond development regularly, you probably want to +download just the patch for each subsequent release. +After downloading the patch (into the patches directory, of course), simply +apply it: + +@example + + gzip -dc ../patches/lilypond-0.1.74.diff.gz | patch -p1 -E + +@end example + +and don't forget to make automatically generated files: + +@example + + autoconf footnote(patches don't include automatically generated files, + i.e. file(configure) and files generated by file(configure).) + + configure + +@end example + + +@bye + + diff --git a/Documentation/programmer/lilypond-overview.doc b/Documentation/programmer/lilypond-overview.doc new file mode 100644 index 0000000000..a408a9e8eb --- /dev/null +++ b/Documentation/programmer/lilypond-overview.doc @@ -0,0 +1,743 @@ +%-*-LaTeX-*- + +\documentclass{article} +\usepackage{a4} +\def\postMudelaExample{\setlength{\parindent}{1em}} +\title{LilyPond, a Music Typesetter} +\author{HWN} +\usepackage{musicnotes} +\usepackage{graphics} + + +\begin{document} +\maketitle + +[THIS IS WORK IN PROGRESS. THIS IS NOT FINISHED] + +% -*-LaTeX-*- +\section{Introduction} + +The Internet has become a popular medium for collaborative work on +information. Its success is partly due to its use of simple, text-based +formats. Examples of these formats are HTML and \LaTeX. Anyone can +produce or modify such files using nothing but a text editor, they are +easily processed with run-of-the-mill text tools, and they can be +integrated into other text-based formats. + +Software for processing this information and presenting these formats +in an elegant form is available freely (Netscape, \LaTeX, etc.). +Ubiquitousness of the software and simplicity of the formats have +revolutionised the way people publish text-based information +nowadays. + +In the field of performed music, where the presentation takes the form +of sheet music, such a revolution has not started yet. Let us review +some alternatives that have been available for transmitting sheet +music until now: +\begin{itemize} +\item MIDI\cite{midi}. This format was designed for interchanging performances + of music; one should think of it as a glorified tape recorder + format. It needs dedicated editors, since it is binary. It does + not provide enough information for producing musical scores: some of + the abstract musical content of what is performed is thrown away. + +\item PostScript\cite{Postscript}. This format is a printer control + language. Printed musical scores can be transmitted in PostScript, + but once a score is converted to PostScript, it is virtually + impossible to modify the score in a meaningful way. + +\item Formats for various notation programs. Notation programs either + work with binary formats (e.g., NIFF\cite{niff-web}), need specific + platforms (e.g., Sibelius\cite{sibelius}), are proprietary or + non-portable tools themselves (idem), produce inadequate output + (e.g., MUP\cite{mup}), are based on graphical content (e.g., + MusixTeX\cite{musixtex1}), limit themselves to specific subdomains + (e.g., ABC\cite{abc2mtex}), or require considerable skill and + knowledge to use (e.g., SCORE\cite{score}) + +\item SMDL\cite{smdl-web}. This is a very rich ASCII format, that is + designed for storing many types of music. Unfortunately, there is + no implementation of a program to print music from SMDL available. + Moreover, SMDL is so verbose, that it is not suitable for human + production. + +\item TAB\cite{tablature-web}. Tab (short for tablature) is a popular + format, for interchanging music over e-mail, but it can only be used + for guitar music. +\end{itemize} + +In summary, sheet music is not published and edited on a wide scale +across the internet because no format for music +interchange exists that is: +\begin{itemize} +\item open, i.e., with publically available specifications. +\item based on ASCII, and therefore suitable for human consumption and + production. +\item rich enough for producing publication quality sheet music from + it. +\item based on musical content (unlike, for example, PostScript), and + therefore suitable for making modifications. +\item accompanied by tools for processing it that are freely available + across multiple platforms. +\end{itemize} + + +With the creation of LilyPond, we have tried to create both a +convenient format for storing sheet music, and a portable, +high-quality implementation of a compiler, that compiles the input +into a printable score. You can find a small example of LilyPond +input along with output in Figure~\ref{fig:intro-fig}. +% +\begin{figure}[htbp] + \begin{center} +\begin[verbatim]{mudela} + \score { + \notes + \context GrandStaff < + \transpose c'' { c4 c4 g4 g4 a4 a4 g2 } + { \clef "bass"; c4 c'4 + \context Staff f'4 c'4 e'4 c'4 } + > + \paper { + linewidth = -1.0\cm ; + } + } +\end{mudela} + \caption{A small example of LilyPond input} + \label{fig:intro-fig} + \end{center} +\end{figure} +% + + +The input language encodes musical events (such as notes and rests) on +the basis of their time-ordering. For example, the grammar includes +constructs that specify that notes start simultaneous and that notes +are to be played in sequence. In this encoding some context that is +present in sheet music is lost. + +The compiler reconstructs the notation from the encoded music. Its +operation comprises four different steps (see +Figure~\ref{fig:intro-steps}). + +\begin{description} +\item[Parsing] During parsing, the input is converted in a syntax tree. + +\item[Interpreting] In the \emph{interpreting} step, it is determined + which symbols have to be printed. Objects that correspond to + notation (\emph{Graphical objects}) are created from the syntax tree + in this phase. Generally speaking, for every symbol printed there is + one graphical object. These objects are incomplete: their position + and their final shape is unknown. + + The context that was lost by encoding the input in a language is + reconstructed during this conversion. +\item[Formatting] The next step is determing where symbols are to be + placed, this is called \emph{formatting}. +\item[Outputting] + Finally, all Graphical objects are outputted as PostScript or \TeX\ code. +\end{description} + +\def\staffsym{\vbox to 16pt{ + \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip + \vfil + \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip + \vfil + \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip + \vfil + \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip + \vfil + \hbox{\vrule width 1cm depth .2pt height .2pt}\nointerlineskip +}} + +\def\vspacer{\vbox to 20pt{\vss}} +\begin{figure}[h] +\def\spacedhbox#1{\hbox{\ #1\ }} +\begin{eqnarray*} + {\spacedhbox{Input}\atop \hbox{\texttt{\{c8 c8\}}}} {\spacedhbox{Parsing}\atop\longrightarrow} + {\spacedhbox{Syntax tree}\atop\spacedhbox{\textsf{Sequential(Note,Note)}}} + {\spacedhbox{Interpreting}\atop\longrightarrow}\\ + \vspacer\\ + {\spacedhbox{Graphic objects}\atop\spacedhbox{\texttrebleclef \textquarterhead\texteighthflag\textquarterhead\texteighthflag \staffsym }} + {\spacedhbox{Formatting}\atop\longrightarrow} + {\spacedhbox{Formatted objects}\atop\hbox{ + \mudela{c''8 c''8} + }}\\ +\vspacer\\ + {\spacedhbox{Outputting}\atop\longrightarrow} + {\spacedhbox{PostScript code}\atop\hbox{\texttt{\%!PS-Adobe}\ldots}} +\end{eqnarray*} + \caption{Parsing, Interpreting, Formatting and Outputting} + \label{fig:intro-steps} +\end{figure} + + +The second step, the interpretation phase of the compiler, can be +manipulated as a separate entity: the interpretation process is +composed of many separate modules, and the behaviour of the modules is +parameterised. By recombining these interpretation modules, +and changing parameter settings, the same piece of music can be +printed differently, as is shown in Figure~\ref{fig:intro-interpret}. + +This makes it easy to extend the program. Moreover, this enables the +same music to be printed in different versions, e.g., in a conductors +score and in extracted parts. + + +\begin{figure}[h] + \begin{center} + \begin{mudela} + \score { + \notes + \context GrandStaff < + \transpose c'' { c4 c4 g4 g4 a4 a4 g2 } + { \clef "bass"; c4 c'4 + \context Staff f'4 c'4 e'4 c'4 } + > + \paper { + linewidth = -1.0\cm ; + \translator { + \VoiceContext + \remove "Stem_engraver"; + } + \translator { + \StaffContext + numberOfStaffLines = 3; + } + } + } + \end{mudela} + \caption{The interpretation phase can be manipulated: the same + music as in Figure~\ref{fig:intro-fig} is interpreted + differently: three staff lines and no stems.} + \label{fig:intro-interpret} + \end{center} +\end{figure} + + + +\section{Preliminaries} + +To understand the rest of the article, it is necessary to know +something about music notation and music typography. Since both +communicate music, we will explain some characteristics of instruments +and western music that motivate some notational constructs. + +\subsection{Music} + +Music notation is meant to be read by human performers. They sing or +play instruments that can produce sounds of different pitches. These +sounds are called \emph{notes}. Additionally, the sounds can be +articulated in differents ways, e.g., staccato (short and separated) +or legato (fluently bound together). The loudness of the notes can +also be varied. Changes in loudness are called \emph{dynamics}. + +Silence is also an element of music. The musical terminology for +silence within music is \emph{rest}. + +The basic unit of pitch is the \emph{octave}. The octave corresponds +to a frequency ratio of 1:2. For example the pitch denoted by a' +(frequency: 440 hertz) is one octave lower than a'' (frequency: 880 +hertz). Various instruments have a limited \emph{pitch range}, for +example, a trumpet has a range of about 2.5 octaves. Not all +instruments have ranges in the same register: a tuba also has a range +of 2.5 octaves, but the range of the tuba is much lower. + +Musicology has a confusing mix of relative and absolute measures for +pitches: the term `octave' refers to both a difference between two +pitches (the frequency ratio of 1:2), and to a range of pitches. For +example, the term `[eengestreept] octave' refers to the pitch range +between 261.6 Hz and 523.3 Hz. + + +The octave is divided into smaller pitch steps. In modern western +music, every octave is divided into twelve approximately equidistant +pitch steps, and each step is called a \emph{semitone}. Usually, the +pitches in a musical piece come from a smaller subset of these twelve +possible pitches. This smaller subset along with the musical +functions fo the pitches is called the +\emph{tonality}\footnote{Tonality also refers to the relations between + and functions of certain pitches. Since these do not have any + impact on notation, we ignore this} of the piece. + + +The standard tonality that forms the basis of music notation +(the key of C major) is a set of seven pitches within every octave. +Each of these seven is denoted by a name. In English, these are names +are (in rising pitch) denoted by c, d, e, f, g, a and b. Pitches that +are a semitone higher or lower than one of these seven can be +represented by suffixing the name with `sharp' or `flat' +respectively (this is called an \emph{chromatic alteration}). + +A pitch therefore can be fully specified by a combination of the +octave number, the note name and a chromatic alteration. +Figure~\ref{fig:intro-pitches} shows the relation between names and +frequencies. + + + + +\begin{figure}[h] + \begin{center} + [te doen] + \end{center} + \caption{Pitches in western music. The octave number is denoted + by a superscript.} + \label{fig:intro-pitches} +\end{figure} + + +Many instruments can produce more than one note at the same time, e.g. +pianos and guitars. When more notes are played simultaneously, they +form a so-called \emph{chord}. + +The unit of duration is the \emph{beat}. When playing, the tempo is +determined by setting the number of beats per minute. In western +music, beats are often stressed in a regular pattern: for example +Waltzes have a stress pattern that is strong-weak-weak, i.e. every +note that starts on a `strong' beat is louder and has more pronounced +articulation. This stress pattern is called \emph{meter}. + +\subsection{Music notation} + +Music notation is a system that tries to represent musical ideas +through printed symbols. Music notation has no precise definition, +but most conventions have described in reference manuals on music +notation\cite{read-notation}. + +In music notation, sounds and silences are represented by symbols that +are called note and rest respectively.\footnote{These names serve a + double purpose: the same terms are used to denote the musical + concepts.} The shape of notes and rests indicates their duration +(See figure~\ref{noteshapes}) relative to the whole note. + + +\begin{figure}[h] + \begin{center} +\begin{mudela} + \score { + \notes \transpose c''{ c\longa*1/4 c\breve*1/2 c1 c2 c4 c8 c16 c32 c64 } + \paper { + \translator { + \StaffContext + \remove "Staff_symbol_engraver"; + \remove "Time_signature_engraver"; +% \remove "Bar_engraver"; + \remove "Clef_engraver"; + } +linewidth = -1.; + } +} +\end{mudela} +\begin{mudela} + \score { + \notes \transpose c''\context Staff { r\longa*1/4 r\breve*1/2 r1 r2 r4 r8 r16 r32 r64 } + \paper { + \translator { + \StaffContext + \remove "Staff_symbol_engraver"; + \remove "Time_signature_engraver"; +% \remove "Bar_engraver"; + \remove "Clef_engraver"; + } + linewidth = -1.; + } +} +\end{mudela} + \caption{Note and rest shapes encode the length. At the top notes + are shown, at the bottom rests. From left to right a quadruple + note (\emph{longa}), double (\emph{breve}), whole, half, + quarter, eigth, sixteenth, thirtysecond and sixtyfourth. Each + note has half of the duration of its predecessor.} + \label{fig:noteshapes} +\end{center} +\end{figure} + + +Notes are printed in a grid of horizontal lines called \emph{staff} to +denote their pitch: each line represents the pitch of from the +standard scale (c, d, e, f, g, a, b). The reference point is the +\emph{clef}, eg., the treble clef marks the location of the $g^1$ +pitch. The notes are printed in their time order, from left to right. + + +\begin{figure}[h] + \begin{center} + \begin{mudela} + \score { \notes { + a4 b c d e f g a \clef bass; + a4 b c d e f g a \clef alto; + a4 b c d e f g a \clef treble; + } + \paper { linewidth = 15.\cm; } + } + \end{mudela} + \caption{Pitches ranging from $a, b, c',\ldots a'$, in different + clefs. From left right the bass, alto and treble clef are + featured.} + \label{fig:pitches} + \end{center} +\end{figure} + +The chromatic alterations are indicated by printing a flat sign or a +sharp sign in front of the note head. If these chromatic alterations +occur systematically (if they are part of the tonality of the piece), +then this indicated with a \emph{key signature}. This is a list of +sharp/flat signs which is printed next to the clef. + +Articulation is notated by marking the note shapes wedges, hats and +dots all indicate specific articulations. If the notes are to be +bound fluently (legato), the note shapes are encompassed by a smooth +curve called \emph{slur}, + +\begin{figure}[h] + \begin{center} + \begin{mudela} + c'4-> c'4-. g'4 ( b'4 ) g''4 + \end{mudela} + \caption{Some articulations. From left to right: extra stress + (\emph{marcato}), short (staccato), slurred notes (legato).} + \label{fig:articulation} + \end{center} +\end{figure} + + + +Dynamics are notated in two ways: absolute dynamics are indicated by +letters: \textbf{f} (from Italian ``forte'') stands for loud, +\textbf{p} (from Italian ``piano'') means soft. Gradual changes in +loudness are notated by (de)crescendos. These are hairpin like shapes +below the staff. + +\begin{figure}[h] + \begin{center} + \begin{mudela} + g'4\pp \< g'4 \! g'4 \ff \> g'4 g' \! g'\ppp + \end{mudela} + \caption{Dynamics: start very soft (pp), grow to loud (ff) and + decrease to extremely soft (ppp)} + \label{fig:dynamics} + \end{center} +\end{figure} + + +The meter is indicated by barlines: every start of the stress pattern +is preceded by a vertical line, the \emph{bar line}. The space +between two bar lines is called measure. It is therefore the unit of +the rhythmic pattern. + +The time signature also indicates what kind of rhythmic pattern is +desired. The time signature takes the form of two numbers stacked +vertically. The top number is the number of beats in one measure, the +bottom number is the duration (relative to the whole note) of the note +that takes one beat. Example: 2/4 time signature means ``two beats +per measure, and a quarter note takes one beat'' + +Chords are written by attaching multiple note heads to one stem. When +the composer wants to emphasize the horizontal relationships between +notes, the simultaneous notes can be written as voices (where every +note head has its own stem). A small example is given in +Figure~\ref{fig:simultaneous}. + +\begin{figure}[h] + \begin{center} + \begin{mudela} + \relative c'' {\time 2/4; + \context Staff < \context Voice = VA{ + \stemdown + c4 d + b16 b b b b b b b } + \context Voice = VB { + \stemup e4 f g8 g4 g8 } > + } + \end{mudela} + \caption{Notes sounding together. Chord notation (left, before + the bar line) emphasizes vertical relations, voice notation + emphasizes horizontal relations. Separate voices needn't have + synchronous rhythms (third measure). + } + \label{fig:simultaneous} + \end{center} +\end{figure} + +Separate voices do not have to share one rhythmic pattern---this is +also demonstrated in Figure~\ref{fig:simultaneous}--- they are in a sense%vaag +independent. A different way to express this in notation, is by +printing each voice on a different staff. This is customary when +writing for piano (both left and right hand have a staff of their own) +and for ensemble (every instrument has a staff of its own). + + + +\subsection{Music typography} + +Music typography is the art of placing symbols in esthetically +pleasing configuration. Little is explicitly known about music +typography. There are only a few reference works +available\cite{ross,wanske}. Most of the knowledge of this art has +been transmitted verbally, and was subsequently lost. + +The motivation behind choices in typography is to represent the idea +as clearly as possible. Among others, this results in the following +guidelines: +\begin{itemize} +\item The printed score should use visual hints to accentuate the + musical content +\item The printed score should not contain distracting elements, such + as large empty regions or blotted regions. +\end{itemize} + +An example of the first guideline in action is the horizontal spacing. +The amount of space following a note should reflect the duration of +that note: short notes get a small amount of space, long notes larger +amounts. Such spacing constraints can be subtle, for the +``amount of space'' is only the impression that should be conveyed; there +has to be some correction for optical illusions. See +Figure~\ref{fig:spacing}. + +\begin{figure}[h] + \begin{center} + \begin{mudela} + \relative c'' { \time 3/4; c16 c c c c8 c8 | f4 f, f' } + \end{mudela} + \caption{Spacing conveys information about duration. Sixteenth + notes at the left get less space than quarter notes in the + middle. Spacing is ``visual'', there should be more space + after the first note of the last measure, and less after second. } + \label{fig:spacing} + \end{center} +\end{figure} + +Another example of music typography is clearly visible in collisions. +When chords or separate voices are printed, the notes that start at +the same time should be printed aligned (ie., with the same $x$ +position). If the pitches are close to each other, the note heads +would collide. To prevent this, some notes (or note heads) have to be +shifted horizontally. An example of this is given in +Figure~\ref{fig:collision}. +\begin{figure}[h] + \begin{center} + [todo] + \caption{Collisions} + \label{fig:collision} + \end{center} +\end{figure} + +\bibliographystyle{hw-plain} +\bibliography{engraving,boeken,colorado,computer-notation,other-packages} + +\section{Requirements} + + +\section{Approach} + +\subsection{Input} + +The input format consists of combining a symbolic representation of +music with style sheet that describes how the symbolic presentation +can converted to notation. The symbolic representation is based on a +context free language called \textsf{music}. Music is a recursively +defined construction in the input language. It can be constructed by +combining lists of \textsf{music} sequentially or parallel or from +terminals like notes or lyrics. + +The grammar for \textsf{music} is listed below. It has been edited to +leave out the syntactic and ergonomic details. + +\begin{center} + \begin{tabular}{ll} +Music: & SimpleMusic\\ + & $|$ REPEATED int Music ALTERNATIVE MusicList\\ + & $|$ SIMULTANEOUS MusicList\\ + & $|$ SEQUENTIAL MusicList\\ + & $|$ CONTEXT STRING '=' STRING Music\\ + & $|$ TIMES int int Music \\ + & $|$ TRANSPOSE PITCH Music \\ +SimpleMusic: & $|$ Note\\ + & $|$ Lyric\\ + & $|$ Rest\\ + & $|$ Chord\\ + & $|$ Command\\ +Command: & METERCHANGE\\ + & $|$ CLEFCHANGE\\ + &$|$ PROPERTY STRING '=' STRING\\ +Chord: &PitchList DURATION\\ +Rest: &REST DURATION\\ +Lyric: &STRING DURATION\\ +Note: &PITCH DURATION\\ +\end{tabular} +\end{center} + +The terminals are both purely musical concepts that have a duration, +and take a non-zero amount of musical time, like notes and lyrics, and +commands that behave as if they have no duration.\footnote{The + PROPERTY command is a generic mechanism for controlling the + interpretation, i.e. the musical style sheets. See [forward ref]} + +The nonterminal productions can +\begin{itemize} +\item Some productions combine multiple elements: one can specify that + element are to be played in sequence, simultaneously or repetitively. +\item There are productions for transposing music, and for dilating + durations of music: the TIMES production can be used to encode a + triplet.\footnote{A triplet is a group of three notes marked by a + bracket, that are played 3/2 times faster.} +\item + There are productions that give directions to the interpretation + engine (the CONTEXT production) +\end{itemize} + + +\section{Context in notation} + +Music notation relies heavily on context. Notational symbols do not +have meaning if they are not surrounded by other context elements. In +this section we give some examples how the reader uses this context do +derive meaning of a piece of notation. We will focus on the prime +example of context: the staff. + +A staff is the grid of five horizontal lines, but it contains more components : +\begin{itemize} +\item A staff can have a key signature (printed at the left) +\item A staff can have a time signature (printed at the left) +\item A staff has bar lines +\item A staff has a clef (printed at the left) +\end{itemize} + +It is still possible to print notes without these components, but one +cannot determine the meaning of the notes. +\begin{mudela} +\score{ +\notes \relative c' { \time 2/4; g'4 c,4 a'4 f4 e c d2 } +\paper { + linewidth = -1.; + \translator { + \StaffContext + \remove "Time_signature_engraver"; +% \remove "Bar_engraver"; + \remove "Staff_symbol_engraver"; + \remove "Clef_engraver"; + \remove "Key_engraver"; + } + } +} +\end{mudela} + +As you can see, you can still make out the general form of the melody +and the rhythm that is to be played, but the notation is difficult to +read and the musical information is not complete. The stress +pattern in the notes can't be deduced from this output. For this, we +need a time signature. Adding barlines helps with finding the strong +and weak beats. +\begin{mudela} +\score { + \notes \relative c' { \time 2/4; g'4 c,4 a'4 f4 e c d2 } + \paper{ + linewidth = -1.; +\translator{ + \StaffContext + \remove "Staff_symbol_engraver"; + \remove "Clef_engraver"; + \remove "Key_engraver";} + } + } +\end{mudela} + +It is impossible to deduce the exact pitch of the notes. One needs a +clef to do so. Staff lines help the eye in determining the vertical +position of a note wrt. to the clef. +\begin{mudela} +\score { + \notes \relative c' {\clef alto; \time 2/4; g'4 c,4 a'4 f4 e c d2 } + \paper { + linewidth = -1.; + } +} +\end{mudela} + +Now you know the pitch of the notes: you look at the start of the line +and see a clef, and with this clef, you can determine the notated pitches. +You have found the em(context) in which the notation is to be +interpreted! + + +\section{Interpretation context} + +Context (clef, time signature etc.) determines the relationship +between musical and its notation in notes. Because LilyPond writes +notation, context works the other way around for LilyPond: with +context a piece of music can be converted to notation. + +A reader remembers this context while reading the notation from left +to right. By analogy, LilyPond constructs this context while +constructing notes from left to right. This is what happens in the +``Interpretation'' phase from~\ref{fig:intro-fig}. In LilyPond, the +state of this context is a set of variables with their values; A staff +context contains variables like + +\begin{itemize} +\item current clef +\item current time signature +\item current key +\end{itemize} + +These variables determine when and how clefs, time signatures, bar +lines and accidentals are printed. + + +Staff is not the only form of context in notation. In polyphonic +music, the stem direction shows which notes form a voice: all notes of +the same voice have stems pointing in the same direction. The value +of this variable determines the appearance of the printed stems. + +In LilyPond ``Notation context'' is abstracted to a data structure +that is used, constructed and modified during the interpretation +phase. It contains context properties, and is responsible for +creating notational elements: the staff context creates symbols for +clefs, time signatures and key signatures. The Voice context creates +stems, note heads. + +For the fragment of polyphonic music below, +\begin{mudela} + \context Staff { c'4 < { \stemup c'4 } \context Voice = VB { \stemdown a4 } > } +\end{mudela} +A staff context is created. Within this staff context (which printed +the clef), a Voice context is created, which prints the first note. +Then, a second Voice context is created, with stem direction set to +``up'', and the direction for the other is set to down. Both Voice +contexts are still part of the same Staff context. + +In the same way, multiple staff scores are created: within the score +context, multiple staff contexts are created. Every staff context +creates the notation associated with a staff. + +\section{Discussion} + + + +\end{document} + +The complexity of music notation was tackled by adopting a modular +design: both the formatting system (which encodes the esthetic rules of +notation), and the interpretation system (which encodes the semantic +rules) are highly modular. + + +The difficulty in creating a format for music notation is rooted in +the fact that music is multi dimensional: each sound has its own +duration, pitch, loudness and articulation. Additionally, multiple +sounds may be played simultaneously. Because of this, there is no +obvious way to ``flatten'' music into a context-free language. + +The difficulty in creating a printing engine is rooted in the fact +that music notation complicated: it is very large graphical +``language'' with many arbitrary esthetic and semantic conventions. +Building a system that formats full fledged musical notation is a +challenge in itself, regardless of whether it is part of a compiler or +an editor. + +The fact that music and its notation are of a different nature, +implies that the conversion between input notation is non-trivial. + +In LilyPond we solved the above problem in the following way: + diff --git a/Documentation/programmer/musicnotes.sty b/Documentation/programmer/musicnotes.sty new file mode 100644 index 0000000000..31d2f83a9c --- /dev/null +++ b/Documentation/programmer/musicnotes.sty @@ -0,0 +1,43 @@ + +\input lilyponddefs + +\def\fetdef#1#2{% + \def#1{\hbox{\char#2}}} + +% huh? from where +\input feta20.sty + +\font\fetasixteenfont=feta16 +\font\fetaelevenfont=feta11 +\def\fetafont{\fetasixteenfont} + +\newdimen\ild +\ild=4pt +\newdimen\stemthick +\stemthick=0.4pt + +\def\eighthstem{{\fetafont\vrule height 3.5ex width \stemthick depth0pt\raise + 3.5ex\hbox{\eighthflag}}} +\def\texteighthflag{{\fetafont\raise 0ex\hbox{\fetafont\eighthflag}}} +\def\textdeighthflag{{\fetafont\raise 0ex\hbox{\deighthflag}}} + +\def\texteighthnote{{\hbox{\hbox{\fetafont\quartball}\kern + -0.5\stemthick\eighthstem}}} +\def\quarterstem{{\fetafont\vrule height 3.5ex width \stemthick depth0pt}} +\def\textquarterstem{\quarterstem} +\def\textchord{{\hbox{\fetafont\lower.5ex\hbox to + 0pt{\textquarterhead}\raise.5ex\hbox{\textquarterhead}\kern + -0.5\stemthick\eighthstem}}} +\def\textbassclef{\hbox{\fetafont\bassclef}} +\def\texttrebleclef{\hbox{\fetafont\trebleclef}} +\def\textslur{\embeddedps{9.378744 -3.171539 3.923099 -3.171539 0.000000 0.000000 12.800000 0.000000 3.672177 -3.672177 9.127823 -3.672177 12.800000 0.000000 0.000000 0.000000 draw_slur}} + +\def\textmarcato{{\fetafont\raise 1ex\hbox{\hskip 1ex\sforzatoaccent}}} + + +\def\textquarterhead{\hbox{\fetafont\raise 2.5pt\hbox{\quartball}}} +\def\texteighthstem{\hbox{\lower 5pt\hbox{\eighthstem}}} +\def\texthalfnote{{\hbox{\hbox{\fetafont\halfball}\kern -0.5\stemthick\quarterstem}}} +\def\textquarternote{{\hbox{\hbox{\fetafont\quartball}\kern -0.5\stemthick\quarterstem}}} +\def\textflat{{\fetafont\raise 1ex\hbox{\flat}}} +\def\textsharp{{\fetafont\raise1ex\hbox{\sharp}}} diff --git a/Documentation/programmer/regression-test.tely b/Documentation/programmer/regression-test.tely new file mode 100644 index 0000000000..fe5ee1dbfd --- /dev/null +++ b/Documentation/programmer/regression-test.tely @@ -0,0 +1,312 @@ +\input texinfo @c -*-texinfo-*- vim:tw=72 +@setfilename regression-test.info +@settitle LilyPond Regression test + +@c fool ls-latex +@ignore +@author Han-Wen Nienhuys and Jan Nieuwenhuizen +@title LilyPond Regression test +@end ignore + +@node Top, , , + +@section Introduction + +This document tries give an brief overview of LilyPond features. When +the text correspond with the shown notation, we consider LilyPond +Officially BugFree (tm). This document is intended for finding bugs, +and documenting bugfixes. + +@section Notes and rests + +Rests. Note that the dot of 8th, 16th and 32nd rests rest should be +next to the top of the rest. All rests except the whole rest are +centered on the middle staff line. + +@mudelafile{rest.fly} + +Note head shapes are settable. The stem endings should be adjusted +per note head. If you want different note head styles on one stem, +you must create a special context called Thread. + +@mudelafile{noteheadstyle.ly} + +Noteheads can have dots, and ---although this is bad style in duple +meters--- rests can too. Augmentation dots should never be printed on +a staff line, but rather be shifted vertically. They should go up, but +in case of multiple parts, the down stems have down shifted dots. +(Wanske p. 186) In case of chords, all dots should be in a column. +The dots go along as rests are shifted to avoid collisions. + +@mudelafile{dots.fly} + +Multiple measure rests do not collide with barlines and clefs. They +are not expanded when you set @code{Score.SkipBars}. Although the +multi-measure-rest is a Spanner, minimum distances are set to keep it +colliding from barlines. + +@mudelafile{multi-measure-rest.ly} + +@section Stems + +Stem tremolos (official naming?) or rolls are tremolo signs that look +like beam segments crossing stems. If the stem is in a beam, the +tremolo must be parallel to the beam. If the stem is invisible +(eg. on a whole note), the tremolo must be centered on the note. + +@mudelafile{stem-tremolo.ly} + +Chord tremolos look like beams, but are a kind of repeat symbol. +To avoid confusion, chord tremolo beams do not reach the stems, but +leave a gap. Chord tremolo beams on half notes are not ambiguous, +as half notes cannot appear in a regular beam, and should reach the +stems. + +@mudelafile{chord-tremolo.sly} + +Beams, stems and noteheads often have communication troubles, since +the two systems for y dimensions (1 unit = staffspace, 1 unit = 1 +point) are mixed. + +Stems, beams, ties and slurs should behave similarly, when placed +on the middle staff line. Of course stem-direction is down for high +notes, and up for low notes. + +@mudelafile{stem-direction.sly} + +Similarly, if @code{stem_default_neutral_direction} is set to @code{-1}. + +@mudelafile{stem-direction-down.ly} + +@section Scripts + +The staccato dot (and all scripts with follow-into-staff set), must +not be on staff lines. + +@mudelafile{staccato-pos.sly} + +@section Grace notes + +Grace notes are typeset as an encapsulated piece of music. You can +have beams, notes, chords, stems etc. within a @code{\grace} section. +Slurs that start within a grace section, but aren't ended are attached +to the next normal note. Grace notes have zero duration. If there +are tuplets, the grace notes won't be under the brace. Grace notes +can have accidentals, but they are (currently) spaced at a fixed +distance. Grace notes (of course) come before the accidentals of the +main note. Grace notes can also be positioned after the main note. + +@mudelafile{grace.ly} + + +@section Beams, slurs and other spanners + +Beaming is generated automatically. Beams may cross bar lines. In that +case, line breaks are forbidden. Yet clef and key signatures are +hidden just as with breakable bar lines. + +@mudelafile{beaming.ly} + +Beams should behave reasonably well, even under extreme circumstances. +Stems may be short, but noteheads should never touch the beam. + +@mudelafile{beam-extreme.ly} + +Beams should always reach the middle staff line, the second beam +counting from the note head side, should never be lower than the +second staff line. This does not hold for grace note beams. + +@mudelafile{beam-position.sly} + +Slurs should look nice and symmetric. The curvature may increase +only to avoid noteheads, and as little as possible. + +@mudelafile{slur-symmetry.ly} +@mudelafile{slur-symmetry-1.ly} + +Ties are strictly horizontal. They are placed in between note heads. +The horizontal middle should not overlap with a staffline. + +@mudelafile{tie.ly} + +Beams can be typeset over fixed distance aligned staffs, beam +beautification doesn't really work, but knees do. Beams should be +behave well, wherever the switching point is. + +@mudelafile{beam-cross-staff.ly} + +The same goes for slurs. They behave decently when broken across +linebreak. + +@mudelafile{slur-cross-staff.ly} + +Tuplets are indicated by a bracket with a number. There should be no +bracket if there is one beam that matches the length of the tuplet. +The bracket does not interfere with the stafflines, and the number is +centered in the gap in the bracket. + +@mudelafile{tup.ly} + +@section Repeats + +LilyPond has three modes for repeats: folded, unfolded and +semi-unfolded. Unfolded repeats are fully written out. Semi unfolded +repeats have the body written and all alternatives sequentially. +Folded repeats have the body written and all alternatives +simultaneously. If the number of alternatives is larger than the +repeat count, the excess alternatives are ignored. If the number of +alternatives is smaller, the first alternative is multiplied to get to +the number of repeats. + +Unfolded behavior: + +@mudelafile{repeat-unfold.ly} + +Volta (Semi folded) behavior. Voltas can start on non-barline moments. +If they don't barlines should still be shown. + +@mudelafile{repeat-volta.ly} + +Folded. This doesn't make sense without alternatives, but it works. + +@mudelafile{repeat-fold.ly} + +@section Lyrics + +Lyrics can be set to a melody automatically. Excess lyrics will be +dumped. Lyrics will not be set over rests. You can have melismata +either by setting a property melismaBusy, or by setting +automaticMelismas (which will set melismas during slurs and ties). If +you want a different order than first Music, then Lyrics, you must +precook a chord of staffs/lyrics and label those. Of course +@code{\rhythm} ignores any other rhythms in the piece. Hyphens and +extenders do not assume anything about lyric lengths, so they continue +to work. + +@mudelafile{lyric-combine.ly} + +@section Multiple notes + +Rests should not collide with beams, stems and noteheads. Rests may +be under beams. Rests should be move by integral number of spaces +inside the staff, and by half spaces outside. Notice that the half +and whole rests just outside the staff get ledger lines in different +cases. + +@mudelafile{rest-collision.ly} + +Normal collisions. We have support for polyphony, where the +middle voices are horizontally shifted. + +@mudelafile{collisions.ly} + +The number of stafflines of a staff can be set with the property +numberOfStaffLines. Ledger lines both on note heads and rests are +adjusted. Barlines also are adjusted. + + +@mudelafile{number-staff-lines.fly} + +@section Spacing + +In a limited number of cases, LilyPond corrects for optical spacing +effects. In this example, space for opposite pointed stems is adjusted + +@mudelafile{stem-spacing.sly} + +If there are accidentals in the music, we add space, but the space +between note and accidentals is less than between the notes with the +same value. Clef changes also get extra space, but not as much as +barlines. + + +Even if a line is very tightly spaced, there will still be room +between prefatory matter and the following notes. The space after the +prefatory is very rigid. In contrast, the space before the barline +must stretch like the space within the measure. + +Tight: + +@mudelafile{spacing-tight.ly} + +Natural: + +@mudelafile{spacing-natural.ly} + +Loose: + +@mudelafile{spacing-loose.ly} + +Adding a @code{Bar_engraver} to the LyricsVoice context makes sure that +lyrics don't collide with barlines. + +@mudelafile{lyrics-bar.ly} + +@section Global stuff + +Breaks can be encouraged and discouraged using @code{\break} and +@code{\nobreak}. They are abbrevs for @code{\penalty} commands. + +@mudelafile{break.ly} + + +Markings that are attached to (invisible) barlines are +delicate: the are attached to the rest of the score without the score +knowing it. Consequently, they fall over often. + +@mudelafile{bar-scripts.ly} + +Staff margins are also markings attached to barlines. They should be +left of the staff, and be centered vertically wrt the staff. They may +be on normal staffs, but also on compound staffs, like the PianoStaff + +@mudelafile{staff-margin.ly} + +Breathing signs, also used for phrasing, do normally not influence +global spacing -- only if space gets tight, notes are shifted to make +room for the breathing sign. Breathing signs break beams running +through their voice. In the following example, the notes in the first +two measures all have the same distance from each other: + +@mudelafile{breathing-sign.ly} + +Fonts are available in a default set of sizes: 11, 13, 16, 20, 23 and +26pt staffheight. Sizes of the text fonts and symbol fonts are made +to match the staff dimensions. + +@mudelafile[nofly]{size11.ly} + +@mudelafile[nofly]{size13.ly} + +@mudelafile[nofly]{size16.ly} + +@mudelafile[nofly]{size20.ly} + +@mudelafile[nofly]{size23.ly} + +@mudelafile[nofly]{size26.ly} + + +@section Clefs and Time Signatures + +The transparent clef should not occupy any space and with style +@code{fullSizeChanges}, the changing clef should be typeset in full +size. For octaviated clefs, the ``8'' should appear closely above or +below the clef respectively. The ``8'' is processed in a convoluted +way, so this is fragile as well. + +@mudelafile{clefs.ly} + +@ignore +@c the input file is too long and does not test for specific bugs +By default, time signatures are written with two numbers. With style +``C'', 4/4 and 2/2 are written with their corresponding symbols and +with style ``old'', 2/2, 3/2, 2/4, 3/4, 4/4, 6/4, 9/4, 4/8, 6/8 and +9/8 are typeset with symbols, all other signatures retain the default +layout. The style ``1'', gives single number signatures for all +signatures. +% +\mu delafile{time.fly} +@end ignore + +@bye diff --git a/Documentation/programs.texi b/Documentation/programs.texi index 6bd3b069c4..6fecb0ea43 100644 --- a/Documentation/programs.texi +++ b/Documentation/programs.texi @@ -2,11 +2,10 @@ @setfilename programs.info @settitle Programs -@node Top, , midi2ly Authors, (dir) +@node Top, , , (dir) @top @menu * Programs:: Your Softs- -* convert-mudela:: convert-mudela to newer versions * Ly2dvi:: Python utility to convert mudela to DVI * midi2ly:: convert MIDI to -mudela- @end menu @@ -14,7 +13,7 @@ -@node Programs, convert-mudela, , Top +@node Programs, , , Top @chapter Programs @@ -23,7 +22,7 @@ -@node Ly2dvi, Ly2dvi DESCRIPTION, LilyPond Authors, Top +@node Ly2dvi, , , Top @menu * Ly2dvi DESCRIPTION:: Ly2dvi DESCRIPTION * Ly2dvi SYNOPSIS:: Ly2dvi SYNOPSIS @@ -39,7 +38,7 @@ @end menu @chapter Ly2dvi -@node Ly2dvi DESCRIPTION, Ly2dvi SYNOPSIS, Ly2dvi, Ly2dvi +@node Ly2dvi DESCRIPTION, , , Ly2dvi @section DESCRIPTION ly2dvi is a Python script which creates input file for LaTeX, based on information from the output files from LilyPond. @@ -53,12 +52,12 @@ one or more DVI files. The majority of this utility came from a bourne script written by Jan Arne Fagertun name @file{ly2dvi}. -@node Ly2dvi SYNOPSIS, Ly2dvi OPTIONS, Ly2dvi DESCRIPTION, Ly2dvi +@node Ly2dvi SYNOPSIS, , , Ly2dvi @section SYNOPSIS ly2dvi [options] inputfile[.ly] [....] -@node Ly2dvi OPTIONS, Ly2dvi Features, Ly2dvi SYNOPSIS, Ly2dvi +@node Ly2dvi OPTIONS, , , Ly2dvi @section OPTIONS @table @samp @@ -106,7 +105,7 @@ Arne Fagertun name @file{ly2dvi}. DVI file for each. @end table -@node Ly2dvi Features, Ly2dvi Environment, Ly2dvi OPTIONS, Ly2dvi +@node Ly2dvi Features, , , Ly2dvi @section Features ly2dvi responds to several parameters specified in the mudela @@ -125,7 +124,7 @@ file. They are overridden by corresponding command line options. Specify name of papersize. @end table -@node Ly2dvi Environment, Ly2dvi Files, Ly2dvi Features, Ly2dvi +@node Ly2dvi Environment, , , Ly2dvi @section Environment @table @samp @@ -137,7 +136,7 @@ file. They are overridden by corresponding command line options. Temporary directory name. Default is /tmp @end table -@node Ly2dvi Files, Ly2dvi Initialization Sequence, Ly2dvi Environment, Ly2dvi +@node Ly2dvi Files, , , Ly2dvi @section Files @file{titledefs.tex} is inspected for definitions used to extract @@ -239,7 +238,7 @@ present. Possible value is a valid directory specification that is writable to the user. @end table -@node Ly2dvi Initialization Sequence, Ly2dvi See Also, Ly2dvi Files, Ly2dvi +@node Ly2dvi Initialization Sequence, , , Ly2dvi @section Initialization Sequence The initialization process reads inputs for several sources. Below is a list of priorities for lowest to hightest proirity. @@ -257,12 +256,12 @@ a list of priorities for lowest to hightest proirity. Note that this differs slightly from the original bourne shell version. -@node Ly2dvi See Also, Ly2dvi Bugs, Ly2dvi Initialization Sequence, Ly2dvi +@node Ly2dvi See Also, , , Ly2dvi @section See Also lilypond(1), tex(1), latex(1) -@node Ly2dvi Bugs, Ly2dvi Remarks, Ly2dvi See Also, Ly2dvi +@node Ly2dvi Bugs, , , Ly2dvi @section Bugs If you have found a bug, you should send a bugreport. @@ -276,7 +275,7 @@ If you have found a bug, you should send a bugreport. to this mailinglist). @end itemize -@node Ly2dvi Remarks, Ly2dvi Authors, Ly2dvi Bugs, Ly2dvi +@node Ly2dvi Remarks, , , Ly2dvi @section Remarks Many papersizes are now supported. Information on other sizes @@ -289,7 +288,7 @@ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, archA, archB, archC, archD, archE, b0, b1, b2, b3, b4, b5, flsa, flse, halfletter, ledger, legal, letter, note -@node Ly2dvi Authors, midi2ly, Ly2dvi Remarks, Ly2dvi +@node Ly2dvi Authors, , , Ly2dvi @section Authors Python Version author: @email{daboys@@austin.rr.com, Jeffrey B. Reed}, @@ -305,24 +304,21 @@ Original bourne shell version author: -@node midi2ly, midi2ly DESCRIPTION, Ly2dvi Authors, Top +@node midi2ly, , , Top @menu * midi2ly DESCRIPTION:: midi2ly DESCRIPTION * midi2ly OPTIONS:: midi2ly OPTIONS -* midi2ly DISCLAIMER:: midi2ly DISCLAIMER -* midi2ly SEE ALSO:: midi2ly SEE ALSO -* midi2ly Authors:: midi2ly Authors @end menu @chapter midi2ly -@node midi2ly DESCRIPTION, midi2ly OPTIONS, midi2ly, midi2ly +@node midi2ly DESCRIPTION, , , midi2ly @section DESCRIPTION midi2ly translates a MIDI input file to Mudela (GNU LilyPond source format). midi2ly is part of the GNU LilyPond music typesetting package. midi2ly [options] midi-file -@node midi2ly OPTIONS, midi2ly DISCLAIMER, midi2ly DESCRIPTION, midi2ly +@node midi2ly OPTIONS, , , midi2ly @section OPTIONS @table @samp @@ -355,33 +351,4 @@ format). midi2ly is part of the GNU LilyPond music typesetting package. Assume no double dotted notes. @end table -@node midi2ly DISCLAIMER, midi2ly SEE ALSO, midi2ly OPTIONS, midi2ly -@section DISCLAIMER - -midi2ly is copyright 1996, 1997 by its authors. midi2ly is distributed -as part of GNU LilyPond, under the terms of the GNU General Public -License. midi2ly is provided without any warranty what so ever. -midi2ly may be freely distributed. For further information consult -the GNU General Public License, from the file @file{COPYING}. - -@node midi2ly SEE ALSO, midi2ly Authors, midi2ly DISCLAIMER, midi2ly -@section SEE ALSO - -@table @samp -@item @strong{lilypond}(1) - The GNU LilyPond music typesetter. -@end table - -@node midi2ly Authors, Top, midi2ly SEE ALSO, midi2ly -@section Authors - -Please consult the documentation file @file{AUTHORS} for more detailed -information, and small contributions. - -@email{janneke@@gnu.org, Jan Nieuwenhuizen}, @uref{http://www.xs4all.nl/~jantien} - - - - - @bye diff --git a/Documentation/topdocs/INSTALL.texi b/Documentation/topdocs/INSTALL.texi index c2884623cc..440404cb13 100644 --- a/Documentation/topdocs/INSTALL.texi +++ b/Documentation/topdocs/INSTALL.texi @@ -61,7 +61,7 @@ NT/95/98 as well. See Section Windows NT/95,es. Check out @uref{ftp://ftp.python.org} or @uref{ftp://ftp.cwi.nl/pub/python}. -@item GUILE 1.3, check out @uref{http://www.gnu.org/software/guile/guile.html,http://www.gnu.org/software/guile/guile.html}. +@item GUILE 1.3.4, check out @uref{http://www.gnu.org/software/guile/guile.html,http://www.gnu.org/software/guile/guile.html}. @item GNU make. Check out @uref{ftp://ftp.gnu.org/make/,ftp://ftp.gnu.org/make/}. @@ -96,7 +96,7 @@ following software @item A PostScript printer and/or viewer (such as Ghostscript) is strongly recommended. Xdvi will show all embedded PostScript too if you have Ghostscript installed. -@item GUILE 1.3, check out @uref{http://www.gnu.org/programs/guile.html,http://www.gnu.org/software/guile/} +@item GUILE 1.3.4, check out @uref{http://www.gnu.org/programs/guile.html,http://www.gnu.org/software/guile/} @end itemize For running LilyPond successfully you have to help TeX and MetaFont @@ -361,10 +361,6 @@ demonstrated in @file{input/bugs/}. Known bugs that are not LilyPond's fault are documented here. -@unnumbered All platforms -@itemize -@item Guile 1.3.2 is buggy in several respects. Do not use it for LilyPond. -@end itemize @unnumbered LinuxPPC Bugs: @@ -390,12 +386,6 @@ solution are not known. Note that this only happens on some computers with the said platform. -@item GUILE -A binary RPM of Guile 1.3 has been distributed from the LilyPond ftp -site. This binary was made in RedHat 5.x, and it will fail if this -RPM is used with RedHat 6.x. - - @item libg++ 2.7 LilyPond occasionally crashes while parsing the initialisation files. diff --git a/Documentation/topdocs/README.texi b/Documentation/topdocs/README.texi index afaf35fb75..8f76f1f673 100644 --- a/Documentation/topdocs/README.texi +++ b/Documentation/topdocs/README.texi @@ -45,13 +45,13 @@ If you want to read the documentation online, these are options: @item use @file{.dvi}, for the tutorial and reference manual. Do @example - make -C Documentation/tex/ dvi + make -C Documentation/user/ dvi @end example @item use ASCII. Do using @example - make -C Documentation/ + make -C doc @end example @end itemize diff --git a/Documentation/topdocs/index.tely b/Documentation/topdocs/index.tely index 973f35c707..6078fa1349 100644 --- a/Documentation/topdocs/index.tely +++ b/Documentation/topdocs/index.tely @@ -6,27 +6,29 @@ @top - @unnumbered LilyPond -- The @uref{http://www.fsf.org/gnu/gnu-history.html,GNU Project} Music Typesetter + +@html + +@end html + @c something breaks on 3.12 f -@c @center -@quotation -@mudela[fragment] - \relative c'' { \key es; r8 [c16 b] [c8 g] [as c16 b] [c8 d] | g,4 } -@end mudela -@end quotation -@c @end center -@c include BLURB? 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. -@c include screenshot +@c @center +@quotation +@mudela[fragment] + \relative c'' { \key es; r8 [c16 b] [c8 g] [as c16 b] [c8 d] | g,4 } +@end mudela +@end quotation +@c @end center @unnumberedsec Sheet music diff --git a/INSTALL.txt b/INSTALL.txt index 5c5754ea88..2a431f3a5c 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -53,7 +53,8 @@ Prerequisites * Python 1.5, Check out `ftp://ftp.python.org' or `ftp://ftp.cwi.nl/pub/python'. - * GUILE 1.3, check out http://www.gnu.org/software/guile/guile.html + * 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/ @@ -93,7 +94,7 @@ following software strongly recommended. Xdvi will show all embedded PostScript too if you have Ghostscript installed. - * GUILE 1.3, check out http://www.gnu.org/software/guile/ + * 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 @@ -333,12 +334,6 @@ demonstrated in `input/bugs/'. Known bugs that are not LilyPond's fault are documented here. -All platforms -************* - - * Guile 1.3.2 is buggy in several respects. Do not use it for - LilyPond. - LinuxPPC Bugs: ************** @@ -361,10 +356,6 @@ Linux-i386 Note that this only happens on some computers with the said platform. - * GUILE A binary RPM of Guile 1.3 has been distributed from the - LilyPond ftp site. This binary was made in RedHat 5.x, and it - will fail if this RPM is used with RedHat 6.x. - * libg++ 2.7 LilyPond occasionally crashes while parsing the initialisation diff --git a/NEWS b/NEWS index 5d740e231d..b2027c3cb1 100644 --- a/NEWS +++ b/NEWS @@ -1,10 +1,3 @@ -WHAT'S NEW SINCE 1.2.0 - -* Much faster spacing engine. - -* Features: automatic staff switching - -* Documentation now all is in texinfo. - +[todo] diff --git a/README.txt b/README.txt index 33f5b31671..c22267cdb8 100644 --- a/README.txt +++ b/README.txt @@ -45,10 +45,10 @@ Documentation * use `.dvi', for the tutorial and reference manual. Do - make -C Documentation/tex/ dvi + make -C Documentation/user/ dvi * use ASCII. Do using - make -C Documentation/ + make -C doc Comments diff --git a/TODO b/TODO index dc34df7475..68c356c704 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ --*-outline-layout:(2 (-1 -1 0 :) 0);outline-stylish-prefixes:nil -*- +i-*-outline-layout:(2 (-1 -1 0 :) 0);outline-stylish-prefixes:nil -*- * GNU LilyPond TODO Features you cannot find in the documentation as working, should be @@ -9,11 +9,20 @@ Most of the items are marked in the code as well Grep -i for TODO, FIXME and ugh/ugr/urg. .* TODO +. * make this file understandable for 3rd parties. . * use Rhythmic_head::position_i () for all Staff_referenced -. * .po -> .pot. +. * note head on stem err msg in dutch. . * why need to run -C mf twice? +. * fix interstaff stuff . * junk BLURB files. . * setting indent to 0 with \shape fails +. * here's no difference at all in output. When either is jacked up to 7.0, +everything works and matches up; when either is set just a bit above the +default 5.0 (5.4 is what I was hoping to use), stems miss note heads. So +it's some sort of a numerical (truncation/roundoff) problem. +John +. * metre -> meter +. * Fixed size staff heights; . * ly2dvi : don't repeat opus if same. . * breaks before mmrests are favored. . * hara kiri _8 clef. @@ -21,10 +30,6 @@ Grep -i for TODO, FIXME and ugh/ugr/urg. . * mudela-book doco . * rerun profile . * fix or replace feta-accordion.mf -. * fix configure with CFLAGS or LDFLAGS, try: - CFLAGS=-g LDFLAGS='-Wl,--warn-common' ./configure -configure will use them while testing the compiler, but they don't -appear in config.make . * script engraver . * Chords: . * Bass/inversion pitch when not part of Chord @@ -86,14 +91,14 @@ melismatic. What's old about absolute to relative conversion? Could maybe use for abc2ly, midi2ly? +. * Junk shared cruft (duration, moment) in lib/ + + .* Cleanups needed . * \$ and $ identifier syntax in examples. . * Junk ghost positioning objects eg, Script leans on Staffside leans on Staff. . * bracket ps code. -. * mudela-book -. * center option (??) -. * make mudela-book understand usepackage{geometry} . * Key_engraver, Local_key_item . * Think of comprehensive solution for "if (grace_b == self_grace_b_)" . * String[String.length] doesn't trap. @@ -166,7 +171,6 @@ one of the spacing bugs mentioned in the TODO. be stacked vertically, avoiding collisions with the notes in all voices. -. * break priority setting from SCM. . * Matanya's tips: . * don't shorten stems/staffs closer to each other. . * accidentals closer to note head @@ -183,7 +187,6 @@ one of the spacing bugs mentioned in the TODO. page three, the c-sharp on the second line should be a quarter with a circle, not a quarter tied to a sixteenth. is this at all possible with lily? -. * scm-ify \property values. . * make dependencies () a virtual function. . * deprecate hangOnClef. . * Abstraction for engravers: diff --git a/VERSION b/VERSION index a29c25c1b1..dc92e1726d 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 -MINOR_VERSION=2 -PATCH_LEVEL=15 +MINOR_VERSION=3 +PATCH_LEVEL=0 MY_PATCH_LEVEL= # use the above to send patches: MY_PATCH_LEVEL is always empty for a diff --git a/buildscripts/set-lily.sh b/buildscripts/set-lily.sh index d69f24b3b7..f809aba7d3 100755 --- a/buildscripts/set-lily.sh +++ b/buildscripts/set-lily.sh @@ -81,7 +81,7 @@ rm -f cmtfm; showln -sf $TEX_TFMDIR $BUILDDIR/cmtfm if [ -f ../.gdbinit.lilypond ]; then - showln -f ../.gdbinit.lilypond . + showln -f ../.gdbinit.lilypond .gdbinit fi if [ -f ../.dstreamrc ] diff --git a/flower/dstream.cc b/flower/dstream.cc index ba46d69ed6..e51f97a39e 100644 --- a/flower/dstream.cc +++ b/flower/dstream.cc @@ -9,7 +9,7 @@ #include #include "dictionary-iter.hh" #include "dstream.hh" -#include "scalar.hh" + #include "text-db.hh" #include "string-convert.hh" #include "rational.hh" @@ -86,7 +86,7 @@ Dstream::operator<<(void const *v_l) } Dstream & -Dstream::operator <<(Scalar s) +Dstream::operator <<(String s) { output (s); return *this; @@ -99,6 +99,32 @@ Dstream::operator <<(const char * s) return *this; } +Dstream & +Dstream::operator <<(char c) +{ + output (to_str (c)); + return *this; +} + +Dstream& +Dstream::operator << (Real r) +{ + output (to_str (r)); + return *this; +} +Dstream & +Dstream::operator <<(Rational c) +{ + output (c.str ()); + return *this; +} +Dstream & +Dstream::operator <<(int i) +{ + output (to_str(i)); + return *this; +} + void Dstream::output (String s) { @@ -158,7 +184,7 @@ Dstream::Dstream (ostream *r, char const * cfg_nm) r.message (_ ("not enough fields in Dstream init")); continue; } - (*silent_dict_p_)[r[0]] = (bool)(int)(Scalar (r[1])); + (*silent_dict_p_)[r[0]] = r[1] == "1"; } if ((*silent_dict_p_).elem_b ("Dstream_default_silence")) diff --git a/flower/include/dstream.hh b/flower/include/dstream.hh index 93b9956a25..c207e21e38 100644 --- a/flower/include/dstream.hh +++ b/flower/include/dstream.hh @@ -10,7 +10,7 @@ #define DSTREAM_HH #include "string.hh" -#include "scalar.hh" + const char eol= '\n'; @@ -51,12 +51,12 @@ public: virtual ~Dstream(); Dstream &identify_as (String s); - /** - Output a Scalar via the Dstream. This is the only output - interface. It explicitely delegates all implicit conversion - to Scalar class. - */ - Dstream &operator << (Scalar); + + Dstream &operator << (String); + Dstream &operator << (Real); + Dstream &operator << (int); + Dstream &operator << (Rational); + Dstream &operator << (char); /** Output memory locations. */ diff --git a/flower/include/rational.hh b/flower/include/rational.hh index 7ea4e0aaf2..b1187ec692 100644 --- a/flower/include/rational.hh +++ b/flower/include/rational.hh @@ -10,15 +10,11 @@ #ifndef RATIONAL_HH #define RATIONAL_HH -#if PARANOIA -#ifndef Rational -#define Rational MyRational -#endif -#endif #include "compare.hh" #include "arithmetic-operator.hh" #include "fproto.hh" +#include "string.hh" /** Rational numbers. Included is support for + and - infinity. diff --git a/flower/include/real.hh b/flower/include/real.hh index ec98982cdf..630d3dd692 100644 --- a/flower/include/real.hh +++ b/flower/include/real.hh @@ -25,7 +25,7 @@ template inline T abs (T x) template inline int sign (T x) { if (x) - return x > 0 ? 1 : -1; + return x > T(0) ? 1 : -1; return 0; } diff --git a/flower/include/scalar.hh b/flower/include/scalar.hh index b389277bc3..1960e53d56 100644 --- a/flower/include/scalar.hh +++ b/flower/include/scalar.hh @@ -13,18 +13,21 @@ #include "string.hh" #include "real.hh" +#error /// Perl -like scalar type. -struct Scalar : public String +struct Scalar { - Scalar (Real r) { *this = to_str (r); } - Scalar (int i) { *this = to_str (i); } - Scalar (long l) { *this = to_str (l); } - Scalar (char c) { *this = to_str (c); } - Scalar (char const *c) : String (c) {} - Scalar (String s) : String (s) {} + Protected_scm scm_; +public: + Scalar (Real r); + Scalar (int i); + Scalar (long l); + Scalar (char c); + Scalar (char const *c); + Scalar (String s); Scalar (Rational); operator Rational(); - Scalar() {} + Scalar(); bool isnum_b() const; bool isdir_b() const; bool isint_b() const; diff --git a/flower/include/string.hh b/flower/include/string.hh index 24b975949a..b0bf9f8952 100644 --- a/flower/include/string.hh +++ b/flower/include/string.hh @@ -90,16 +90,7 @@ public: void operator += (String s); bool empty_b () const; -#if 0 - /** is the string empty? - Ugh-ugh-thank-you-cygnus. W32 barfs on this - */ - operator bool () const; - { - return length_i (); - } -#endif void append (String); void prepend (String); diff --git a/flower/scalar.cc b/flower/scalar.cc index 476b6485bd..48d4889a4e 100644 --- a/flower/scalar.cc +++ b/flower/scalar.cc @@ -1,3 +1,4 @@ +#if 0 /* scalar.cc -- implement Scalar @@ -8,7 +9,7 @@ #include #include -#include "scalar.hh" + #include "rational.hh" Scalar::Scalar (Rational r) @@ -105,3 +106,4 @@ Scalar::to_bool () const } +#endif diff --git a/input/praeludium-fuga-E.ly b/input/praeludium-fuga-E.ly index 3f9deec181..ed568286ed 100644 --- a/input/praeludium-fuga-E.ly +++ b/input/praeludium-fuga-E.ly @@ -204,24 +204,24 @@ breakmusic = \notes { \translator { \VoiceContext \name "VoiceOne"; - verticalDirection = "1"; + verticalDirection = #1 } \translator { \VoiceContext \name "VoiceTwo"; - verticalDirection = "-1"; + verticalDirection = #1 } \translator { \VoiceContext \name "VoiceThree"; - verticalDirection = "1"; - horizontalNoteShift = "1"; + verticalDirection = #1 + horizontalNoteShift = #1 } \translator { \VoiceContext \name "VoiceFour"; - verticalDirection = "-1"; - horizontalNoteShift = "1"; + verticalDirection = #-1 + horizontalNoteShift = #1 } \translator { \StaffContext diff --git a/input/star-spangled-banner.ly b/input/star-spangled-banner.ly index d16dadc5e6..0cc8c8b8a6 100644 --- a/input/star-spangled-banner.ly +++ b/input/star-spangled-banner.ly @@ -4,6 +4,8 @@ http://www.Arkkra.com/doc/star.html http://www.Arkkra.com/doc/star.ps %} + + \header{ title="The Star Spangled Banner"; subtitle="The United States National Anthem"; @@ -101,7 +103,7 @@ textxx = \lyrics { { stripes and bright stars, through the per- il- ous fight, O'er the ram- parts we watched, were so gal- lant- ly - _ _ _ _ % UGH UGH UGH + " " " " " " " "% _ _ _ _ % UGH UGH UGH stream- ing And the rock- ets' red glare, the bombs burst- ing in air, gave proof through the night that @@ -120,25 +122,25 @@ automaticLyrics = \notes \context GrandStaff < \context Staff=staffA < \beginmatter \clef treble; - \property Staff.automaticMelismata = "1" - \notes \transpose c'' {\voiceone \$staff1_voice_1 \bar "|.";} - \notes \transpose c'' {\voicetwo \$staff1_voice_2 } + \property Staff.automaticMelismata = ##t + \context Voice = one \transpose c'' {\stemup \$staff1_voice_1 \bar "|.";} + \context Voice = two \transpose c'' {\stemdown \$staff1_voice_2 } > \context LyricVoice \textxx \context Staff=staffB < \beginmatter \clef bass; - \property Staff.noVoltaBraces = "1" - {\voiceone \$staff2_voice_1 \bar "|."; } - {\voicetwo \$staff2_voice_2 } + \property Staff.noVoltaBraces = ##t + \context Voice = three {\stemup \$staff2_voice_1 \bar "|."; } + \context Voice = four {\stemdown \$staff2_voice_2 } > > handLyrics = \notes \context GrandStaff < \context Staff=staffA < \beginmatter - \notes \transpose c'' {\voiceone \$staff1_voice_1 \bar "|.";} - \notes \transpose c'' {\voicetwo \$staff1_voice_2 } + \transpose c'' {\voiceone \$staff1_voice_1 \bar "|.";} + \transpose c'' {\voicetwo \$staff1_voice_2 } > \nonRepeatText \context Staff=staffB < diff --git a/input/test/beam-cross-staff.ly b/input/test/beam-cross-staff.ly new file mode 100644 index 0000000000..376b25c3c9 --- /dev/null +++ b/input/test/beam-cross-staff.ly @@ -0,0 +1,33 @@ +\score{ + \context PianoStaff < + \context Staff=one \notes\relative c'{ + \stemup [c8 c \translator Staff=two \stemup c c] + [c c c c] + \translator Staff=one + \stemdown [c8 c \translator Staff=two \stemup c c] + r2 + \stemdown [c8 c \translator Staff=one \stemdown c c] + r2 + \translator Staff=two + \stemup [c8 c \translator Staff=one \stemdown c c] + r2 + } + \context Staff=two \notes\relative c'{ + \clef bass; + s1 + s1 + s1 + s1 + } + > + \paper{ + \translator{ + \PianoStaffContext + minVerticalAlign = 3.0*\staffheight; + maxVerticalAlign = 3.0*\staffheight; + } +% linewidth=-1.; + } +} + +\version "1.2.0"; diff --git a/input/test/beam-interstaff.ly b/input/test/beam-interstaff.ly deleted file mode 100644 index 376b25c3c9..0000000000 --- a/input/test/beam-interstaff.ly +++ /dev/null @@ -1,33 +0,0 @@ -\score{ - \context PianoStaff < - \context Staff=one \notes\relative c'{ - \stemup [c8 c \translator Staff=two \stemup c c] - [c c c c] - \translator Staff=one - \stemdown [c8 c \translator Staff=two \stemup c c] - r2 - \stemdown [c8 c \translator Staff=one \stemdown c c] - r2 - \translator Staff=two - \stemup [c8 c \translator Staff=one \stemdown c c] - r2 - } - \context Staff=two \notes\relative c'{ - \clef bass; - s1 - s1 - s1 - s1 - } - > - \paper{ - \translator{ - \PianoStaffContext - minVerticalAlign = 3.0*\staffheight; - maxVerticalAlign = 3.0*\staffheight; - } -% linewidth=-1.; - } -} - -\version "1.2.0"; diff --git a/input/test/embedded-scm.ly b/input/test/embedded-scm.ly new file mode 100644 index 0000000000..d530c85965 --- /dev/null +++ b/input/test/embedded-scm.ly @@ -0,0 +1,4 @@ +#(begin (newline)(display "hello world")(newline))\score{ + \notes\relative c'{ c } +} + diff --git a/input/test/no-stem-extend.fly b/input/test/no-stem-extend.fly new file mode 100644 index 0000000000..35ef31eac4 --- /dev/null +++ b/input/test/no-stem-extend.fly @@ -0,0 +1,13 @@ +% test noStemExtend +\context Staff < + \context Voice = "a" { + f2 f8 g a b + \property Voice.noStemExtend = 1 + f2 f8 g a b + } + \context Voice = "b" { + c''2 c8 b a g + \property Voice.noStemExtend = 1 + c2 c8 b a g + } +> diff --git a/input/test/slur-cross-staff.ly b/input/test/slur-cross-staff.ly new file mode 100644 index 0000000000..e53a579f89 --- /dev/null +++ b/input/test/slur-cross-staff.ly @@ -0,0 +1,39 @@ +\score{ + \context PianoStaff < + \context Staff=one \notes\relative c'{ + \stemup c4( c \translator Staff=two c )c | + \translator Staff=one + \stemup c4( c \translator Staff=two c )c | + \stemup c4( c \translator Staff=one c )c | + \translator Staff=two + \stemup c4( c \translator Staff=one c )c | + \translator Staff=two + \stemup c4( \translator Staff=one c c )c | + r2 + \translator Staff=two + \stemup c4( \translator Staff=one c + \break + c )c + r2 +% \stemdown c4( \translator Staff=two c c \translator Staff=one )c + \stemdown d4( \translator Staff=two c c \translator Staff=one )d + \translator Staff=two + \stemup c4( \translator Staff=one c c \translator Staff=two )c + r1 + } + \context Staff=two \notes\relative c'{ + \clef bass; + s1 s1 s1 s1 s1 s1 s1 s1 s1 s1 + } + > + \paper{ + \translator{ + \PianoStaffContext + minVerticalAlign = 3.0*\staffheight; + maxVerticalAlign = 3.0*\staffheight; + } + %linewidth=100.\mm; + } +} + +\version "1.2.0"; diff --git a/input/test/slur-interstaff.ly b/input/test/slur-interstaff.ly deleted file mode 100644 index e53a579f89..0000000000 --- a/input/test/slur-interstaff.ly +++ /dev/null @@ -1,39 +0,0 @@ -\score{ - \context PianoStaff < - \context Staff=one \notes\relative c'{ - \stemup c4( c \translator Staff=two c )c | - \translator Staff=one - \stemup c4( c \translator Staff=two c )c | - \stemup c4( c \translator Staff=one c )c | - \translator Staff=two - \stemup c4( c \translator Staff=one c )c | - \translator Staff=two - \stemup c4( \translator Staff=one c c )c | - r2 - \translator Staff=two - \stemup c4( \translator Staff=one c - \break - c )c - r2 -% \stemdown c4( \translator Staff=two c c \translator Staff=one )c - \stemdown d4( \translator Staff=two c c \translator Staff=one )d - \translator Staff=two - \stemup c4( \translator Staff=one c c \translator Staff=two )c - r1 - } - \context Staff=two \notes\relative c'{ - \clef bass; - s1 s1 s1 s1 s1 s1 s1 s1 s1 s1 - } - > - \paper{ - \translator{ - \PianoStaffContext - minVerticalAlign = 3.0*\staffheight; - maxVerticalAlign = 3.0*\staffheight; - } - %linewidth=100.\mm; - } -} - -\version "1.2.0"; diff --git a/input/test/uniform-breaking.ly b/input/test/uniform-breaking.ly new file mode 100644 index 0000000000..b07a7b21a6 --- /dev/null +++ b/input/test/uniform-breaking.ly @@ -0,0 +1,112 @@ +%{ +Hmm, ik vraag me af of dit al helemaal koel is. + + return abs (this_one.force_f_) + abs (prev.force_f_ - this_one.force_f_) + + break_penalties; + +Neem als voorbeeld iets dat lijkt op allemande: keuze tussen 2 of drie +maten per regel. + +* 2 lange maten -> lelie kiest 2 /regel :beetje los +* 3 korte -> lelie kiest 3 /regel :beetje krap +* 2 korte, 1 lange -> 3/regel :krap +* 1 korte, 2 lange -> 3/regel :erg krap +* 3 lange -> 3/regel :urg krap + +als je naar beloningen kijkt, kan ik me goed voorstellen dat sprong +van 'al wat krapper' naar los te groot wordt, en ze dus steeds krapper +wordt, tot urg krap aan toe, want kracht lineair? Dat lijkt ook geval +in allemande. + +Zie hoe eerst 10 en 9 mooi op 2maat/regel staan terwijl later tot 14 +toe 3/regel. + +Heb niet zomaar beter idee, nog. +%} + +\score{ + \notes\relative c'{ + % 10 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 ces c ces + + % 9 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 c ces c + + % 1 + c4 c c c + c4 c c c + c4 c c c + + % 2 + c4 c c c + c4 c c c + c4 c c8 c c c + + % 3 + c4 c c c + c4 c c c + c8 c c c c8 c c c + + % 4 + c4 c c c + c4 c c8 c c c + c8 c c c c8 c c c + + % 5 + c4 c c c + c8 c c c c8 c c c + c8 c c c c8 c c c + + % 6 + c4 c c8 c c c + % c4 c c c8 c + c8 c c c c8 c c c + c8 c c c c8 c c c + + % 7 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 c c c + + % 8 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 c c ces + + % 9 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 c ces c + + % 10 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c c8 ces c ces + + % 11 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c c ces8 c ces c + + % 12 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c c ces c8 ces c ces + + % 13 + c8 c c c c8 c c c + c8 c c c c8 c c c + c8 c ces c ces8 c ces c + + } + \paper { + indent=0.0\mm; + linewidth=90.0\mm; + } +} + + diff --git a/input/twinkle.ly b/input/twinkle.ly index bc8d67cbe3..847368ebeb 100644 --- a/input/twinkle.ly +++ b/input/twinkle.ly @@ -48,9 +48,6 @@ accompany = \notes \relative c { d b | c a | f g | c,2 } -global = \notes { - \time 2/4; -} tekst = \lyrics{ Al -- tijd is Kort -- jak -- je ziek, " " @@ -120,14 +117,16 @@ textiii = \lyrics{ \context Staff=i s1 \context Lyrics=top s1 \context GrandStaff < - \context Staff=ii \repeat semi 2 < \global\melody > - \context Staff=iii \repeat semi 2 < \global\accompany > + \context Staff=ii \repeat volta 2 < + \time 2/4; + \melody > + \context Staff=iii \repeat volta 2 < + \accompany > > \context Lyrics=bottom s1 % ugh, \repeat in \addlyrics dumps core \addlyrics - % \context Staff = i \repeat semi 2 <\global\melody> - \context Staff = i <\global\melody> + \context Staff = i < \melody> < %\repeat fold 2 {} %\alternative { diff --git a/lib/duration-convert.cc b/lib/duration-convert.cc index 5f3be55dd8..ac46fd7a60 100644 --- a/lib/duration-convert.cc +++ b/lib/duration-convert.cc @@ -44,7 +44,7 @@ Duration_convert::dur2ticks_i (Duration dur) { if (dur.ticks_i_) return dur.ticks_i_; - return dur2_mom (dur) * Moment (Duration::division_1_i_s); + return dur2_mom (dur) * Rational (Duration::division_1_i_s); } int @@ -67,22 +67,22 @@ Duration_convert::type2_i (int type) return 1 << type; } -Moment +Rational Duration_convert::dur2_mom (Duration dur) { if (dur.ticks_i_) - return Moment (dur.ticks_i_, Duration::division_1_i_s); + return Rational (dur.ticks_i_, Duration::division_1_i_s); // or simply assert? if (dur.durlog_i_<-10) - return Moment (0); - Moment mom; + return Rational (0); + Rational mom; if (dur.durlog_i_<0) - mom = Moment (type2_i (-dur.durlog_i_), 1); + mom = Rational (type2_i (-dur.durlog_i_), 1); else - mom = Moment (1 , type2_i (dur.durlog_i_)); + mom = Rational (1 , type2_i (dur.durlog_i_)); - Moment delta = mom; + Rational delta = mom; while (dur.dots_i_--) { delta /= 2.0; @@ -93,7 +93,7 @@ Duration_convert::dur2_mom (Duration dur) } Duration -Duration_convert::mom2_dur (Moment mom) +Duration_convert::mom2_dur (Rational mom) { if (!mom) { @@ -111,8 +111,8 @@ Duration_convert::mom2_dur (Moment mom) // dur.set_plet (type_mom, Duration::division_1_i_s / 4); - // Moment as_plet_mom = mom / dur.mom (); - Moment as_plet_mom = mom / dur.length_mom (); + // Rational as_plet_mom = mom / dur.mom (); + Rational as_plet_mom = mom / dur.length_mom (); as_plet_mom *= dur.plet_.mom (); long num = as_plet_mom.num (); long den = as_plet_mom.den (); @@ -121,7 +121,7 @@ Duration_convert::mom2_dur (Moment mom) } Duration -Duration_convert::mom2standardised_dur (Moment mom) +Duration_convert::mom2standardised_dur (Rational mom) { // if (!dur_array_s.length_i ()) if (!dur_array_s.size ()) @@ -129,12 +129,12 @@ Duration_convert::mom2standardised_dur (Moment mom) assert (dur_array_s.size ()); for (int i = 0; i < dur_array_s.size () - 1; i++) { - Moment lower_mom = dur2_mom (dur_array_s[ i ]); + Rational lower_mom = dur2_mom (dur_array_s[ i ]); if (mom <= lower_mom) { // all arbitrary, but 3/4 will get rid of the noise... // kinda ok - if (i || (mom / lower_mom > Moment (3, 4))) + if (i || (mom / lower_mom > Rational (3, 4))) return dur_array_s[ i ]; else { @@ -143,7 +143,7 @@ Duration_convert::mom2standardised_dur (Moment mom) return d; } } - Moment upper_mom = dur2_mom (dur_array_s[ i + 1 ]); + Rational upper_mom = dur2_mom (dur_array_s[ i + 1 ]); if ((mom < upper_mom) && ((mom - lower_mom) / lower_mom < (upper_mom - mom) / upper_mom)) @@ -164,14 +164,14 @@ Duration_convert::set_array () } -Moment +Rational Duration_convert::plet_factor_mom (Duration dur) { return dur.plet_.mom (); } Real -Duration_convert::sync_f (Duration dur, Moment mom) +Duration_convert::sync_f (Duration dur, Rational mom) { return mom / dur2_mom (dur); } @@ -179,7 +179,7 @@ Duration_convert::sync_f (Duration dur, Moment mom) Duration Duration_convert::ticks2_dur (int ticks_i) { - Moment mom (ticks_i, Duration::division_1_i_s); + Rational mom (ticks_i, Duration::division_1_i_s); if (midi_as_plet_b_s) return mom2_dur (mom); @@ -194,7 +194,7 @@ Duration_convert::ticks2_dur (int ticks_i) Duration Duration_convert::ticks2standardised_dur (int ticks_i) { - Moment mom (ticks_i, Duration::division_1_i_s); + Rational mom (ticks_i, Duration::division_1_i_s); Duration dur = mom2standardised_dur (mom); return dur; } diff --git a/lib/duration-iter.cc b/lib/duration-iter.cc index 9472c0217d..abb467d1c1 100644 --- a/lib/duration-iter.cc +++ b/lib/duration-iter.cc @@ -114,5 +114,5 @@ Duration_iterator::forward_dur () bool Duration_iterator::ok () { - return cursor_dur_.length_mom () <= Moment (4); + return cursor_dur_.length_mom () <= Rational (4); } diff --git a/lib/duration.cc b/lib/duration.cc index bd9435fd82..b2a5f84643 100644 --- a/lib/duration.cc +++ b/lib/duration.cc @@ -16,7 +16,7 @@ #include "string.hh" #include "source-file.hh" #include "source.hh" -#include "moment.hh" +#include "rational.hh" #include "duration.hh" #include "duration-convert.hh" #include "duration-iter.hh" @@ -42,13 +42,13 @@ Duration::duration_type_b (int t) } void -Duration::compress (Moment m) +Duration::compress (Rational m) { plet_.iso_i_ *= m.num_i (); plet_.type_i_ *= m.den_i (); } -Moment +Rational Duration::length_mom () const { return Duration_convert::dur2_mom (*this); diff --git a/lib/include/duration-convert.hh b/lib/include/duration-convert.hh index 11ee123ee0..980c62a6f5 100644 --- a/lib/include/duration-convert.hh +++ b/lib/include/duration-convert.hh @@ -1,5 +1,5 @@ /* - duration-convert.hh -- declare + duration-convert.hh -- declare Duration_convert source file of the LilyPond music typesetter @@ -11,7 +11,6 @@ #define DURATION_CONVERT_HH #include "duration.hh" #include "string.hh" -//#include "array.hh" #include "array.hh" /** @@ -19,13 +18,9 @@ That is including (integer + division) representation for MIDI, and conversion from unexact time representation (best guess :-). - A Moment (mom) is a Rational that holds the time fraction + A Rational (mom) is a Rational that holds the time fraction compared to a whole note (before also called wholes). - SUGGESTION: currently a moment in time is called moment too; - let-s typedef Rational When too, so that we get - When Staff_column::when (), Moment Voice_element::mom (). - [todo] move all statics to real members, instantiate Duration_convert object (s). @@ -51,27 +46,27 @@ struct Duration_convert { /// Return 0 if longer than whole note. static int type2_i (int type); - /// Return Moment representation (fraction of whole note). - static Moment dur2_mom (Duration dur ); + /// Return Rational representation (fraction of whole note). + static Rational dur2_mom (Duration dur ); /// Return Mudela string representation. static String dur2_str (Duration dur ); - /// Return duration from Moment (fraction of whole) representation. - static Duration mom2_dur (Moment mom ); + /// Return duration from Rational (fraction of whole) representation. + static Duration mom2_dur (Rational mom ); /// Return standardised duration, best guess if not exact. - static Duration mom2standardised_dur (Moment mom ); + static Duration mom2standardised_dur (Rational mom ); - /// Return plet factor (not a Moment: should use Rational?). - static Moment plet_factor_mom (Duration dur ); + /// Return plet factor (not a Rational: should use Rational?). + static Rational plet_factor_mom (Duration dur ); static void set_array (); /** Return synchronisation factor for mom, so that mom2_dur (mom / sync_f ) will return the duration dur. */ - static Real sync_f (Duration dur, Moment mom ); + static Real sync_f (Duration dur, Rational mom ); /// Return exact duration, in midi-ticks if not-exact. static Duration ticks2_dur (int ticks_i ); diff --git a/lib/include/duration.hh b/lib/include/duration.hh index a4f5cdc71c..28580b63af 100644 --- a/lib/include/duration.hh +++ b/lib/include/duration.hh @@ -13,7 +13,7 @@ #define DURATION_HH #include "fproto.hh" -#include "moment.hh" +#include "rational.hh" #include "plet.hh" /** @@ -27,11 +27,11 @@ struct Duration { bool plet_b (); String str () const; void set_plet (int,int ); - void compress (Moment); + void compress (Rational); static bool duration_type_b (int t); void set_ticks (int ticks_i ); - Moment length_mom () const ; + Rational length_mom () const ; static int division_1_i_s; /// Logarithm of the base duration. diff --git a/lib/include/moment.hh b/lib/include/moment.hh deleted file mode 100644 index d578fbc59a..0000000000 --- a/lib/include/moment.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - (c) 1996--98 Han-Wen Nienhuys -*/ - -#ifndef MOMENT_HH -#define MOMENT_HH - -#include -#include "rational.hh" - -class String; -typedef Rational Moment; - - -/** - A really big time-moment. - - Windhoze-suck-suck-suck-suck-suck-thank-you-cygnus - - I get tired of all these incompatibilities. Let's just assume that - INT_MAX is really, really, really big. - - Can't we name this Saint_jut_mom (Sintjuttemis ?) */ - - -const Moment infinity_mom = INT_MAX; - -#endif // - diff --git a/lib/include/plet.hh b/lib/include/plet.hh index dbb26da95d..42ef83b435 100644 --- a/lib/include/plet.hh +++ b/lib/include/plet.hh @@ -9,7 +9,7 @@ #ifndef PLET_HH #define PLET_HH -#include "moment.hh" +#include "rational.hh" /** The type and replacement value of a plet (triplet, quintuplet.) Conceptually the same as a rational, but 4/6 != 2/3. @@ -18,7 +18,7 @@ */ struct Plet { Plet (); - Moment mom () const; + Rational mom () const; bool unit_b () const; int iso_i_; // 2/3; 2 is not duration, maar of count! int type_i_; diff --git a/lib/moment.cc b/lib/moment.cc deleted file mode 100644 index a4c50d8d07..0000000000 --- a/lib/moment.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* - moment.cc -- implement Moment - - source file of the GNU LilyPond music typesetter - - (c) 1996, 1997--1999 Han-Wen Nienhuys -*/ - -#include -#include "string.hh" -#include "moment.hh" - diff --git a/lib/plet.cc b/lib/plet.cc index a145aa7ae4..e567515b7e 100644 --- a/lib/plet.cc +++ b/lib/plet.cc @@ -15,10 +15,10 @@ Plet::Plet () iso_i_ = 1; } -Moment +Rational Plet::mom () const { - return Moment (iso_i_, type_i_); + return Rational (iso_i_, type_i_); } bool diff --git a/lily/align-note-column-engraver.cc b/lily/align-note-column-engraver.cc index ddb83af5f2..c28320f301 100644 --- a/lily/align-note-column-engraver.cc +++ b/lily/align-note-column-engraver.cc @@ -50,10 +50,10 @@ Align_note_column_engraver::do_creation_processing () void Align_note_column_engraver::do_removal_processing () { - Scalar al = get_property ("graceAlignPosition", 0); - if (al.isdir_b ()) + SCM al = get_property ("graceAlignPosition", 0); + if (isdir_b (al)) { - align_item_p_->notehead_align_dir_ = Direction (int (al)); + align_item_p_->notehead_align_dir_ = to_dir (al); } typeset_element (align_item_p_); @@ -85,10 +85,13 @@ Align_note_column_engraver::process_acknowledged () B. it has no pscore_l_ field. */ - Scalar grsp = get_property ("graceAccidentalSpace", 0); - if (grsp.isnum_b ()) + SCM grsp = get_property ("graceAccidentalSpace", 0); + if (SCM_NUMBERP(grsp)) { - Real extra_space = double(grsp); + /* + ugh. + */ + Real extra_space = gh_scm2double(grsp); SCM e = gh_cons (gh_double2scm (-extra_space), gh_double2scm (0.0)); now_column_l_->set_elt_property (extra_space_scm_sym, e); } diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 69b9a4f6ed..7caf691c79 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -103,49 +103,53 @@ Auto_beam_engraver::consider_end_and_begin (Moment test_mom) /* second guess: property generic time exception */ - Scalar begin = get_property (time_str + "beamAutoBegin", 0); - if (begin.length_i ()) - begin_mom = begin.to_rat (); + SCM begin = get_property (time_str + "beamAutoBegin", 0); + if (SMOB_IS_TYPE_B(Moment, begin)) + begin_mom = * SMOB_TO_TYPE(Moment, begin); - Scalar end = get_property (time_str + "beamAutoEnd", 0); - if (end.length_i ()) - end_mom = end.to_rat (); + SCM end = get_property (time_str + "beamAutoEnd", 0); + if (SMOB_IS_TYPE_B (Moment, end)) + end_mom = * SMOB_TO_TYPE(Moment,end); /* third guess: property time exception, specific for duration type */ if (type_str.length_i ()) { - Scalar end_mult = get_property (time_str + "beamAutoEnd" + type_str, 0); - if (end_mult.length_i ()) - end_mom = end_mult.to_rat (); - Scalar begin_mult = get_property (time_str + "beamAutoBegin" + type_str, 0); - if (begin_mult.length_i ()) - begin_mom = begin_mult.to_rat (); + SCM end_mult = get_property (time_str + "beamAutoEnd" + type_str, 0); + if (SMOB_IS_TYPE_B (Moment, end_mult)) + end_mom = * SMOB_TO_TYPE (Moment,end_mult); + + SCM begin_mult = get_property (time_str + "beamAutoBegin" + type_str, 0); + if (SMOB_IS_TYPE_B (Moment, begin_mult)) + begin_mom = * SMOB_TO_TYPE (Moment,begin_mult); } /* fourth guess [user override]: property plain generic */ begin = get_property ("beamAutoBegin", 0); - if (begin.length_i ()) - begin_mom = begin.to_rat (); + if (SMOB_IS_TYPE_B(Moment, begin)) + begin_mom = * SMOB_TO_TYPE(Moment, begin); + + end = get_property ("beamAutoEnd", 0); - if (end.length_i ()) - end_mom = end.to_rat (); + if (SMOB_IS_TYPE_B (Moment, end)) + end_mom = * SMOB_TO_TYPE (Moment,end); /* fifth guess [user override]: property plain, specific for duration type */ if (type_str.length_i ()) { - Scalar end_mult = get_property (String ("beamAutoEnd") + type_str, 0); - if (end_mult.length_i ()) - end_mom = end_mult.to_rat (); - Scalar begin_mult = get_property (String ("beamAutoBegin") + type_str, 0); - if (begin_mult.length_i ()) - begin_mom = begin_mult.to_rat (); + SCM end_mult = get_property (String ("beamAutoEnd") + type_str, 0); + if (SMOB_IS_TYPE_B (Moment, end_mult)) + end_mom = * SMOB_TO_TYPE (Moment,end_mult); + + SCM begin_mult = get_property (String ("beamAutoBegin") + type_str, 0); + if (SMOB_IS_TYPE_B (Moment, begin_mult)) + begin_mom = * SMOB_TO_TYPE (Moment,begin_mult); } Rational r; @@ -160,8 +164,8 @@ Auto_beam_engraver::consider_end_and_begin (Moment test_mom) /* Allow already started autobeam to end */ - Scalar on = get_property ("noAutoBeaming", 0); - if (on.to_bool ()) + SCM on = get_property ("noAutoBeaming", 0); + if (gh_boolean_p (on) && gh_scm2bool (on)) return; if (begin_mom) @@ -200,20 +204,20 @@ Auto_beam_engraver::create_beam_p () } /* urg, copied from Beam_engraver */ - Scalar prop = get_property ("beamslopedamping", 0); - if (prop.isnum_b ()) - beam_p->set_elt_property (damping_scm_sym, gh_int2scm(prop)); + SCM prop = get_property ("beamslopedamping", 0); + if (SCM_NUMBERP(prop)) + beam_p->set_elt_property (damping_scm_sym, prop); prop = get_property ("autoKneeGap", 0); - if (prop.isnum_b ()) - beam_p->set_elt_property (auto_knee_gap_scm_sym, gh_int2scm(prop)); + if (SCM_NUMBERP(prop)) + beam_p->set_elt_property (auto_knee_gap_scm_sym, prop); prop = get_property ("autoInterstaffKneeGap", 0); - if (prop.isnum_b ()) - beam_p->set_elt_property (auto_interstaff_knee_gap_scm_sym, gh_int2scm( prop)); + if (SCM_NUMBERP(prop)) + beam_p->set_elt_property (auto_interstaff_knee_gap_scm_sym, prop); prop = get_property ("beamquantisation", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) beam_p->quantisation_ = (Beam::Quantisation)(int)prop; announce_element (Score_element_info (beam_p, 0)); @@ -281,7 +285,7 @@ Auto_beam_engraver::do_removal_processing () { /* finished beams may be typeset */ typeset_beam (); - /* but unfinished may need another announce/acknoledge pass */ + /* but unfinished may need another announce/acknowledge pass */ if (stem_l_arr_p_) junk_beam (); } @@ -289,9 +293,9 @@ Auto_beam_engraver::do_removal_processing () bool Auto_beam_engraver::same_grace_state_b (Score_element* e) { - bool gr = (e->get_elt_property (grace_scm_sym) != SCM_BOOL_F) ; - - return gr == get_property ("weAreGraceContext",0).to_bool (); + bool gr = e->get_elt_property (grace_scm_sym) != SCM_BOOL_F; + SCM wg =get_property ("weAreGraceContext",0); + return (gh_boolean_p (wg) && gh_scm2bool (wg)) == gr; } void diff --git a/lily/bar-engraver.cc b/lily/bar-engraver.cc index 2aa4904054..5811e6dc86 100644 --- a/lily/bar-engraver.cc +++ b/lily/bar-engraver.cc @@ -35,25 +35,24 @@ Bar_engraver::create_bar () bar_p_->set_elt_property (break_priority_scm_sym, gh_int2scm (0)); // urg: "" != empty... - String default_type = get_property ("defaultBarType", 0); - if (default_type.length_i ()) + SCM default_type = get_property ("defaultBarType", 0); + if (gh_string_p (default_type)) { - bar_p_->type_str_ = default_type; + bar_p_->type_str_ = ly_scm2string (default_type); } /* urg. Why did I implement this? */ - Scalar prop = get_property ("barAtLineStart", 0); - if (prop.to_bool ()) + SCM prop = get_property ("barAtLineStart", 0); + if (gh_boolean_p (prop) && gh_scm2bool (prop)) { bar_p_->set_elt_property (at_line_start_scm_sym, SCM_BOOL_T); } prop = get_property ("barSize", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - bar_p_->set_elt_property (bar_size_scm_sym, - gh_double2scm (Real(prop))); + bar_p_->set_elt_property (bar_size_scm_sym, prop); } announce_element (Score_element_info (bar_p_, 0)); } @@ -67,11 +66,10 @@ Bar_engraver::create_bar () void Bar_engraver::request_bar (String requested_type) { - Scalar prop = get_property ("barAtLineStart", 0); if (!now_mom ()) { - Scalar prop = get_property ("barAtLineStart", 0); - if (!prop.to_bool ()) + SCM prop = get_property ("barAtLineStart", 0); + if (!gh_boolean_p (prop) && gh_scm2bool (prop)) return; } bool bar_existed = bar_p_; diff --git a/lily/bar-script-engraver.cc b/lily/bar-script-engraver.cc index f5bfcacd91..12e94befc1 100644 --- a/lily/bar-script-engraver.cc +++ b/lily/bar-script-engraver.cc @@ -31,8 +31,8 @@ Bar_script_engraver::Bar_script_engraver () void Bar_script_engraver::do_creation_processing () { - Scalar prop = get_property (type_ + "HangOnClef", 0); - if (prop.to_bool ()) + SCM prop = get_property (type_ + "HangOnClef", 0); + if (gh_boolean_p (prop) && gh_scm2bool (prop)) { hang_on_clef_b_ = true; } @@ -141,10 +141,10 @@ Bar_script_engraver::create_items (Request *rq) text_p_ = new Text_item; text_p_->set_elt_property (breakable_scm_sym, SCM_BOOL_T); // ugh - Scalar prop = get_property (type_ + "Direction", 0); - if (prop.isnum_b ()) + SCM prop = get_property (type_ + "Direction", 0); + if (isdir_b (prop)) { - staff_side_p_->dir_ = (Direction) (int) prop; + staff_side_p_->dir_ = to_dir (prop); } else { @@ -153,10 +153,10 @@ Bar_script_engraver::create_items (Request *rq) staff_side_p_->set_victim(text_p_); - Scalar padding = get_property (type_ + "ScriptPadding", 0); - if (padding.length_i() && padding.isnum_b ()) + SCM padding = get_property (type_ + "ScriptPadding", 0); + if (SCM_NUMBERP(padding)) { - staff_side_p_->set_elt_property (padding_scm_sym, gh_double2scm(Real(padding))); + staff_side_p_->set_elt_property (padding_scm_sym, padding); } else { diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index 5ba4ed9306..6022a0a578 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -99,21 +99,21 @@ Beam_engraver::do_process_requests () /* urg, must copy to Auto_beam_engraver too */ - Scalar prop = get_property ("beamslopedamping", 0); - if (prop.isnum_b ()) - beam_p_->set_elt_property (damping_scm_sym, gh_int2scm( prop)); + SCM prop = get_property ("beamslopedamping", 0); + if (SCM_NUMBERP(prop)) + beam_p_->set_elt_property (damping_scm_sym, prop); prop = get_property ("autoKneeGap", 0); - if (prop.isnum_b ()) - beam_p_->set_elt_property (auto_knee_gap_scm_sym, gh_int2scm( prop)); + if (SCM_NUMBERP(prop)) + beam_p_->set_elt_property (auto_knee_gap_scm_sym, prop); prop = get_property ("autoInterstaffKneeGap", 0); - if (prop.isnum_b ()) - beam_p_->set_elt_property (auto_interstaff_knee_gap_scm_sym, gh_int2scm( prop)); + if (SCM_NUMBERP(prop)) + beam_p_->set_elt_property (auto_interstaff_knee_gap_scm_sym, prop); prop = get_property ("beamquantisation", 0); - if (prop.isnum_b ()) - beam_p_->quantisation_ = (Beam::Quantisation)(int)prop; + if (SCM_NUMBERP(prop)) + beam_p_->quantisation_ = (Beam::Quantisation)gh_scm2int(prop); announce_element (Score_element_info (beam_p_, reqs_drul_[START])); } @@ -173,7 +173,10 @@ Beam_engraver::acknowledge_element (Score_element_info info) bool stem_grace = stem_l->get_elt_property (grace_scm_sym) != SCM_BOOL_F; - if (get_property ("weAreGraceContext",0).to_bool () != stem_grace) + SCM wg =get_property ("weAreGraceContext",0); + bool wgb= gh_boolean_p (wg) && gh_scm2bool (wg); + + if (wgb!= stem_grace) return; Rhythmic_req *rhythmic_req = dynamic_cast (info.req_l_); diff --git a/lily/breathing-sign-engraver.cc b/lily/breathing-sign-engraver.cc index e9f243532b..2259c17097 100644 --- a/lily/breathing-sign-engraver.cc +++ b/lily/breathing-sign-engraver.cc @@ -21,7 +21,6 @@ TODO: #include "note-head.hh" #include "local-key-item.hh" -#include Breathing_sign_engraver::Breathing_sign_engraver() { @@ -46,9 +45,9 @@ Breathing_sign_engraver::do_process_requests() if(breathing_sign_req_l_) { breathing_sign_p_ = new Breathing_sign; - Scalar prop = get_property ("verticalDirection", 0); - if(prop.isnum_b()) - breathing_sign_p_->set_vertical_position((Direction)int(prop)); + SCM prop = get_property ("verticalDirection", 0); + if(isdir_b(prop)) + breathing_sign_p_->set_vertical_position(to_dir (prop)); announce_element (Score_element_info (breathing_sign_p_, breathing_sign_req_l_)); } diff --git a/lily/breathing-sign.cc b/lily/breathing-sign.cc index 4c36f261aa..0fff51106f 100644 --- a/lily/breathing-sign.cc +++ b/lily/breathing-sign.cc @@ -18,7 +18,6 @@ TODO: --> see breathing-sign-engraver.cc #include "dimensions.hh" #include "direction.hh" -#include Breathing_sign::Breathing_sign () { diff --git a/lily/change-iterator.cc b/lily/change-iterator.cc index e932c794fe..4fa7c519e4 100644 --- a/lily/change-iterator.cc +++ b/lily/change-iterator.cc @@ -21,6 +21,9 @@ Change_iterator::error (String reason) String warn1 = _f ("Can't change `%s' to `%s'", to_type, to_id) + ": " + reason; + /* + GUHG! + */ String warn2= "Change_iterator::do_process_and_next (): " + report_to_l ()->type_str_ + " = `" + report_to_l ()->id_str_ + "': "; diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 487514ff26..d0005c8983 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -56,8 +56,8 @@ Chord_name_engraver::do_process_requests () Chord chord (pitch_arr_); Musical_pitch* inversion = 0; - Scalar chord_inversion = get_property ("chordInversion", 0); - if (chord_inversion.to_bool ()) + SCM chord_inversion = get_property ("chordInversion", 0); + if (gh_boolean_p (chord_inversion) && gh_scm2bool (chord_inversion)) { int tonic_i = tonic_req_ ? chord.find_notename_i (tonic_req_->pitch_) : chord.find_tonic_i (); @@ -76,16 +76,16 @@ Chord_name_engraver::do_process_requests () - switch on property, add american (?) chordNameStyle: Chord::american_str (...) - Scalar chordNameStyle = get_property ("chordNameStyle", 0); + SCM chordNameStyle = get_property ("chordNameStyle", 0); if (chordNameStyle == "Banter") item_p->text_str_ = chord.banter_str (inversion); */ item_p->text_str_ = chord.banter_str (inversion); - Scalar style = get_property ("textStyle", 0); - if (style.length_i ()) - item_p->style_str_ = style; + SCM style = get_property ("textStyle", 0); + if (gh_string_p (style)) + item_p->style_str_ = ly_scm2string (style); text_p_arr_.push (item_p); announce_element (Score_element_info (item_p, 0)); diff --git a/lily/clef-engraver.cc b/lily/clef-engraver.cc index 060b0ad2af..68d96cef59 100644 --- a/lily/clef-engraver.cc +++ b/lily/clef-engraver.cc @@ -157,9 +157,9 @@ void Clef_engraver::do_creation_processing() { create_default_b_ = true; // should read property. - Scalar def = get_property ("createInitdefaultClef", 0); - if (def.to_bool ()) // egcs: Scalar to bool is ambiguous - set_type (def); + SCM def = get_property ("createInitdefaultClef", 0); + if (gh_string_p (def)) + set_type (ly_scm2string (def)); if (clef_type_str_.length_i ()) { @@ -191,10 +191,9 @@ Clef_engraver::create_clef() { Clef_item *c= new Clef_item; c->set_elt_property (break_priority_scm_sym, gh_int2scm (-2)); // ugh - String clefstyle = get_property ("clefStyle", 0); - if (clefstyle.length_i ()) - c->set_elt_property (style_scm_sym, - ly_ch_C_to_scm (clefstyle.ch_C())); + SCM clefstyle = get_property ("clefStyle", 0); + if (gh_string_p(clefstyle)) + c->set_elt_property (style_scm_sym, clefstyle); announce_element (Score_element_info (c, clef_req_l_)); clef_p_ = c; @@ -218,8 +217,11 @@ Clef_engraver::do_process_requests() } else if (create_default_b_) { - String type = get_property ("defaultClef", 0); - set_type (type.length_i () ? type : "treble"); + SCM type = get_property ("defaultClef", 0); + if (gh_string_p (type)) + set_type (ly_scm2string (type)); + else + set_type ( "treble"); create_clef (); create_default_b_ =0; } diff --git a/lily/column-x-positions.cc b/lily/column-x-positions.cc index eb4c983701..2532610973 100644 --- a/lily/column-x-positions.cc +++ b/lily/column-x-positions.cc @@ -14,11 +14,11 @@ Column_x_positions::Column_x_positions() { energy_f_ = infinity_f; satisfies_constraints_b_ = false; + force_f_ = 0; } Column_x_positions::~Column_x_positions() { - } diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 4c3db32bb4..2933131c8d 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -114,9 +114,6 @@ Dynamic_engraver::do_process_requests() text_p_ = new Text_item; text_p_->text_str_ = loud; // ugh - Scalar prop = get_property ("dynamicStyle", 0); - - text_p_->style_str_ = prop.length_i () ? prop : "dynamic"; staff_side_p_ = new Staff_side_item; staff_side_p_->set_elt_property (script_priority_scm_sym, @@ -127,16 +124,16 @@ Dynamic_engraver::do_process_requests() staff_side_p_->dir_ = DOWN; - prop = get_property ("verticalDirection", 0); - if (prop.isdir_b()) + SCM prop = get_property ("verticalDirection", 0); + if (isdir_b (prop)) { - staff_side_p_->dir_ = Direction (int (prop)); + staff_side_p_->dir_ = to_dir (prop); } prop = get_property ("dynamicDirection", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - staff_side_p_->dir_ = (Direction) (int) prop; + staff_side_p_->dir_ = to_dir (prop); } if (absd->dir_) { @@ -144,10 +141,9 @@ Dynamic_engraver::do_process_requests() } prop = get_property ("dynamicPadding", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - staff_side_p_->set_elt_property (padding_scm_sym, - gh_double2scm(Real(prop))); + staff_side_p_->set_elt_property (padding_scm_sym, prop); } announce_element (Score_element_info (text_p_, absd)); announce_element (Score_element_info (staff_side_p_, absd)); @@ -173,21 +169,20 @@ Dynamic_engraver::do_process_requests() - Scalar prop = get_property ("verticalDirection", 0); - if (prop.isdir_b()) + SCM prop = get_property ("verticalDirection", 0); + if (isdir_b (prop)) { - to_end_ss_span_p_->dir_ = Direction (int (prop)); + to_end_ss_span_p_->dir_ = to_dir (prop); } prop = get_property ("dynamicDirection", 0); - if (prop.isdir_b ()) + if (isdir_b (prop)) { - to_end_ss_span_p_->dir_ = (Direction) (int) prop; + to_end_ss_span_p_->dir_ = to_dir (prop); } prop = get_property ("dynamicPadding", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - to_end_ss_span_p_->set_elt_property (padding_scm_sym, - gh_double2scm(Real(prop))); + to_end_ss_span_p_->set_elt_property (padding_scm_sym,prop); } } } diff --git a/lily/font-size-engraver.cc b/lily/font-size-engraver.cc index 30f47498c9..b8d91ae55c 100644 --- a/lily/font-size-engraver.cc +++ b/lily/font-size-engraver.cc @@ -19,11 +19,11 @@ Font_size_engraver::Font_size_engraver () void Font_size_engraver::do_process_requests () { - Scalar s (get_property ("fontSize", 0)); + SCM s (get_property ("fontSize", 0)); - if (s.length_i () && s.isnum_b ()) + if (SCM_NUMBERP(s)) { - size_i_ = int (s); + size_i_ = gh_scm2int (s); } } diff --git a/lily/gourlay-breaking.cc b/lily/gourlay-breaking.cc index 63a6adc624..0e0ea46f4b 100644 --- a/lily/gourlay-breaking.cc +++ b/lily/gourlay-breaking.cc @@ -40,6 +40,7 @@ struct Break_node { { prev_break_i_ = -1; line_i_ = 0; + demerits_f_ = 0; } }; @@ -56,10 +57,7 @@ Gourlay_breaking::do_solve () const optimal_paths.set_size (breaks.size ()); Break_node first_node ; - first_node.prev_break_i_ = -1; - first_node.line_config_.force_f_ = 0; first_node.line_config_.energy_f_ = 0; - first_node.line_i_ = 0; optimal_paths[0] = first_node; int break_idx=1; diff --git a/lily/grace-position-performer.cc b/lily/grace-position-performer.cc index 41cee8065e..58bdd73d6f 100644 --- a/lily/grace-position-performer.cc +++ b/lily/grace-position-performer.cc @@ -61,9 +61,9 @@ Grace_position_performer::process_acknowledged () shortest_mom = shortest_mom length_mom_; Rational grace_fraction_rat (1, 2); - Scalar prop = get_property ("graceFraction", 0); - if (prop.length_i ()) - grace_fraction_rat = prop.to_rat (); + SCM prop = get_property ("graceFraction", 0); + if (SMOB_IS_TYPE_B(Moment, prop)) + grace_fraction_rat = *SMOB_TO_TYPE (Moment,prop); delay_mom = shortest_mom * grace_fraction_rat; for (int i=0; i < notes_.size (); i++) diff --git a/lily/identifier.cc b/lily/identifier.cc index 0fbaa06185..e8421fb70d 100644 --- a/lily/identifier.cc +++ b/lily/identifier.cc @@ -14,7 +14,7 @@ #include "my-lily-lexer.hh" #include "debug.hh" #include "request.hh" -#include "translator.hh" +#include "translator-group.hh" #include "notename-table.hh" @@ -79,7 +79,7 @@ Class ## _identifier::do_print () const { \ -DEFAULT_PRINT(Translator); +DEFAULT_PRINT(Translator_group); DEFAULT_PRINT(Music); DEFAULT_PRINT(Request); DEFAULT_PRINT(Score); @@ -95,7 +95,7 @@ Class ## _identifier::do_str () const { \ DUMMY_STR(Notename_table); -DUMMY_STR(Translator); +DUMMY_STR(Translator_group); DUMMY_STR(Music); DUMMY_STR(Request); DUMMY_STR(Score); @@ -144,7 +144,7 @@ Class ## _identifier::access_content_ ## Class (bool copy_b) const {\ Class*\ Class ## _identifier::access_content_ ## Class (bool copy_b) const{\ ((Class ## _identifier*)this)->accessed_b_ = true;\ - return copy_b ? (Class*)data_p_->clone() : data_p_;\ + return copy_b ? dynamic_cast (data_p_->clone()) : data_p_;\ } #define IMPLEMENT_ID_CLASS(Class) \ @@ -162,7 +162,7 @@ Class ## _identifier::Class ## _identifier (Class ## _identifier const &s) \ IMPLEMENT_ID_CLASS(Duration); -IMPLEMENT_ID_CLASS(Translator); +IMPLEMENT_ID_CLASS(Translator_group); IMPLEMENT_ID_CLASS(int); IMPLEMENT_ID_CLASS(Real); IMPLEMENT_ID_CLASS(String); @@ -174,7 +174,7 @@ IMPLEMENT_ID_CLASS(Paper_def); IMPLEMENT_ID_CLASS(Notename_table); VIRTUAL_ACCESSOR(Music); VIRTUAL_ACCESSOR(Request); -VIRTUAL_ACCESSOR(Translator); +VIRTUAL_ACCESSOR(Translator_group); DEFAULT_ACCESSOR(Notename_table); DEFAULT_ACCESSOR(Duration); DEFAULT_ACCESSOR(int); diff --git a/lily/includable-lexer.cc b/lily/includable-lexer.cc index 89c7483478..961089bf62 100644 --- a/lily/includable-lexer.cc +++ b/lily/includable-lexer.cc @@ -66,7 +66,7 @@ Includable_lexer::new_input (String s, Sources * global_sources) Whoops. The size argument to yy_create_buffer is not the filelength but a BUFFERSIZE. Maybe this is why reading stdin fucks up. - */ + */ yy_switch_to_buffer (yy_create_buffer (sl->istream_l (), YY_BUF_SIZE)); } @@ -102,10 +102,10 @@ Includable_lexer::close_input () return false; } else - { - yy_switch_to_buffer (state_stack_.pop ()); - return true; - } + { + yy_switch_to_buffer (state_stack_.pop ()); + return true; + } } char const* diff --git a/lily/include/clef-engraver.hh b/lily/include/clef-engraver.hh index 35ae82c19b..47e64af617 100644 --- a/lily/include/clef-engraver.hh +++ b/lily/include/clef-engraver.hh @@ -10,7 +10,6 @@ #ifndef CLEF_GRAV_HH #define CLEF_GRAV_HH -#include "scalar.hh" #include "array.hh" #include "engraver.hh" #include "direction.hh" diff --git a/lily/include/global-translator.hh b/lily/include/global-translator.hh index 721f97ddaf..00f8ed8204 100644 --- a/lily/include/global-translator.hh +++ b/lily/include/global-translator.hh @@ -11,7 +11,7 @@ #define GLOBAL_TRANSLATOR_HH #include "translator-group.hh" -#include "rational.hh" +#include "moment.hh" #include "pqueue.hh" diff --git a/lily/include/header.hh b/lily/include/header.hh index 32907cdbe7..2a31d99266 100644 --- a/lily/include/header.hh +++ b/lily/include/header.hh @@ -15,9 +15,5 @@ #include "scope.hh" -/** Store bibliographical information. The information in the \header - block is read into this struct. Lily does not process this - information. */ -typedef Scope Header; #endif // HEADER_HH diff --git a/lily/include/identifier.hh b/lily/include/identifier.hh index 4d705020fb..ded6ac4a0e 100644 --- a/lily/include/identifier.hh +++ b/lily/include/identifier.hh @@ -16,7 +16,7 @@ #define DECLARE_TYPE_NAME(Class) class Notename_table_identifier; -class Translator_identifier; +class Translator_group_identifier; class Music_identifier; class Articulation_req_identifier; class Symtables_identifier; @@ -51,7 +51,7 @@ struct Identifier : public Input { void error (String) const; String str () const; - IDACCESSOR(Translator) + IDACCESSOR(Translator_group) IDACCESSOR(Notename_table) IDACCESSOR(Music) IDACCESSOR(Symtables) @@ -84,7 +84,7 @@ struct Class ## _identifier : Identifier {\ }\ -DECLARE_ID_CLASS(Translator); +DECLARE_ID_CLASS(Translator_group); DECLARE_ID_CLASS(Duration); DECLARE_ID_CLASS(Notename_table); DECLARE_ID_CLASS(Real); diff --git a/lily/include/key.hh b/lily/include/key.hh index 140db77927..af89371f22 100644 --- a/lily/include/key.hh +++ b/lily/include/key.hh @@ -8,7 +8,6 @@ #define KEY_HH #include "array.hh" -#include "scalar.hh" #include "lily-proto.hh" /// administration of current key in one octave. diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 90773ac8d1..994489c411 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -24,6 +24,7 @@ SCM ly_set_scm (String name , SCM val); SCM ly_append (SCM a, SCM b); SCM ly_eval (SCM a); SCM ly_func_o (char const* name); +SCM ly_parse_scm (char const* s, int* n); SCM ly_quote_scm (SCM s); void ly_display_scm (SCM s); String ly_scm2string (SCM s); @@ -31,21 +32,32 @@ SCM array_to_list (SCM *a , int l); #include "array.hh" -#include "scalar.hh" - void read_lily_scm_file (String); void init_lily_guile (); #include "ly-symbols.hh" -/* - Do It Yourself GC protection. - */ -SCM ly_protect_scm (SCM s); -SCM ly_unprotect_scm (SCM s); void init_ly_protection (); +unsigned int ly_scm_hash (SCM s); SCM index_cell (SCM cellp, Direction d); + +/* + snarfing. + */ +void add_scm_init_func (void (*)()); + +#define ADD_SCM_INIT_FUNC(name, func)\ +class name ## _scm_initter { \ +public:\ + name ## _scm_initter () \ + { \ + add_scm_init_func (func); \ + } \ +} _ ## name ## _scm_initter; \ +/* end define */ + + #endif // LILY_GUILE_HH diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index d3c177c2a6..9e397a0ad2 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -55,14 +55,14 @@ struct Bracket_req; struct Break_align_item; struct Break_req; struct CHyphen_req; -struct Chord_tremolo; -struct Chord_tremolo_engraver; -struct Chord_tremolo_req; struct Cadenza_req; struct Change_iterator; struct Change_translator; struct Chord; struct Chord_name_engraver; +struct Chord_tremolo; +struct Chord_tremolo_engraver; +struct Chord_tremolo_req; struct Clef_change_req; struct Clef_engraver; struct Clef_item; @@ -113,7 +113,6 @@ struct Lily_stream; struct Line_group_engraver; struct Line_of_score; struct Line_of_staff; -struct Simple_spacer; struct Linestaff; struct Local_key; struct Local_key_engraver; @@ -208,6 +207,7 @@ struct Script_req; struct Separating_group_spanner; struct Sequential_music; struct Simple_music; +struct Simple_spacer; struct Simultaneous_music; struct Single_malt_grouping_item; struct Skip_req; @@ -267,8 +267,7 @@ struct Unfolded_repeat_iterator; struct Vertical_brace; struct Vertical_spanner; struct Volta_spanner; +struct Moment; -typedef Rational Moment; -typedef Scope Header; #endif // LILY_PROTO_HH diff --git a/lily/include/ly-smobs.icc b/lily/include/ly-smobs.icc new file mode 100644 index 0000000000..2bb82ae41b --- /dev/null +++ b/lily/include/ly-smobs.icc @@ -0,0 +1,75 @@ +/* + ly-smobs.icc -- implement smob glue. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef LY_SMOBS_ICC +#define LY_SMOBS_ICC + +#define IMPLEMENT_SMOBS(CL)\ +long CL::smob_tag_;\ +static scm_smobfuns CL ## _funs = { \ + CL::mark_smob, CL::free_smob, \ + CL::print_smob, 0, \ +}; \ +void \ +CL::init_smobs () \ +{ \ + smob_tag_ = scm_newsmob (&CL ## _funs); \ +} \ + \ + \ +void \ +CL::unsmobify_self () \ +{ \ + SCM s = self_scm_; \ + scm_unprotect_object (s); \ + \ + SCM_CAR(self_scm_) = SCM_EOL; \ + SCM_CDR(self_scm_) = SCM_EOL; \ + self_scm_ = SCM_EOL; \ +} \ +\ +SCM \ +CL::smobify_self () \ +{ \ + if (self_scm_ != SCM_EOL) \ + return self_scm_; \ + \ + /* \ + This is local. We don't assign to self_scm_ directly, to assure \ + that S isn't GC-ed from under us. \ + */ \ + SCM s; \ + \ + SCM_NEWCELL(s); \ + self_scm_ = s; \ + \ + SCM_SETCAR(s,smob_tag_); \ + void * me_p = this; \ + SCM_SETCDR(s,me_p); \ + scm_protect_object (s); \ + \ + do_smobify_self(); \ + return s; \ +} \ +scm_sizet \ +CL::free_smob (SCM ses) \ +{ \ + CL * s = (CL*) SCM_CDR(ses); \ + /* someone else did the deed already; this might be an automatic var.*/ \ + if (s->self_scm_ != ses)\ + return 0; \ + SCM_CAR(ses) = SCM_EOL;\ + \ + return sizeof(CL); \ +} \ +ADD_SCM_INIT_FUNC(CL, CL::init_smobs)\ + + +#endif /* LY_SMOBS_ICC */ + diff --git a/lily/include/ly-symbols.hh b/lily/include/ly-symbols.hh index f0f3dd098d..0e3f1cf746 100644 --- a/lily/include/ly-symbols.hh +++ b/lily/include/ly-symbols.hh @@ -60,6 +60,7 @@ DECLARE_LY_SYMBOL(notewidth); DECLARE_LY_SYMBOL(non_default); DECLARE_LY_SYMBOL(non_rhythmic); DECLARE_LY_SYMBOL(no_staff_support); +DECLARE_LY_SYMBOL(no_stem_extend); DECLARE_LY_SYMBOL(octave_dir); DECLARE_LY_SYMBOL(origin); DECLARE_LY_SYMBOL(output); diff --git a/lily/include/midi-stream.hh b/lily/include/midi-stream.hh index f367d62a2a..06c4f84ffc 100644 --- a/lily/include/midi-stream.hh +++ b/lily/include/midi-stream.hh @@ -7,7 +7,6 @@ #ifndef MIDI_STREAM_HH #define MIDI_STREAM_HH -#include #include "string.hh" /// Midi outputfile diff --git a/lily/include/moment.hh b/lily/include/moment.hh new file mode 100644 index 0000000000..53942657fc --- /dev/null +++ b/lily/include/moment.hh @@ -0,0 +1,53 @@ +/* + moment.hh -- declare Moment + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef MOMENT_HH +#define MOMENT_HH + +#include "smobs.hh" +#include "rational.hh" + +/** + Rationals with glue for Guilification; + */ +struct Moment : public Rational +{ + Moment () { self_scm_ = SCM_EOL; } + Moment (int m) : Rational (m) {self_scm_ = SCM_EOL; } + Moment (int m, int n) : Rational (m,n) {self_scm_ = SCM_EOL; } + Moment (Rational m) : Rational (m) {self_scm_ = SCM_EOL; } + ~Moment (); + + DECLARE_SMOBS; +}; + +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, / ); +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, + ); +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, * ); +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, - ); +IMPLEMENT_ARITHMETIC_OPERATOR (Moment, % ); + +INSTANTIATE_COMPARE (Moment const&, Rational::compare); + + +/** + A really big time-moment. + + Windhoze-suck-suck-suck-suck-suck-thank-you-cygnus + + I get tired of all these incompatibilities. Let's just assume that + INT_MAX is really, really, really big. + + Can't we name this Saint_jut_mom (Sintjuttemis ?) */ + +/* URG ! WE HAVE TWO RATIONAL INFINITIES! */ +const Moment infinity_mom = INT_MAX; + +#endif /* MOMENT_HH */ + diff --git a/lily/include/music-iterator.hh b/lily/include/music-iterator.hh index d5ca0e0560..f7d9c061e3 100644 --- a/lily/include/music-iterator.hh +++ b/lily/include/music-iterator.hh @@ -28,8 +28,6 @@ class Music_iterator { Interpretation_context_handle handle_; protected: - bool playback_b_; // Should use SCMs - Music const * music_l_; /// ugh. JUNKME @@ -75,9 +73,9 @@ public: void set_translator (Translator_group*); /** Get an iterator matching the type of MUS, and use TRANS to find - an accompanying translation unit. Repeated music can be fully - unfolded by setting PLAYING */ - static Music_iterator* static_get_iterator_p (Music const* mus, bool playing); + an accompanying translation unit + */ + static Music_iterator* static_get_iterator_p (Music const* mus); void init_translator (Music const *, Translator_group *); Music_iterator(); diff --git a/lily/include/music-output-def.hh b/lily/include/music-output-def.hh index 9007903714..45644294ee 100644 --- a/lily/include/music-output-def.hh +++ b/lily/include/music-output-def.hh @@ -25,9 +25,6 @@ public: Scope *scope_p_; Array filename_str_arr_; - - - Music_output_def (Music_output_def const&); Music_output_def (); @@ -39,8 +36,8 @@ public: Global_translator *get_global_translator_p (); Translator_group *get_group_translator_p (String type) const; - String get_default_output () const; - void assign_translator (Translator*); + String get_default_output () const; + void assign_translator (Translator_group*); Translator * find_translator_l (String) const; virtual int get_next_default_count () const; }; diff --git a/lily/include/paper-stream.hh b/lily/include/paper-stream.hh index e5429511f6..f7e3bf5624 100644 --- a/lily/include/paper-stream.hh +++ b/lily/include/paper-stream.hh @@ -1,7 +1,6 @@ #ifndef PAPER_STREAM_HH #define PAPER_STREAM_HH -#include #include "string.hh" /** Paper output @@ -23,7 +22,7 @@ public: Paper_stream (String filename); /// delegate conversion to scalar class - Paper_stream &operator <<(Scalar); + Paper_stream &operator <<(String); /// close the file ~Paper_stream(); diff --git a/lily/include/property-inspect.hh b/lily/include/property-inspect.hh new file mode 100644 index 0000000000..31d26ac3e9 --- /dev/null +++ b/lily/include/property-inspect.hh @@ -0,0 +1,20 @@ +/* + property-inspect.hh -- declare various property related funcs. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef PROPERTY_INSPECT_HH +#define PROPERTY_INSPECT_HH + +#include "direction.hh" +#include "lily-guile.hh" + +bool isdir_b (SCM s); +Direction to_dir (SCM s); + +#endif /* PROPERTY_INSPECT_HH */ + diff --git a/lily/include/scm-hash.hh b/lily/include/scm-hash.hh new file mode 100644 index 0000000000..a0382d0446 --- /dev/null +++ b/lily/include/scm-hash.hh @@ -0,0 +1,32 @@ +/* + scm-hash.hh -- declare Scheme hasher. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef SCM_HASH_HH +#define SCM_HASH_HH + +#include "lily-guile.hh" +#include "hash-table.hh" +#include "smobs.hh" + +/** + auto resizing hash table. This should come from GUILE. + */ +class Scheme_hash_table : public Hash_table +{ +public: + Scheme_hash_table (); + void operator = (Scheme_hash_table const &); + Scheme_hash_table (Scheme_hash_table const &); + virtual ~Scheme_hash_table (); + DECLARE_SMOBS; + SCM to_alist () const; +}; + +#endif /* SCM_HASH_HH */ + diff --git a/lily/include/score-element.hh b/lily/include/score-element.hh index 25a30532ff..c9b1a30188 100644 --- a/lily/include/score-element.hh +++ b/lily/include/score-element.hh @@ -11,7 +11,7 @@ #include "virtual-methods.hh" #include "graphical-element.hh" #include "lily-guile.hh" - +#include "smobs.hh" typedef void (Score_element::*Score_element_method_pointer) (void); @@ -148,13 +148,8 @@ protected: static Interval dim_cache_callback (Dimension_cache*); public: - SCM smobify_self (); - static SCM mark_smob (SCM); - static scm_sizet free_smob (SCM s); - static int print_smob (SCM s, SCM p, scm_print_state*); - static long smob_tag; - static void init_smobs(); - SCM self_scm_; + + DECLARE_SMOBS; }; diff --git a/lily/include/smobs.hh b/lily/include/smobs.hh new file mode 100644 index 0000000000..a038db298e --- /dev/null +++ b/lily/include/smobs.hh @@ -0,0 +1,50 @@ +/* + smobs.hh -- declare smob related stuff. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#ifndef SMOBS_HH +#define SMOBS_HH + +#include "lily-guile.hh" + +/** + A smob is a C++ class with static member functions to glue it with + Scheme. Every instance carries SELF_SCM_, a pointer to the Scheme + smob of itself. Upon destruction, SELF_SCM_ is set to SCM_EOL. + + smob_free() checks if SELF_SCM_ equals its argument, so we can also + use a smobbified object on the stack: the destruction will happen + before GC hits the object. + + This is discouraged, though, because it causes memory leaks, and has + weird semantics. + + +*/ + +#define DECLARE_SMOBS \ + SCM smobify_self (); \ + static SCM mark_smob (SCM); \ + static scm_sizet free_smob (SCM s); \ + static int print_smob (SCM s, SCM p, scm_print_state*); \ + static long smob_tag_; \ + static void init_smobs(); \ + void unsmobify_self ();\ + void do_smobify_self();\ + SCM self_scm_; + + +/** + Check if S is of the specified C++ class. + */ +#define SMOB_IS_TYPE_B(TYPE, S) (SCM_NIMP((S)) && SCM_CAR((S)) == TYPE::smob_tag_) + +/// Cast S. No checks are done. +#define SMOB_TO_TYPE(TYPE, S) ((TYPE*) SCM_CDR((S))) +#endif /* SMOBS_HH */ + diff --git a/lily/include/translation-property.hh b/lily/include/translation-property.hh index 3e55b46a61..8278dd829d 100644 --- a/lily/include/translation-property.hh +++ b/lily/include/translation-property.hh @@ -11,7 +11,8 @@ #define TRANSLATION_PROPERTY_HH #include "music.hh" -#include "scalar.hh" +#include "protected-scm.hh" + /** Set a property of Translator @@ -20,7 +21,8 @@ class Translation_property : public Music { public: String var_str_; - Scalar value_; + Protected_scm value_; + VIRTUAL_COPY_CONS(Music); protected: diff --git a/lily/include/translator-group.hh b/lily/include/translator-group.hh index 4868940bb8..00da2cd391 100644 --- a/lily/include/translator-group.hh +++ b/lily/include/translator-group.hh @@ -16,6 +16,8 @@ #include "translator.hh" #include "cons.hh" #include "parray.hh" +#include "scm-hash.hh" + // egcs typedef void (Translator::*Method_pointer)(void); @@ -28,7 +30,7 @@ class Translator_group : public virtual Translator { Array consists_str_arr_; Array consists_end_str_arr_; Array accepts_str_arr_; - Dictionary properties_dict_; + Scheme_hash_table properties_dict_; int iterator_count_; friend class Interpretation_context_handle; @@ -36,8 +38,8 @@ class Translator_group : public virtual Translator { Cons_list trans_p_list_; public: - Scalar get_property (String type_str, Translator_group **where_found_l) const; - void set_property (String var_name, Scalar value); + SCM get_property (String type_str, Translator_group **where_found_l) const; + void set_property (String var_name, SCM value); String id_str_; @@ -73,10 +75,11 @@ public: Link_array path_to_acceptable_translator (String alias) const; Translator_group*get_default_interpreter(); + virtual ~Translator_group (); + protected: bool try_music_on_nongroup_children (Music *m); - virtual ~Translator_group (); virtual void do_print () const; virtual void do_process_requests (); virtual void do_add_processing (); diff --git a/lily/include/translator.hh b/lily/include/translator.hh index d2db7b13e4..ec0feb943f 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -13,7 +13,7 @@ #include "string.hh" #include "lily-proto.hh" #include "virtual-methods.hh" -#include "scalar.hh" +#include "property-inspect.hh" #include "dictionary.hh" #include "parray.hh" #include "input.hh" @@ -59,7 +59,7 @@ public: ask daddy for a feature */ Music_output_def *output_def_l () const; - Scalar get_property (String, Translator_group **) const; + SCM get_property (String, Translator_group **) const; virtual Moment now_mom () const; protected: diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc index 66c1463383..6e571d4fcb 100644 --- a/lily/key-engraver.cc +++ b/lily/key-engraver.cc @@ -48,7 +48,7 @@ Key_engraver::create_key () item_p_->add (m_l.notename_i_, a); } - for (int i = 0 ; i< old_accidental_idx_arr_.size(); i++) + for (int i = 0 ; i < old_accidental_idx_arr_.size(); i++) { Musical_pitch m_l =old_accidental_idx_arr_[i]; int a =m_l.accidental_i_; @@ -80,8 +80,8 @@ Key_engraver::acknowledge_element (Score_element_info info) { if (dynamic_cast (info.req_l_)) { - int i= get_property ("createKeyOnClefChange", 0).length_i (); - if (i) + SCM c = get_property ("createKeyOnClefChange", 0); + if (gh_boolean_p (c) && gh_scm2bool (c)) create_key (); } else if (dynamic_cast (info.elem_l_) @@ -126,11 +126,9 @@ Key_engraver::read_req (Key_change_req const * r) { old_accidental_idx_arr_ = accidental_idx_arr_; key_.clear (); - Scalar prop = get_property ("keyOctaviation", 0); - if (prop.length_i () > 0) - { - key_.multi_octave_b_ = ! prop.to_bool (); - } + SCM prop = get_property ("keyOctaviation", 0); + + key_.multi_octave_b_ = gh_boolean_p (prop) && gh_scm2bool (prop); accidental_idx_arr_.clear (); @@ -196,7 +194,4 @@ Key_engraver::do_post_move_processing () old_accidental_idx_arr_.clear (); } - - ADD_THIS_TRANSLATOR (Key_engraver); - diff --git a/lily/lexer.ll b/lily/lexer.ll index 42e4996c58..7d2d699ead 100644 --- a/lily/lexer.ll +++ b/lily/lexer.ll @@ -4,7 +4,8 @@ source file of the LilyPond music typesetter - (c) 1996,1997 Han-Wen Nienhuys + (c) 1996--1999 Han-Wen Nienhuys + Jan Nieuwenhuizen */ @@ -24,11 +25,13 @@ #include #include +#include "lily-guile.hh" #include "string.hh" #include "string-convert.hh" #include "my-lily-lexer.hh" #include "array.hh" #include "interval.hh" +#include "lily-guile.hh" #include "parser.hh" #include "debug.hh" #include "main.hh" @@ -206,8 +209,7 @@ HYPHEN -- } {RESTNAME} { const char *s = YYText (); - yylval.string = new String (s); - DEBUG_OUT << "rest:"<< yylval.string; + yylval.scm = ly_ch_C_to_scm (s); return RESTNAME; } R { @@ -231,6 +233,27 @@ HYPHEN -- cerr << _ ("white expected") << endl; exit (1); } +# { //embedded scm + //char const* s = YYText () + 1; + char const* s = here_ch_C (); + int n = 0; + if (main_input_b_ && safe_global_b) { + error (_ ("Can't evaluate Scheme in safe mode")); + return SCM_EOL; + } + yylval.scm = ly_parse_scm (s, &n); + DEBUG_OUT << "Scheme: "; + if (flower_dstream) + ly_display_scm (yylval.scm); + + for (int i=0; i < n; i++) + { + yyinput (); + } + char_count_stack_.top () += n; + + return SCM_T; +} { {ALPHAWORD} { return scan_bare_word (YYText ()); @@ -267,6 +290,11 @@ HYPHEN -- \" { DEBUG_OUT << "quoted string: `" << *yylval.string << "'\n"; yy_pop_state (); + + /* yylval is union. Must remember STRING before setting SCM*/ + String *sp = yylval.string; + yylval.scm = ly_ch_C_to_scm (sp->ch_C ()); + delete sp; return STRING; } . { @@ -305,7 +333,8 @@ HYPHEN -- if (c == '{' && c == '}') // brace open is for not confusing dumb tools. here_input ().warning ( "Brace found at end of lyric. Did you forget a space?"); - yylval.string = new String (s); + yylval.scm = ly_ch_C_to_scm (YYText()); + DEBUG_OUT << "lyric : `" << s << "'\n"; return STRING; } @@ -457,8 +486,8 @@ My_lily_lexer::scan_escaped_word (String str) String msg (_f ("unknown escaped string: `\\%s'", str)); LexerError (msg.ch_C ()); DEBUG_OUT << "(string)"; - String *sp = new String (str); - yylval.string=sp; + yylval.scm = ly_ch_C_to_scm(str.ch_C()); + return STRING; } @@ -482,7 +511,7 @@ My_lily_lexer::scan_bare_word (String str) } } - yylval.string=new String (str); + yylval.scm = ly_ch_C_to_scm (str.ch_C()); return STRING; } diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index 311397cdd8..51b56ca726 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -33,6 +33,62 @@ ly_ch_C_eval_scm (char const*c) return gh_eval_str ((char*)c); } + +/* + Pass string to scm parser, evaluate one expression. + Return result value and #chars read. + + Thanks to Gary Houston + + Need guile-1.3.4 (>1.3 anyway) for ftell on str ports -- jcn +*/ +SCM +ly_parse_scm (char const* s, int* n) +{ + SCM str = gh_str02scm ((char*)s); + SCM port = scm_mkstrport (SCM_INUM0, str, SCM_OPN | SCM_RDNG, + "scm_eval_0str"); + SCM from = scm_ftell (port); + + SCM form; + SCM answer = SCM_UNSPECIFIED; + + /* Read expression from port */ + if (!SCM_EOF_OBJECT_P (form = scm_read (port))) + answer = scm_eval_x (form); + + /* + After parsing + + (begin (foo 1 2)) + + all seems fine, but after parsing + + (foo 1 2) + + read_buf has been advanced to read_pos - 1, + so that scm_ftell returns 1, instead of #parsed chars + */ + + /* + urg: reset read_buf for scm_ftell + shouldn't scm_read () do this for us? + */ + scm_fill_input (port); + SCM to = scm_ftell (port); + *n = gh_scm2int (to) - gh_scm2int (from); + + /* Don't close the port here; if we re-enter this function via a + continuation, then the next time we enter it, we'll get an error. + It's a string port anyway, so there's no advantage to closing it + early. + + scm_close_port (port); + */ + + return answer; +} + /* scm_m_quote doesn't use any env, but needs one for a good signature in GUILE. */ @@ -129,7 +185,7 @@ ly_scm2string (SCM s) char * p = gh_scm2newstr (s , &len); String r (p); - // delete p; + free (p); return r; } @@ -168,14 +224,28 @@ init_functions () scm_make_gsubr ("ly-gulp-file", 1,0, 0, (SCM(*)(...))ly_gulp_file); } -extern void init_symbols (); -extern void init_smobs (); // guh -> .hh +ADD_SCM_INIT_FUNC(funcs, init_functions); + +typedef void (*Void_fptr)(); +Array *scm_init_funcs_; + +void add_scm_init_func (void (*f)()) +{ + if (!scm_init_funcs_) + scm_init_funcs_ = new Array; + + scm_init_funcs_->push (f); +} void init_lily_guile () { - init_symbols(); - init_functions (); - init_smobs (); + for (int i=scm_init_funcs_->size() ; i--;) + (scm_init_funcs_->elem (i)) (); +} + +unsigned int ly_scm_hash (SCM s) +{ + return scm_ihashv (s, ~1u); } diff --git a/lily/local-key-engraver.cc b/lily/local-key-engraver.cc index a6a69fec56..8e773bf05a 100644 --- a/lily/local-key-engraver.cc +++ b/lily/local-key-engraver.cc @@ -58,7 +58,8 @@ Local_key_engraver::process_acknowledged () { if (!key_item_p_ && mel_l_arr_.size()) { - bool forget = get_property ("forgetAccidentals",0).to_bool(); + SCM f = get_property ("forgetAccidentals",0); + bool forget = gh_boolean_p (f) && gh_scm2bool(f); for (int i=0; i < mel_l_arr_.size(); i++) { Item * support_l = support_l_arr_[i]; @@ -126,7 +127,9 @@ Local_key_engraver::do_pre_move_processing() void Local_key_engraver::acknowledge_element (Score_element_info info) { - bool selfgr = get_property ("weAreGraceContext", 0).to_bool (); + SCM wg= get_property ("weAreGraceContext", 0); + + bool selfgr = gh_boolean_p (wg) &&gh_scm2bool (wg); bool he_gr = info.elem_l_->get_elt_property (grace_scm_sym) != SCM_BOOL_F; Grace_align_item * gai = dynamic_cast (info.elem_l_); @@ -159,7 +162,8 @@ Local_key_engraver::do_process_requests() Time_description const * time_C_ = get_staff_info().time_C_; if (time_C_ && !time_C_->whole_in_measure_) { - bool no_res = get_property ("noResetKey",0).to_bool (); + SCM n = get_property ("noResetKey",0); + bool no_res = gh_boolean_p (n) && gh_scm2bool (n); if (!no_res && key_grav_l_) local_key_= key_grav_l_->key_; } diff --git a/lily/local-key-item.cc b/lily/local-key-item.cc index 9953c7550d..6e35416a18 100644 --- a/lily/local-key-item.cc +++ b/lily/local-key-item.cc @@ -7,7 +7,7 @@ */ #include "local-key-item.hh" #include "molecule.hh" -#include "scalar.hh" + #include "lookup.hh" #include "paper-def.hh" #include "musical-request.hh" diff --git a/lily/lookup.cc b/lily/lookup.cc index 1000f37ab6..1181e03925 100644 --- a/lily/lookup.cc +++ b/lily/lookup.cc @@ -15,7 +15,7 @@ #include "lookup.hh" #include "debug.hh" #include "dimensions.hh" -#include "scalar.hh" + #include "paper-def.hh" #include "string-convert.hh" #include "file-path.hh" diff --git a/lily/ly-symbols.cc b/lily/ly-symbols.cc index 719bf6dfba..93edfce560 100644 --- a/lily/ly-symbols.cc +++ b/lily/ly-symbols.cc @@ -29,3 +29,4 @@ init_symbols () } +ADD_SCM_INIT_FUNC(lysyms, init_symbols); diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index 37aa4065ee..080546f2f5 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -44,9 +44,9 @@ Lyric_engraver::do_process_requests() text_p_->text_str_ = req_l_->text_str_; text_p_->text_str_ += " "; // ugh. - Scalar style = get_property ("textStyle", 0); - if (style.length_i ()) - text_p_->style_str_ = style; + SCM style = get_property ("textStyle", 0); + if (gh_string_p(style)) + text_p_->style_str_ = ly_scm2string (style); text_p_->set_elt_property (non_rhythmic_scm_sym, SCM_BOOL_T); diff --git a/lily/melisma-engraver.cc b/lily/melisma-engraver.cc index 62e5d494f9..2bc76c9930 100644 --- a/lily/melisma-engraver.cc +++ b/lily/melisma-engraver.cc @@ -27,10 +27,12 @@ Melisma_engraver::do_try_music (Music *m ) { if (dynamic_cast(m)) { - Scalar plain (get_property ("melismaBusy", 0)); - Scalar slur (get_property ("slurMelismaBusy", 0)); - Scalar tie (get_property ("tieMelismaBusy", 0)); - return plain.to_bool () || slur.to_bool () || tie.to_bool (); + SCM plain (get_property ("melismaBusy", 0)); + SCM slur (get_property ("slurMelismaBusy", 0)); + SCM tie (get_property ("tieMelismaBusy", 0)); + return (gh_boolean_p (plain) && gh_scm2bool (plain)) + || (gh_boolean_p (slur) && gh_scm2bool (slur)) + || (gh_boolean_p (tie) && gh_scm2bool (tie)); } return false; } diff --git a/lily/moment.cc b/lily/moment.cc new file mode 100644 index 0000000000..7b76747d73 --- /dev/null +++ b/lily/moment.cc @@ -0,0 +1,69 @@ +/* + moment.cc -- implement Moment + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + + +#include "lily-guile.hh" +#include "moment.hh" +#include "warn.hh" + +SCM +Moment::mark_smob (SCM s) +{ + return SCM_EOL; +} + + +Moment::~Moment() +{ + self_scm_ = SCM_EOL; +} + +int +Moment::print_smob (SCM s, SCM port, scm_print_state *) +{ + Moment *r = (Moment *) SCM_CDR (s); + + scm_puts ("#str()); + scm_puts ((char *)str.ch_C(), port); + scm_puts (" >", port); + + return 1; +} + +void +Moment::do_smobify_self () +{} + +SCM +make_rational (SCM n, SCM d) +{ + if (SCM_INUMP (n) && SCM_INUMP(d)) + { + Moment *r = new Moment (gh_scm2int (n), gh_scm2int (d)); + return r->smobify_self (); + } + else + { + ::error ("Not a number"); + assert(false); + } +} + +#include "ly-smobs.icc" + +IMPLEMENT_SMOBS(Moment); + +void +init_moments () +{ + scm_make_gsubr ("make-moment", 2 , 0, 0, (SCM(*)(...)) make_rational); +} + +ADD_SCM_INIT_FUNC(moms,init_moments); diff --git a/lily/music-iterator.cc b/lily/music-iterator.cc index e5774c9f32..9de2bb6af7 100644 --- a/lily/music-iterator.cc +++ b/lily/music-iterator.cc @@ -114,7 +114,7 @@ Music_iterator::ok() const } Music_iterator* -Music_iterator::static_get_iterator_p (Music const *m, bool playing) +Music_iterator::static_get_iterator_p (Music const *m) { Music_iterator * p =0; @@ -142,15 +142,14 @@ Music_iterator::static_get_iterator_p (Music const *m, bool playing) p = new Music_wrapper_iterator; else if (Repeated_music const * n = dynamic_cast (m)) { - if (n->fold_b_ && !playing) + if (n->fold_b_) p = new Folded_repeat_iterator; else p = new Unfolded_repeat_iterator; } else assert (0); - - p->playback_b_ = playing; + p->music_l_ = m; return p; @@ -177,7 +176,7 @@ Music_iterator::init_translator (Music const *m, Translator_group *report_l) Music_iterator* Music_iterator::get_iterator_p (Music const*m) const { - Music_iterator*p = static_get_iterator_p (m, playback_b_); + Music_iterator*p = static_get_iterator_p (m); p->init_translator (m, report_to_l()); p->construct_children(); @@ -186,7 +185,6 @@ Music_iterator::get_iterator_p (Music const*m) const Music_iterator::Music_iterator() { - playback_b_ = false; first_b_ = true; } diff --git a/lily/music-output-def.cc b/lily/music-output-def.cc index 6006f038b4..d355840d24 100644 --- a/lily/music-output-def.cc +++ b/lily/music-output-def.cc @@ -42,13 +42,13 @@ Music_output_def::Music_output_def (Music_output_def const &s) for (Scope_iter i (*translator_p_dict_p_); i.ok (); i++) { - Translator * t = i.val ()->access_content_Translator (false); + Translator * t = i.val ()->access_content_Translator_group (false); t-> output_def_l_ = this; } } void -Music_output_def::assign_translator (Translator*tp) +Music_output_def::assign_translator (Translator_group*tp) { String s =tp->type_str_; if (s.empty_b ()) @@ -58,7 +58,7 @@ Music_output_def::assign_translator (Translator*tp) if (translator_p_dict_p_->elem_b (s)) delete translator_p_dict_p_->elem (s); - translator_p_dict_p_->elem (s) = new Translator_identifier (tp, 0); + translator_p_dict_p_->elem (s) = new Translator_group_identifier (tp, 0); tp ->output_def_l_ = this; } @@ -66,7 +66,7 @@ Translator* Music_output_def::find_translator_l (String name) const { if (translator_p_dict_p_->elem_b (name)) - return translator_p_dict_p_->elem (name)->access_content_Translator (false); + return translator_p_dict_p_->elem (name)->access_content_Translator_group (false); if (global_translator_dict_p->elem_b (name)) return global_translator_dict_p->elem(name); diff --git a/lily/my-lily-lexer.cc b/lily/my-lily-lexer.cc index 49d84d6335..de4ea2373a 100644 --- a/lily/my-lily-lexer.cc +++ b/lily/my-lily-lexer.cc @@ -11,6 +11,7 @@ #include "notename-table.hh" #include "interval.hh" #include "identifier.hh" +#include "lily-guile.hh" #include "parser.hh" #include "keyword.hh" #include "my-lily-lexer.hh" @@ -19,6 +20,7 @@ #include "main.hh" #include "scope.hh" #include "input.hh" +#include "moment.hh" static Keyword_ent the_key_tab[]={ {"autochange", AUTOCHANGE}, @@ -64,8 +66,6 @@ static Keyword_ent the_key_tab[]={ {"repeat", REPEAT}, {"repetitions", REPETITIONS}, {"addlyrics", ADDLYRICS}, - {"scm", SCM_T}, - {"scmfile", SCMFILE}, {"score", SCORE}, {"script", SCRIPT}, {"shape", SHAPE}, diff --git a/lily/my-lily-parser.cc b/lily/my-lily-parser.cc index aaae6a6d94..11ae2eeda4 100644 --- a/lily/my-lily-parser.cc +++ b/lily/my-lily-parser.cc @@ -14,6 +14,7 @@ #include "music-list.hh" #include "musical-request.hh" #include "command-request.hh" +#include "lily-guile.hh" #include "parser.hh" #include "scope.hh" #include "file-results.hh" diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index 7ac5c8ade6..99477e09d7 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -49,7 +49,7 @@ Note_heads_engraver::do_process_requests() if (note_p_arr_.size ()) return ; - String noteheadstyle = get_property ("noteHeadStyle", 0); + SCM noteheadstyle = get_property ("noteHeadStyle", 0); for (int i=0; i < note_req_l_arr_.size (); i++) { Note_head *note_p = new Note_head; @@ -62,10 +62,10 @@ Note_heads_engraver::do_process_requests() note_p->dots_l_ = d; d->dots_i_ = note_req_l->duration_.dots_i_; - Scalar dir = get_property ("verticalDirection",0); - if (dir.isdir_b()) + SCM dir = get_property ("verticalDirection",0); + if (isdir_b (dir)) { - d->resolve_dir_ = (Direction)(int)dir; + d->resolve_dir_ = to_dir (dir); } announce_element (Score_element_info (d,0)); @@ -73,12 +73,13 @@ Note_heads_engraver::do_process_requests() } note_p->position_i_ = note_req_l->pitch_.steps (); - if (noteheadstyle == "transparent") - note_p->set_elt_property (transparent_scm_sym, SCM_BOOL_T); - else - note_p->set_elt_property (style_scm_sym, - ly_ch_C_to_scm (noteheadstyle.ch_C())); - + if (gh_string_p (noteheadstyle)) + { + if (ly_scm2string (noteheadstyle) == "transparent") + note_p->set_elt_property (transparent_scm_sym, SCM_BOOL_T); + else + note_p->set_elt_property (style_scm_sym, noteheadstyle); + } Score_element_info itinf (note_p,note_req_l); announce_element (itinf); diff --git a/lily/note-performer.cc b/lily/note-performer.cc index 1f88de4aad..f455204067 100644 --- a/lily/note-performer.cc +++ b/lily/note-performer.cc @@ -37,9 +37,9 @@ Note_performer::do_process_requests () { int transposing_i = 0; //urg - Scalar prop = get_property ("transposing", 0); - if (!prop.empty_b () && prop.isnum_b ()) - transposing_i = prop; + SCM prop = get_property ("transposing", 0); + if (SCM_NUMBERP(prop)) + transposing_i = gh_scm2int (prop); while (note_req_l_arr_.size ()) { diff --git a/lily/paper-def.cc b/lily/paper-def.cc index dc99d4d87b..c5a9146f81 100644 --- a/lily/paper-def.cc +++ b/lily/paper-def.cc @@ -209,7 +209,7 @@ Paper_def::reset_default_count() } Paper_outputter* -Paper_def::paper_outputter_p (Paper_stream* os_p, Header* header_l, String origin_str) const +Paper_def::paper_outputter_p (Paper_stream* os_p, Scope* header_l, String origin_str) const { Paper_outputter* p = new Paper_outputter (os_p); diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index fc628db526..b58ba0eeaf 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -161,7 +161,7 @@ Paper_outputter::output_comment (String str) { if (String (output_global_ch) == "scm") { - *outstream_l_ << "; " << str << '\n'; + *outstream_l_ << "; " << str << "\n"; } else { diff --git a/lily/paper-score.cc b/lily/paper-score.cc index ef983e8053..d8cba19d43 100644 --- a/lily/paper-score.cc +++ b/lily/paper-score.cc @@ -50,6 +50,9 @@ Paper_score::typeset_element (Score_element * elem_p) SCM_CDR(element_smob_list_) = gh_cons (elem_p->self_scm_, SCM_CDR (element_smob_list_)); + elem_p->set_elt_property (ly_symbol ("full-name"), + gh_str02scm((char*)elem_p->name())); + scm_unprotect_object (elem_p->self_scm_); } diff --git a/lily/paper-stream.cc b/lily/paper-stream.cc index 2f791019ad..f7844a8995 100644 --- a/lily/paper-stream.cc +++ b/lily/paper-stream.cc @@ -42,7 +42,7 @@ Paper_stream::~Paper_stream () // print string. don't forget indent. Paper_stream& -Paper_stream::operator << (Scalar s) +Paper_stream::operator << (String s) { for (char const *cp = s.ch_C (); *cp; cp++) { diff --git a/lily/parser.yy b/lily/parser.yy index 4d84041f38..c5b3927e59 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -5,14 +5,13 @@ source file of the GNU LilyPond music typesetter - (c) 1997 Han-Wen Nienhuys + (c) 1997--1999 Han-Wen Nienhuys Jan Nieuwenhuizen */ #include #include "lily-guile.hh" #include "notename-table.hh" -#include "scalar.hh" #include "translation-property.hh" #include "lookup.hh" #include "misc.hh" @@ -79,11 +78,11 @@ print_mudela_versions (ostream &os) Array* realarr; Array *pitch_arr; Link_array *reqvec; - Array * strvec; Array *intvec; Notename_table *chordmodifiertab; Duration *duration; Identifier *id; + String * string; Music *music; Music_list *music_list; Score *score; @@ -98,11 +97,14 @@ print_mudela_versions (ostream &os) Paper_def *paper; Real real; Request * request; - Scalar *scalar; - String *string; + /* We use SCMs to do strings, because it saves us the trouble of +deleting them. Let's hope that a stack overflow doesnt trigger a move +of the parse stack onto the heap. */ + SCM scm; + Tempo_req *tempo; - Translator* trans; + Translator_group* trans; char c; int i; int ii[10]; @@ -170,7 +172,6 @@ yylex (YYSTYPE *s, void * v_l) %token REPETITIONS %token ADDLYRICS %token SCM_T -%token SCMFILE %token SCORE %token SCRIPT %token SHAPE @@ -206,8 +207,9 @@ yylex (YYSTYPE *s, void * v_l) %token MIDI_IDENTIFIER %token PAPER_IDENTIFIER %token REAL -%token DURATION RESTNAME -%token STRING +%token DURATION RESTNAME +%token STRING +%token SCM_T %token UNSIGNED @@ -221,7 +223,7 @@ yylex (YYSTYPE *s, void * v_l) %type abbrev_type %type int unsigned %type script_dir -%type optional_modality +%type optional_modality %type identifier_init %type steno_duration optional_notemode_duration %type entered_notemode_duration explicit_duration @@ -238,7 +240,7 @@ yylex (YYSTYPE *s, void * v_l) %type midi_block midi_body %type duration_length -%type scalar +%type embedded_scm scalar %type Music Sequential_music Simultaneous_music Music_sequence %type relative_music re_rhythmed_music %type property_def translator_change @@ -250,11 +252,11 @@ yylex (YYSTYPE *s, void * v_l) %type command_req verbose_command_req %type extender_req %type hyphen_req -%type string +%type string %type score_block score_body %type real_array -%type script_abbreviation +%type script_abbreviation %type translator_spec_block translator_spec_body %type tempo_request %type notenames_body notenames_block chordmodifiers_block @@ -300,21 +302,14 @@ toplevel_expression: Midi_def_identifier ($1, MIDI_IDENTIFIER); THIS->lexer_p_->set_identifier ("$defaultmidi", id) } - | embedded_scm { - } + | embedded_scm { + // junk value + } ; embedded_scm: - SCMFILE STRING semicolon { - read_lily_scm_file (*$2); - delete $2; - } - | SCM_T STRING semicolon { - if (THIS->lexer_p_->main_input_b_ && safe_global_b) - error (_("Can't evaluate Scheme in safe mode")); - gh_eval_str ($2->ch_l ()); - delete $2; - }; + SCM_T + ; chordmodifiers_block: @@ -336,10 +331,9 @@ notenames_body: $$ = $1-> access_content_Notename_table(true); } | notenames_body STRING '=' explicit_musical_pitch { - (*$$)[*$2] = *$4; + (*$$)[ly_scm2string ($2)] = *$4; delete $4; - delete $2; } ; @@ -369,7 +363,7 @@ assignment: THIS->remember_spot (); } /* cont */ '=' identifier_init { - THIS->lexer_p_->set_identifier (*$1, $4); + THIS->lexer_p_->set_identifier (ly_scm2string ($1), $4); $4->init_b_ = THIS->init_parse_b_; $4->set_spot (THIS->pop_spot ()); } @@ -396,7 +390,7 @@ identifier_init: } | translator_spec_block { - $$ = new Translator_identifier ($1, TRANS_IDENTIFIER); + $$ = new Translator_group_identifier ($1, TRANS_IDENTIFIER); } | Music { $$ = new Music_identifier ($1, MUSIC_IDENTIFIER); @@ -412,7 +406,7 @@ identifier_init: $$ = new Real_identifier (new Real ($1), REAL_IDENTIFIER); } | string { - $$ = new String_identifier ($1, STRING_IDENTIFIER); + $$ = new String_identifier (new String (ly_scm2string ($1)), STRING_IDENTIFIER); } | int { $$ = new int_identifier (new int ($1), INT_IDENTIFIER); @@ -428,23 +422,23 @@ translator_spec_block: translator_spec_body: TRANS_IDENTIFIER { - $$ = $1->access_content_Translator (true); - Translator_group * tg = dynamic_cast ($$); - if (!tg) - THIS->parser_error (_("Need a translator group for a context")); + $$ = $1->access_content_Translator_group (true); $$-> set_spot (THIS->here_input ()); } | TYPE STRING semicolon { - Translator* t = get_translator_l (*$2); + Translator* t = get_translator_l (ly_scm2string ($2)); Translator_group * tg = dynamic_cast (t); if (!tg) THIS->parser_error (_("Need a translator group for a context")); - t = t->clone (); - t->set_spot (THIS->here_input ()); - $$ = t; - delete $2; + tg = dynamic_cast (t->clone ()); + tg->set_spot (THIS->here_input ()); + $$ = tg; + } + | translator_spec_body STRING '=' embedded_scm { + Translator_group* tg = dynamic_cast ($$); + tg->set_property (ly_scm2string ($2), $4); } | translator_spec_body STRING '=' identifier_init semicolon { Identifier* id = $4; @@ -452,39 +446,33 @@ translator_spec_body: Real_identifier *r= dynamic_cast(id); int_identifier *i = dynamic_cast (id); - String str; - if (s) str = *s->access_content_String (false); - if (i) str = to_str (*i->access_content_int (false)); - if (r) str = to_str (*r->access_content_Real (false)); + SCM v; + if (s) v = ly_ch_C_to_scm (s->access_content_String (false)->ch_C()); + if (i) v = gh_int2scm (*i->access_content_int (false)); + if (r) v = gh_double2scm (*r->access_content_Real (false)); if (!s && !i && !r) THIS->parser_error (_("Wrong type for property value")); delete $4; /* ugh*/ Translator_group* tg = dynamic_cast ($$); - if (!tg) - THIS->parser_error (_("Need a translator group for a context")); - tg->set_property (*$2, str); + + tg->set_property (ly_scm2string ($2), v); } | translator_spec_body NAME STRING semicolon { - $$->type_str_ = *$3; - delete $3; + $$->type_str_ = ly_scm2string ($3); } | translator_spec_body CONSISTS STRING semicolon { - dynamic_cast ($$)-> set_element (*$3, true); - delete $3; + dynamic_cast ($$)-> set_element (ly_scm2string ($3), true); } | translator_spec_body CONSISTSEND STRING semicolon { - dynamic_cast ($$)-> set_element (*$3, true); - delete $3; + dynamic_cast ($$)-> set_element (ly_scm2string ($3), true); } | translator_spec_body ACCEPTS STRING semicolon { - dynamic_cast ($$)-> set_acceptor (*$3, true); - delete $3; + dynamic_cast ($$)-> set_acceptor (ly_scm2string ($3), true); } | translator_spec_body REMOVE STRING semicolon { - dynamic_cast ($$)-> set_element (*$3, false); - delete $3; + dynamic_cast ($$)-> set_element (ly_scm2string ($3), false); } ; @@ -558,8 +546,7 @@ paper_def_body: } | paper_def_body int '=' FONT STRING { // ugh, what a syntax Lookup * l = new Lookup; - l->font_name_ = *$5; - delete $5; + l->font_name_ = ly_scm2string ($5); $$->set_lookup ($2, l); } | paper_def_body assignment semicolon { @@ -731,9 +718,8 @@ Repeated_music: Repeated_music * r = new Repeated_music ($4, $3 >? 1, m); $$ = r; - r->fold_b_ = (*$2 == "fold"); - r->volta_fold_b_ = (*$2 == "volta"); - delete $2; + r->fold_b_ = (ly_scm2string ($2) == "fold"); + r->volta_fold_b_ = (ly_scm2string ($2) == "volta"); r->set_spot ($4->spot ()); } ; @@ -786,15 +772,15 @@ Composite_music: CONTEXT STRING Music { Context_specced_music *csm = new Context_specced_music ($3); - csm->translator_type_str_ = *$2; + csm->translator_type_str_ = ly_scm2string ($2); csm->translator_id_str_ = ""; - delete $2; + $$ = csm; } | AUTOCHANGE STRING Music { - Auto_change_music * chm = new Auto_change_music (*$2, $3); - delete $2; + Auto_change_music * chm = new Auto_change_music (ly_scm2string ($2), $3); + $$ = chm; chm->set_spot ($3->spot ()); } @@ -804,10 +790,8 @@ Composite_music: | CONTEXT STRING '=' STRING Music { Context_specced_music *csm = new Context_specced_music ($5); - csm->translator_type_str_ = *$2; - csm->translator_id_str_ = *$4; - delete $2; - delete $4; + csm->translator_type_str_ = ly_scm2string ($2); + csm->translator_id_str_ = ly_scm2string ($4); $$ = csm; } @@ -873,38 +857,33 @@ re_rhythmed_music: translator_change: TRANSLATOR STRING '=' STRING { Change_translator * t = new Change_translator; - t-> change_to_type_str_ = *$2; - t-> change_to_id_str_ = *$4; + t-> change_to_type_str_ = ly_scm2string ($2); + t-> change_to_id_str_ = ly_scm2string ($4); $$ = t; $$->set_spot (THIS->here_input ()); - delete $2; - delete $4; } ; property_def: - PROPERTY STRING '.' STRING '=' scalar { + PROPERTY STRING '.' STRING '=' scalar { Translation_property *t = new Translation_property; - t-> var_str_ = *$4; - t-> value_ = *$6; + t->var_str_ = ly_scm2string ($4); + t->value_ = $6; Context_specced_music *csm = new Context_specced_music (t); $$ = csm; $$->set_spot (THIS->here_input ()); - csm-> translator_type_str_ = *$2; - - delete $2; - delete $4; - delete $6; + csm-> translator_type_str_ = ly_scm2string ($2); } ; scalar: - string { $$ = new Scalar (*$1); delete $1; } - | int { $$ = new Scalar ($1); } + string { $$ = $1; } + | int { $$ = gh_int2scm ($1); } + | embedded_scm { $$ = $1; } ; @@ -992,12 +971,11 @@ abbrev_command_req: verbose_command_req: BAR STRING { - $$ = new Bar_req (*$2); - delete $2; + $$ = new Bar_req (ly_scm2string ($2)); } | MARK STRING { - $$ = new Mark_req (*$2); - delete $2; + $$ = new Mark_req (ly_scm2string ($2)); + } | MARK unsigned { $$ = new Mark_req (to_str ($2)); @@ -1031,9 +1009,10 @@ verbose_command_req: delete $2; } | CLEF STRING { - $$ = new Clef_change_req (*$2); - delete $2; + $$ = new Clef_change_req (ly_scm2string ($2)); + } +/* UGH. optional. */ | KEY NOTENAME_PITCH optional_modality { Key_change_req *key_p= new Key_change_req; key_p->key_.pitch_arr_.push (*$2); @@ -1073,10 +1052,9 @@ request_that_take_dir: gen_text_def | verbose_request | script_abbreviation { - Identifier*i = THIS->lexer_p_->lookup_identifier ("dash-" + *$1); + Identifier*i = THIS->lexer_p_->lookup_identifier ("dash-" + ly_scm2string ($1)); Articulation_req *a = new Articulation_req; a->articulation_str_ = *i->access_content_String (false); - delete $1; $$ = a; } ; @@ -1098,17 +1076,16 @@ verbose_request: } | TEXTSCRIPT STRING STRING { Text_script_req *ts_p = new Text_script_req; - ts_p-> text_str_ = *$2; - ts_p-> style_str_ = *$3; + ts_p-> text_str_ = ly_scm2string ($2); + ts_p-> style_str_ = ly_scm2string ($3); ts_p->set_spot (THIS->here_input ()); - delete $3; - delete $2; + $$ = ts_p; } | SPANREQUEST int STRING { Span_req * sp_p = new Span_req; sp_p-> span_dir_ = Direction($2); - sp_p->span_type_str_ = *$3; + sp_p->span_type_str_ = ly_scm2string ($3); sp_p->set_spot (THIS->here_input ()); $$ = sp_p; } @@ -1120,10 +1097,10 @@ verbose_request: } | SCRIPT STRING { Articulation_req * a = new Articulation_req; - a->articulation_str_ = *$2; + a->articulation_str_ = ly_scm2string ($2); a->set_spot (THIS->here_input ()); $$ = a; - delete $2; + } ; @@ -1283,8 +1260,8 @@ gen_text_def: string { Text_script_req *t = new Text_script_req; $$ = t; - t->text_str_ = *$1; - delete $1; + t->text_str_ = ly_scm2string ($1); + $$->set_spot (THIS->here_input ()); } | DIGIT { @@ -1298,22 +1275,22 @@ gen_text_def: script_abbreviation: '^' { - $$ = new String ("hat"); + $$ = gh_str02scm ("hat"); } | '+' { - $$ = new String ("plus"); + $$ = gh_str02scm("plus"); } | '-' { - $$ = new String ("dash"); + $$ = gh_str02scm ("dash"); } | '|' { - $$ = new String ("bar"); + $$ = gh_str02scm ("bar"); } | '>' { - $$ = new String ("larger"); + $$ = gh_str02scm ("larger"); } | '.' { - $$ = new String ("dot"); + $$ = gh_str02scm ("dot"); } ; @@ -1429,8 +1406,8 @@ simple_element: $$ = v; } | RESTNAME optional_notemode_duration { - $$ = THIS->get_rest_element (*$1, $2); - delete $1; // delete notename + $$ = THIS->get_rest_element (ly_scm2string ($1), $2); + } | MEASURES optional_notemode_duration { Multi_measure_rest_req* m = new Multi_measure_rest_req; @@ -1455,8 +1432,8 @@ simple_element: | STRING optional_notemode_duration { if (!THIS->lexer_p_->lyric_state_b ()) THIS->parser_error (_ ("Have to be in Lyric mode for lyrics")); - $$ = THIS->get_word_element (*$1, $2); - delete $1; + $$ = THIS->get_word_element (ly_scm2string ($1), $2); + } | chord { if (!THIS->lexer_p_->chord_state_b ()) @@ -1594,11 +1571,10 @@ string: $$ = $1; } | STRING_IDENTIFIER { - $$ = $1->access_content_String (true); + $$ = ly_ch_C_to_scm ($1->access_content_String (true)->ch_C ()); } | string '+' string { - *$$ += *$3; - delete $3; + $$ = scm_string_append (scm_listify ($1, $3, SCM_UNDEFINED)); } ; diff --git a/lily/property-inspect.cc b/lily/property-inspect.cc new file mode 100644 index 0000000000..5e29f4160b --- /dev/null +++ b/lily/property-inspect.cc @@ -0,0 +1,27 @@ +/* + property-inspect.cc -- implement Property inspect funcs. + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#include "property-inspect.hh" + +bool +isdir_b (SCM s) +{ + if (SCM_NUMBERP (s)) + { + int i = gh_int2scm (s); + return i>= -1 && i <= 1; + } + return false; +} + +Direction +to_dir (SCM s) +{ + return (Direction) gh_scm2int (s); +} diff --git a/lily/protected-scm.cc b/lily/protected-scm.cc index cf06c84a5d..1d8fd16b2a 100644 --- a/lily/protected-scm.cc +++ b/lily/protected-scm.cc @@ -10,14 +10,6 @@ #include "lily-guile.hh" #include "main.hh" -#ifdef LYPROT -#define PROTECT ly_protect_scm -#define UNPROTECT ly_unprotect_scm -#else -#define PROTECT scm_protect_object -#define UNPROTECT scm_unprotect_object -#endif - Protected_scm::Protected_scm () { object_ = 0; @@ -25,12 +17,12 @@ Protected_scm::Protected_scm () Protected_scm::Protected_scm (SCM s) { - object_ = s ? PROTECT (s): 0; + object_ = s ? scm_protect_object (s): 0; } Protected_scm::Protected_scm (Protected_scm const &s) { - object_ = s.object_ ? PROTECT (s.object_) : 0; + object_ = s.object_ ? scm_protect_object (s.object_) : 0; } Protected_scm & @@ -39,9 +31,9 @@ Protected_scm::operator =(SCM s) if (object_ == s) return *this; if (object_) - UNPROTECT(object_); + scm_unprotect_object(object_); - object_ = s ? PROTECT (s): 0; + object_ = s ? scm_protect_object (s): 0; return *this; } @@ -56,8 +48,7 @@ Protected_scm::~Protected_scm () { if (object_) { - UNPROTECT (object_); - object_ =0L; // be nice to conservative GC + scm_unprotect_object (object_); } } diff --git a/lily/repeat-engraver.cc b/lily/repeat-engraver.cc index c716bb1243..3be9fb02e2 100644 --- a/lily/repeat-engraver.cc +++ b/lily/repeat-engraver.cc @@ -55,7 +55,8 @@ Repeat_engraver::queue_events () Music_sequence* alt = repeated_music_l_->alternatives_p_; Moment walk_mom = now_mom () + repeated_music_l_->repeat_body_p_->length_mom (); - bool create_volta = ! get_property ("noVoltaBraces",0).to_bool (); + SCM novolta = get_property ("noVoltaBraces",0); + bool create_volta = gh_boolean_p (novolta) && !gh_scm2bool (novolta); Cons_list becel; becel.append (new Bar_create_event (now_mom (), "|:")); @@ -101,11 +102,10 @@ Repeat_engraver::queue_events () becel.append (c); last_number = volta_number; volta_number ++; - Scalar l (get_property ("voltaSpannerDuration", 0)); - if (l.length_i ()) // voltaSpannerDuration OK? + SCM l (get_property ("voltaSpannerDuration", 0)); + if (SMOB_IS_TYPE_B (Moment, l)) { - - Moment vSD_mom = l.to_rat(); + Moment vSD_mom = *SMOB_TO_TYPE (Moment,l); if ( vSD_mom < i->car_->length_mom() ) // terminate volta early ? { vSD_mom += walk_mom; diff --git a/lily/rest-engraver.cc b/lily/rest-engraver.cc index d3436d462b..939baa2161 100644 --- a/lily/rest-engraver.cc +++ b/lily/rest-engraver.cc @@ -58,10 +58,9 @@ Rest_engraver::do_process_requests () } if (rest_p_->balltype_i_ >= 2) { - String reststyle = get_property ("restStyle", 0); - if (reststyle.length_i ()) - rest_p_->set_elt_property (style_scm_sym, - ly_ch_C_to_scm (reststyle.ch_C())); + SCM reststyle = get_property ("restStyle", 0); + if (gh_string_p (reststyle)) + rest_p_->set_elt_property (style_scm_sym,reststyle); } announce_element (Score_element_info (rest_p_, rest_req_l_)); } diff --git a/lily/rhythmic-column-engraver.cc b/lily/rhythmic-column-engraver.cc index 81e0cb65bf..914a2c2ecf 100644 --- a/lily/rhythmic-column-engraver.cc +++ b/lily/rhythmic-column-engraver.cc @@ -58,8 +58,8 @@ Rhythmic_column_engraver::process_acknowledged () stem_l_ = 0; } - - bool wegrace = get_property ("weAreGraceContext",0).to_bool (); + SCM wg = get_property ("weAreGraceContext",0); + bool wegrace = gh_boolean_p (wg) && gh_scm2bool (wg); if (!wegrace) for (int i=0; i < grace_slur_endings_.size(); i++) @@ -71,7 +71,9 @@ Rhythmic_column_engraver::process_acknowledged () void Rhythmic_column_engraver::acknowledge_element (Score_element_info i) { - if ((get_property ("weAreGraceContext",0).to_bool () != + SCM wg = get_property ("weAreGraceContext",0); + bool wegrace = gh_boolean_p (wg) && gh_scm2bool (wg); + if ((wegrace != (i.elem_l_->get_elt_property (grace_scm_sym) != SCM_BOOL_F)) && !dynamic_cast (i.elem_l_)) return ; @@ -105,18 +107,16 @@ Rhythmic_column_engraver::do_pre_move_processing() { if (ncol_p_) { - Scalar sh = get_property ("horizontalNoteShift", 0); - if (sh.isnum_b ()) + SCM sh = get_property ("horizontalNoteShift", 0); + if (SCM_NUMBERP(sh)) { - ncol_p_->set_elt_property (horizontal_shift_scm_sym, - gh_int2scm (int (sh))); + ncol_p_->set_elt_property (horizontal_shift_scm_sym, sh); } sh = get_property ("forceHorizontalShift" ,0); - if (sh.isnum_b ()) + if (SCM_NUMBERP(sh)) { - ncol_p_->set_elt_property (force_hshift_scm_sym, - gh_double2scm (double (sh))); + ncol_p_->set_elt_property (force_hshift_scm_sym, sh); } typeset_element (ncol_p_); diff --git a/lily/scm-hash.cc b/lily/scm-hash.cc new file mode 100644 index 0000000000..043cb23949 --- /dev/null +++ b/lily/scm-hash.cc @@ -0,0 +1,93 @@ +/* + scm-hash.cc -- implement Scheme_hash_table + + source file of the GNU LilyPond music typesetter + + (c) 1999 Han-Wen Nienhuys + + */ + +#include "scm-hash.hh" +#include "hash-table-iter.hh" + +Scheme_hash_table::Scheme_hash_table () +{ + hash_func_ = ly_scm_hash; + self_scm_ = SCM_EOL; + smobify_self (); +} + +void +Scheme_hash_table::operator =(Scheme_hash_table const & src) +{ + Hash_table::operator = (src); + + // we do not copy the self_scm_ field! +} + +void +Scheme_hash_table::do_smobify_self () +{ +} + +#include "ly-smobs.icc" +IMPLEMENT_SMOBS(Scheme_hash_table); + +SCM +Scheme_hash_table::mark_smob (SCM s) +{ + /* + can't typecheck naively, since GC bit lives in CAR of S + */ + //assert (SMOB_IS_TYPE_B (Scheme_hash_table, s)); + + Scheme_hash_table *me = SMOB_TO_TYPE(Scheme_hash_table,s); + for (Hash_table_iter i (*me); i.ok(); i++) + { + scm_gc_mark (i.key()); + scm_gc_mark (i.val ()); + } + return SCM_EOL; +} + + +Scheme_hash_table::Scheme_hash_table (Scheme_hash_table const &src) + : Hash_table (src) +{ + hash_func_ = src.hash_func_; + self_scm_ = SCM_EOL; + smobify_self (); +} + +int +Scheme_hash_table::print_smob (SCM s, SCM p, scm_print_state*ps) +{ + assert (SMOB_IS_TYPE_B (Scheme_hash_table, s)); + Scheme_hash_table *me = SMOB_TO_TYPE(Scheme_hash_table,s); + for (Hash_table_iter i (*me); i.ok(); i++) + { + scm_display (i.key(), p); + scm_puts (" = ",p); + scm_display (i.val (), p); + scm_puts ("\n",p); + } + return 1; +} + + + + +Scheme_hash_table::~Scheme_hash_table( ) +{ + unsmobify_self (); +} + +SCM +Scheme_hash_table::to_alist () const +{ + SCM l = SCM_EOL; + for (Hash_table_iter i (*this); i.ok(); i++) + l = gh_cons (gh_cons (i.key (), i.val()), l); + return l; +} + diff --git a/lily/scope.cc b/lily/scope.cc index e58ad798cb..be98f18612 100644 --- a/lily/scope.cc +++ b/lily/scope.cc @@ -44,14 +44,15 @@ Scope::Scope (Scope const&s) } } -unsigned int scm_hash (Protected_scm s) +unsigned int ly_pscm_hash (Protected_scm s) { - return scm_ihashv (s, ~1u); + return ly_scm_hash (s); } + Scope::Scope () { - hash_func_ = scm_hash; + hash_func_ = ly_pscm_hash; } bool diff --git a/lily/score-element.cc b/lily/score-element.cc index 9282bfc010..a8a82a8a87 100644 --- a/lily/score-element.cc +++ b/lily/score-element.cc @@ -70,7 +70,7 @@ Score_element::Score_element (Score_element const&s) Score_element::~Score_element() { - delete output_p_; + assert (!output_p_); assert (status_i_ >=0); status_i_ = -1; } @@ -435,30 +435,6 @@ Score_element::find_broken_piece (Line_of_score*) const return 0; } -static scm_smobfuns score_elt_funs = { - Score_element::mark_smob, Score_element::free_smob, - Score_element::print_smob, 0, -}; - - -SCM -Score_element::smobify_self () -{ - if (self_scm_ != SCM_EOL) - return self_scm_; - - SCM s; - SCM_NEWCELL(s); - SCM_SETCAR(s,smob_tag); - void * me_p = this; - SCM_SETCDR(s,me_p); - scm_protect_object (s); - self_scm_ = s; - - scm_unprotect_object (element_property_alist_); // ugh - return s; -} - SCM Score_element::mark_smob (SCM ses) { @@ -469,13 +445,6 @@ Score_element::mark_smob (SCM ses) return s->element_property_alist_; } -scm_sizet -Score_element::free_smob (SCM ses) -{ - Score_element * s = (Score_element*) SCM_CDR(ses); - delete s; - return 0; -} int Score_element::print_smob (SCM s, SCM port, scm_print_state *) @@ -488,16 +457,10 @@ Score_element::print_smob (SCM s, SCM port, scm_print_state *) return 1; } -long Score_element::smob_tag; - void -Score_element::init_smobs () +Score_element::do_smobify_self () { - smob_tag = scm_newsmob (&score_elt_funs); -} - -void -init_smobs() -{ - Score_element::init_smobs (); + scm_unprotect_object (element_property_alist_); // ugh } +#include "ly-smobs.icc" +IMPLEMENT_SMOBS(Score_element); diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 76580cbb38..be6dd2417f 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -262,7 +262,10 @@ Score_engraver::do_try_music (Music*r) void Score_engraver::forbid_breaks () { - SCM junk = command_column_l_->remove_elt_property (breakable_scm_sym); + /* + result is junked. + */ + command_column_l_->remove_elt_property (breakable_scm_sym); } ADD_THIS_TRANSLATOR(Score_engraver); diff --git a/lily/score.cc b/lily/score.cc index 5f9a2b65c5..b517950721 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -36,7 +36,7 @@ Score::Score (Score const &s) for (int i=0; i < s.def_p_arr_.size (); i++) def_p_arr_.push(s.def_p_arr_[i]->clone()); errorlevel_i_ = s.errorlevel_i_; - header_p_ = (s.header_p_) ? new Header (*s.header_p_): 0; + header_p_ = (s.header_p_) ? new Scope (*s.header_p_): 0; } Score::~Score() @@ -60,8 +60,7 @@ Score::run_translator (Music_output_def *odef_l) trans_p->last_mom_ = music_p_->length_mom (); - bool playing = odef_l->scope_p_->elem_b ("unfold_all"); - Music_iterator * iter = Music_iterator::static_get_iterator_p (music_p_, playing); + Music_iterator * iter = Music_iterator::static_get_iterator_p (music_p_); iter->init_translator(music_p_, trans_p); iter->construct_children(); diff --git a/lily/scores.cc b/lily/scores.cc index 65e9c087af..b3899c2d2e 100644 --- a/lily/scores.cc +++ b/lily/scores.cc @@ -23,7 +23,7 @@ Sources* source_global_l = 0; Array inclusion_global_array; Array target_str_global_array; Link_array score_global_array; -Header * header_global_p; +Scope * header_global_p; void write_dependency_file (String fn, Array targets, @@ -69,7 +69,7 @@ void do_scores() { if (!header_global_p) - header_global_p = new Header; + header_global_p = new Scope; for (int i=0; i < score_global_array.size(); i++) { Score* is_p = score_global_array[i]; diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 9c5749b892..ae2dfa312e 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -70,31 +70,32 @@ Script_engraver::do_process_requests() else ss->dir_ = (Direction)force_dir; - Scalar dir_prop (get_property ("articulationScriptVerticalDirection", 0)); - if (dir_prop.isnum_b () && (int) dir_prop != CENTER) - ss->dir_ = (Direction)(int)dir_prop; + SCM dir_prop (get_property ("articulationScriptVerticalDirection", 0)); + if (SCM_NUMBERP(dir_prop)) + ss->dir_ = to_dir (dir_prop); if (l->dir_) ss->dir_ = l->dir_; - Real padding = 0.0; - Scalar paddingprop = get_property ("articulationScriptPadding", 0); - if (paddingprop.length_i() && paddingprop.isnum_b ()) + SCM paddingprop = get_property ("articulationScriptPadding", 0); + if (SCM_NUMBERP(paddingprop)) { - padding = (Real)paddingprop; + ss->set_elt_property (padding_scm_sym, paddingprop); } - Scalar axisprop = get_property ("scriptHorizontal",0); - if (axisprop.to_bool ()) + SCM axisprop = get_property ("scriptHorizontal",0); + if (gh_boolean_p (axisprop) && gh_scm2bool (axisprop)) ss->axis_ = X_AXIS; - if (follow_staff && !axisprop.to_bool ()) + if (follow_staff && !gh_boolean_p (axisprop) && gh_scm2bool (axisprop)) ss->set_elt_property (no_staff_support_scm_sym, SCM_BOOL_T); p->set_staff_side (ss); ss->set_elt_property (script_priority_scm_sym, priority); - if (padding) - ss->set_elt_property (padding_scm_sym, gh_double2scm(padding)); + if (SCM_NUMBERP (paddingprop)) + ss->set_elt_property (padding_scm_sym, paddingprop); + + script_p_arr_.push (p); staff_side_p_arr_.push (ss); @@ -152,7 +153,5 @@ Script_engraver::do_post_move_processing() script_req_l_arr_.clear(); } - - ADD_THIS_TRANSLATOR(Script_engraver); diff --git a/lily/separating-line-group-engraver.cc b/lily/separating-line-group-engraver.cc index 99fc66a907..35e24dab23 100644 --- a/lily/separating-line-group-engraver.cc +++ b/lily/separating-line-group-engraver.cc @@ -31,8 +31,8 @@ Separating_line_group_engraver::do_creation_processing () void Separating_line_group_engraver::do_removal_processing () { - Scalar sz (get_property ("postBreakPadding", 0)); - if (!sz.empty_b () && sz.isnum_b ()) + SCM sz (get_property ("postBreakPadding", 0)); + if (SCM_NUMBERP(sz)) { sep_span_p_->padding_f_ = Real(sz); } diff --git a/lily/simultaneous-music-iterator.cc b/lily/simultaneous-music-iterator.cc index 7f1ff97560..1faaa67c13 100644 --- a/lily/simultaneous-music-iterator.cc +++ b/lily/simultaneous-music-iterator.cc @@ -31,7 +31,7 @@ Simultaneous_music_iterator::construct_children() Cons *i = (sim->music_p_list_p_) ? sim->music_p_list_p_->head_ : 0; for (; i; i = i->next_, j++) { - Music_iterator * mi = static_get_iterator_p (i->car_, playback_b_); + Music_iterator * mi = static_get_iterator_p (i->car_); /* if separate_contexts_b_ is set, create a new context with the number number as name */ diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 6a3a72f05f..0ac32e8d34 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -34,7 +34,7 @@ Slur_engraver::set_melisma (bool m) if (!where) where = daddy_trans_l_; - daddy_trans_l_->set_property ("slurMelismaBusy", m ? "1" :"0"); + daddy_trans_l_->set_property ("slurMelismaBusy", m ? SCM_BOOL_T :SCM_BOOL_F); } void @@ -58,7 +58,9 @@ Slur_engraver::do_removal_processing () typeset_element (slur_l_stack_[i]); } slur_l_stack_.clear (); - if (!get_property ("weAreGraceContext",0).to_bool ()) + SCM wg = get_property ("weAreGraceContext",0); + bool wgb = gh_boolean_p (wg) && gh_scm2bool (wgb); + if (!wgb) for (int i=0; i < requests_arr_.size(); i++) { requests_arr_[i]->warning (_ ("unterminated slur")); @@ -89,9 +91,9 @@ Slur_engraver::do_process_requests() // push a new slur onto stack. //(use temp. array to wait for all slur STOPs) Slur * s_p =new Slur; - Scalar prop = get_property ("slurDash", 0); - if (prop.isnum_b ()) - s_p->set_elt_property (dashed_scm_sym, gh_int2scm(prop)); + SCM prop = get_property ("slurDash", 0); + if (SCM_NUMBERP(prop)) + s_p->set_elt_property (dashed_scm_sym, prop); requests_arr_.push (slur_req_l); @@ -106,14 +108,14 @@ Slur_engraver::do_process_requests() void Slur_engraver::do_pre_move_processing() { - Scalar dir (get_property ("slurVerticalDirection", 0)); - Scalar dir2 (get_property ("verticalDirection", 0)); + SCM dir (get_property ("slurVerticalDirection", 0)); + SCM dir2 (get_property ("verticalDirection", 0)); Direction slurdir = CENTER; - if (dir.length_i () && dir.isnum_b ()) - slurdir = (Direction) sign (int(dir)); - else if (dir2.length_i () && dir2.isnum_b ()) - slurdir = (Direction) sign (int (dir2)); + if (SCM_NUMBERP(dir)) + slurdir = to_dir (dir); + else if (gh_number_p (dir2)) + slurdir = to_dir (dir2); for (int i = 0; i < end_slur_l_arr_.size(); i++) { @@ -127,7 +129,8 @@ void Slur_engraver::do_post_move_processing() { new_slur_req_l_arr_.clear(); - if (get_property ("automaticMelismata",0).to_bool ()) + SCM m = get_property ("automaticMelismata",0); + if (gh_boolean_p (m) && gh_scm2bool (m)) { set_melisma (slur_l_stack_.size ()); } diff --git a/lily/slur.cc b/lily/slur.cc index c8582e8abb..9e3b16d827 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -14,7 +14,7 @@ */ #include "slur.hh" -#include "scalar.hh" + #include "lookup.hh" #include "paper-def.hh" #include "note-column.hh" @@ -243,11 +243,11 @@ Slur::do_post_processing () } while (flip (&d) != LEFT); - bool cross_count = cross_staff_count (); + int cross_count = cross_staff_count (); bool interstaff_b = (0 < cross_count) && (cross_count < encompass_arr_.size ()); Drul_array info_drul; - Interval interstaff_interval; + Drul_array interstaff_interval; do { @@ -257,7 +257,7 @@ Slur::do_post_processing () } while (flip (&d) != LEFT); - Real interstaff_f = interstaff_interval.length (); + Real interstaff_f = interstaff_interval[RIGHT] - interstaff_interval[LEFT]; if (fix_broken_b) { diff --git a/lily/staff-margin-engraver.cc b/lily/staff-margin-engraver.cc index 706d89e990..bddeeb9543 100644 --- a/lily/staff-margin-engraver.cc +++ b/lily/staff-margin-engraver.cc @@ -41,16 +41,17 @@ Staff_margin_engraver::acknowledge_element (Score_element_info inf) return; - String long_str = get_property ("instrument", 0); - String short_str = get_property ("instr", 0); + SCM long_name = get_property ("instrument", 0); + SCM short_name = get_property ("instr", 0); + if (now_mom () > Moment (0)) - long_str = short_str; + long_name = short_name; - if (long_str.empty_b ()) + if (gh_string_p (long_name)) return; create_items (0); - text_p_->text_str_ = long_str; + text_p_->text_str_ = ly_scm2string (long_name); staff_side_p_->dir_ = LEFT; Bar_script_engraver::do_acknowledge_element (i); diff --git a/lily/staff-performer.cc b/lily/staff-performer.cc index 927285702b..853af03f63 100644 --- a/lily/staff-performer.cc +++ b/lily/staff-performer.cc @@ -96,21 +96,17 @@ String Staff_performer::new_instrument_str () { // mustn't ask Score for instrument: it will return piano! - String str = get_property ("midiInstrument", 0); - if (!str.length_i ()) - str = get_property ("instrument", 0); - if (str == instrument_str_) + SCM minstr = get_property ("midiInstrument", 0); + + if (!gh_string_p(minstr)) + minstr = get_property ("instrument", 0); + + if (ly_scm2string (minstr) == instrument_str_) return ""; - instrument_str_ = str; + instrument_str_ = ly_scm2string (minstr); return instrument_str_; - -/* ugh, but can 't - if (properties_dict_.elem_b ("instrument")) - return properties_dict_["instrument"]; - return ""; -*/ } void diff --git a/lily/staff-switching-translator.cc b/lily/staff-switching-translator.cc deleted file mode 100644 index 1d1809ed84..0000000000 --- a/lily/staff-switching-translator.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - staff-switching-translator.cc -- implement Staff_switching_translator - - source file of the GNU LilyPond music typesetter - - (c) 1999 Han-Wen Nienhuys - - */ -#include "engraver.hh" -#include "interpretation-context-handle.hh" -#include "drul-array.hh" -#include "engraver-group-engraver.hh" -#include "musical-request.hh" - -class Staff_switching_translator : public Engraver -{ - Interpretation_context_handle my_voice_; - Drul_array staff_handle_drul_; - - int switch_pitch_i_ ; -protected: - virtual bool do_try_music (Music* m); - virtual void do_creation_processing (); - - void default_voice (Direction); -public: - Staff_switching_translator (); - VIRTUAL_COPY_CONS(Translator); -}; - -Staff_switching_translator::Staff_switching_translator () -{ - switch_pitch_i_ =0; -} - -void -Staff_switching_translator::do_creation_processing () -{ - Translator_group * daddy =daddy_grav_l (); // staff switching context - - - Scalar pit = get_property ("switchPitch", 0); - if (pit.isnum_b ()) - switch_pitch_i_ = int (pit); - Scalar s = get_property("staffContextName", 0); - Scalar up = get_property ("upStaffName",0); - Scalar down = get_property ("downStaffName",0); - if (!up.length_i()) up = "upper"; - if (!down.length_i()) up = "lower"; - - staff_handle_drul_[UP].set_translator (daddy->daddy_trans_l_ -> find_create_translator_l (s, up)); - staff_handle_drul_[DOWN].set_translator (daddy->daddy_trans_l_-> find_create_translator_l (s, down)); - - - staff_handle_drul_[DOWN].report_to_l ()->set_property ("defaultClef", "bass"); - - default_voice (UP); -} - - -void -Staff_switching_translator::default_voice (Direction d) -{ - Scalar s = get_property ("acceptorName",0); - my_voice_.set_translator (staff_handle_drul_[d].report_to_l ()->find_create_translator_l ("Thread", daddy_trans_l_->id_str_)); -} - -bool -Staff_switching_translator::do_try_music (Music*m) -{ - if (Note_req*nr = dynamic_cast (m)) - { - Direction staff = (nr->pitch_.semitone_pitch () >= switch_pitch_i_) - ? UP - : DOWN; - - - Translator_group * mv = my_voice_.report_to_l (); - Translator_group *dest_staff =staff_handle_drul_[staff].report_to_l (); - Scalar s = get_property ("switcherName", 0); - - while (mv && mv->type_str_ != s) - { - mv = mv -> daddy_trans_l_; - } - - if (!mv) - default_voice (staff); - - if (mv->daddy_trans_l_ != dest_staff) - { - mv->daddy_trans_l_->remove_translator_p (mv); - dest_staff->add_translator (mv); - } - } - - return my_voice_.try_music (m); -} - -ADD_THIS_TRANSLATOR(Staff_switching_translator); diff --git a/lily/staff-sym-engraver.cc b/lily/staff-sym-engraver.cc index b665200f35..93e41b28ab 100644 --- a/lily/staff-sym-engraver.cc +++ b/lily/staff-sym-engraver.cc @@ -34,16 +34,16 @@ Staff_symbol_engraver::do_creation_processing() void Staff_symbol_engraver::do_removal_processing() { - Scalar l (get_property ("numberOfStaffLines", 0)); - if (l.isnum_b ()) + SCM l (get_property ("numberOfStaffLines", 0)); + if (SCM_NUMBERP(l)) { - span_p_->no_lines_i_ = l; + span_p_->no_lines_i_ = gh_scm2int (l); } - Scalar sz (get_property ("staffLineLeading", 0)); - if (!sz.empty_b () && sz.isnum_b ()) + SCM sz (get_property ("staffLineLeading", 0)); + if (SCM_NUMBERP(sz)) { - span_p_->staff_line_leading_f_ = Real(sz); + span_p_->staff_line_leading_f_ = gh_scm2double (sz); } else { diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc index 1679e52441..d48fa3925f 100644 --- a/lily/stem-engraver.cc +++ b/lily/stem-engraver.cc @@ -28,10 +28,10 @@ Stem_engraver::Stem_engraver() void Stem_engraver::do_creation_processing () { - Scalar prop = get_property ("abbrev", 0); - if (prop.isnum_b ()) + SCM prop = get_property ("abbrev", 0); + if (SCM_NUMBERP(prop)) { - default_abbrev_i_ = prop; + default_abbrev_i_ = gh_scm2int (prop); } } @@ -96,38 +96,43 @@ Stem_engraver::do_pre_move_processing() if (stem_p_) { - Scalar prop = get_property ("verticalDirection", 0); - Direction dir = prop.isnum_b () ? (Direction)int(prop) : CENTER; - if (dir) + SCM prop = get_property ("verticalDirection", 0); + if (SCM_NUMBERP(prop)) { - stem_p_->dir_ = dir; + stem_p_->dir_ = to_dir (prop); stem_p_->set_elt_property (dir_forced_scm_sym, SCM_BOOL_T); } Translator_group* which; prop = get_property ("stemLeftBeamCount", &which); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - stem_p_->beams_i_drul_[LEFT] = prop; - ((Translator_group*)which)->set_property ("stemLeftBeamCount", ""); + stem_p_->beams_i_drul_[LEFT] = gh_scm2int (prop); + ((Translator_group*)which)->set_property ("stemLeftBeamCount", SCM_UNDEFINED); } prop = get_property ("stemRightBeamCount", &which); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - stem_p_->beams_i_drul_[RIGHT] = prop; - ((Translator_group*)which)->set_property ("stemRightBeamCount", ""); + stem_p_->beams_i_drul_[RIGHT] = gh_scm2int (prop); + ((Translator_group*)which)->set_property ("stemRightBeamCount", SCM_UNDEFINED); } prop = get_property ("stemLength", 0); - if (prop.isnum_b ()) + if (SCM_NUMBERP(prop)) { - stem_p_->set_elt_property (length_scm_sym, gh_double2scm (prop.to_f ())); + stem_p_->set_elt_property (length_scm_sym, prop); } prop = get_property ("stemStyle", 0); - if (prop.to_bool ()) + if (gh_string_p (prop)) { - stem_p_->set_elt_property (style_scm_sym, ly_ch_C_to_scm (prop.ch_C())); + stem_p_->set_elt_property (style_scm_sym, prop); + } + + prop = get_property ("noStemExtend", 0); + if (gh_boolean_p (prop) && gh_scm2bool (prop)) + { + stem_p_->set_elt_property (no_stem_extend_scm_sym, prop); } typeset_element(stem_p_); diff --git a/lily/stem-info.cc b/lily/stem-info.cc index 4a9e06e05e..f555ab0a6b 100644 --- a/lily/stem-info.cc +++ b/lily/stem-info.cc @@ -35,7 +35,6 @@ Stem_info::Stem_info (Stem*s, int mult) SCM bd = stem_l_->remove_elt_property (beam_dir_scm_sym); beam_dir_ = gh_scm2int (SCM_CDR(bd)); - interstaff_f_ = 0; Paper_def* paper_l = stem_l_->paper_l (); Real internote_f = stem_l_->staff_line_leading_f ()/2; @@ -53,6 +52,8 @@ Stem_info::Stem_info (Stem*s, int mult) idealy_f_ *= beam_dir_; bool grace_b = stem_l_->get_elt_property (grace_scm_sym) != SCM_BOOL_F; + bool no_extend_b = stem_l_->get_elt_property (no_stem_extend_scm_sym) + != SCM_BOOL_F; int stem_max = (int)rint(paper_l->get_var ("stem_max")); String type_str = grace_b ? "grace_" : ""; @@ -85,7 +86,7 @@ Stem_info::Stem_info (Stem*s, int mult) than middle staffline, just as normal stems. */ - if (!grace_b) + if (!grace_b && !no_extend_b) { //highest beam of (UP) beam must never be lower than middle staffline miny_f_ = miny_f_ >? 0; @@ -116,9 +117,9 @@ Stem_info::Stem_info (Stem*s, int mult) // interstaff beam Beam* beam_l = stem_l_->beam_l_; - Real is = calc_interstaff_dist (stem_l_, beam_l); - idealy_f_ += is* beam_dir_; - miny_f_ += is * beam_dir_; - maxy_f_ += is * beam_dir_; + interstaff_f_ = calc_interstaff_dist (stem_l_, beam_l) / internote_f; + idealy_f_ += interstaff_f_* beam_dir_; + miny_f_ += interstaff_f_ * beam_dir_; + maxy_f_ += interstaff_f_ * beam_dir_; } diff --git a/lily/stem.cc b/lily/stem.cc index 919969187c..7c7797a385 100644 --- a/lily/stem.cc +++ b/lily/stem.cc @@ -201,7 +201,8 @@ Stem::set_default_stemlen () set_stemend ((dir_ > 0) ? head_positions()[BIGGER] + length_f: head_positions()[SMALLER] - length_f); - if (!grace_b && (dir_ * stem_end_f () < 0)) + bool no_extend_b = get_elt_property (no_stem_extend_scm_sym) != SCM_BOOL_F; + if (!grace_b && !no_extend_b && (dir_ * stem_end_f () < 0)) set_stemend (0); } diff --git a/lily/text-engraver.cc b/lily/text-engraver.cc index 1d652e935e..9ecc46f434 100644 --- a/lily/text-engraver.cc +++ b/lily/text-engraver.cc @@ -83,8 +83,8 @@ Text_engraver::do_process_requests () - Scalar axisprop = get_property ("scriptHorizontal",0); - if (axisprop.to_bool ()) + SCM axisprop = get_property ("scriptHorizontal",0); + if (gh_boolean_p (axisprop) && gh_scm2bool (axisprop)) { ss->axis_ = X_AXIS; text->set_parent (ss, Y_AXIS); @@ -100,21 +100,21 @@ Text_engraver::do_process_requests () if (r->style_str_.empty_b ()) { - Scalar p (get_property ("textStyle", 0)); - if (p.length_i ()) - text->style_str_ = p; + SCM p (get_property ("textStyle", 0)); + if (gh_string_p (p)) + text->style_str_ = ly_scm2string(p); } else text->style_str_ = r->style_str_; - Scalar padding = get_property ("textScriptPadding", 0); - if (padding.length_i() && padding.isnum_b ()) + SCM padding = get_property ("textScriptPadding", 0); + if (SCM_NUMBERP(padding)) { - ss->set_elt_property (padding_scm_sym, gh_double2scm(Real(padding))); + ss->set_elt_property (padding_scm_sym, padding); } - Scalar empty = get_property ("textEmptyDimension", 0); - if (empty.to_bool ()) + SCM empty = get_property ("textEmptyDimension", 0); + if (gh_boolean_p (empty) && gh_scm2bool (empty)) { text->set_empty (true, X_AXIS); } diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 4d3c8ca01c..946f8e9367 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -26,7 +26,9 @@ Tie_engraver::do_try_music (Music *m) if (Tie_req * c = dynamic_cast (m)) { req_l_ = c; - if (get_property ("automaticMelismata",0).to_bool ()) + SCM m = get_property ("automaticMelismata",0); + bool am = gh_boolean_p (m) &&gh_scm2bool (m); + if (am) { set_melisma (true); } @@ -43,7 +45,7 @@ Tie_engraver::set_melisma (bool m) if (!where) where = daddy_trans_l_; - daddy_trans_l_->set_property ("tieMelismaBusy", m ? "1" :"0"); + daddy_trans_l_->set_property ("tieMelismaBusy", m ? SCM_BOOL_T : SCM_BOOL_F); } void @@ -76,89 +78,55 @@ Tie_engraver::do_process_requests () void Tie_engraver::process_acknowledged () { - bool old_behavior = get_property ("oldTieBehavior", 0).to_bool (); - if (req_l_) { - - /* - JUNKME! - */ - if (old_behavior) + now_heads_.sort (CHead_melodic_tuple::pitch_compare); + stopped_heads_.sort(CHead_melodic_tuple::pitch_compare); + int i=0; + int j=0; + int tie_count=0; + while ( i < now_heads_.size () && j < stopped_heads_.size ()) { - if (now_heads_.size () != stopped_heads_.size ()) - { - req_l_->warning (_ ("unequal number of note heads for tie")); - } - int sz = now_heads_.size () pitch_ , + stopped_heads_[j].req_l_->pitch_); - now_heads_.sort (CHead_melodic_tuple::pitch_compare); - stopped_heads_.sort(CHead_melodic_tuple::pitch_compare); - - for (int i=0; i < sz; i++) + if (comp) { - Tie * p = new Tie; - p->set_head (LEFT, stopped_heads_[i].head_l_); - p->set_head (RIGHT, now_heads_[i].head_l_); - tie_p_arr_.push (p); - announce_element (Score_element_info (p, req_l_)); + (comp < 0) ? i ++ : j++; + continue; } - } - else - { - now_heads_.sort (CHead_melodic_tuple::pitch_compare); - stopped_heads_.sort(CHead_melodic_tuple::pitch_compare); - int i=0; - int j=0; - int tie_count=0; - while ( i < now_heads_.size () && j < stopped_heads_.size ()) + else { - int comp - = Musical_pitch::compare (now_heads_[i].req_l_->pitch_ , - stopped_heads_[j].req_l_->pitch_); + tie_count ++; - if (comp) + /* don't go around recreating ties that were already + made. Not infallible. Due to reordering in sort (), + we will make the wrong ties when noteheads are + added. */ + if (tie_count > tie_p_arr_.size ()) { - (comp < 0) ? i ++ : j++; - continue; + Tie * p = new Tie; + p->set_head (LEFT, stopped_heads_[j].head_l_); + p->set_head (RIGHT, now_heads_[i].head_l_); + tie_p_arr_.push (p); + announce_element (Score_element_info (p, req_l_)); } - else - { - tie_count ++; - - /* don't go around recreating ties that were already - made. Not infallible. Due to reordering in sort (), - we will make the wrong ties when noteheads are - added. */ - if (tie_count > tie_p_arr_.size ()) - { - Tie * p = new Tie; - p->set_head (LEFT, stopped_heads_[j].head_l_); - p->set_head (RIGHT, now_heads_[i].head_l_); - tie_p_arr_.push (p); - announce_element (Score_element_info (p, req_l_)); - } - i++; - j++; + i++; + j++; - } } + } - if (!tie_p_arr_.size ()) - { - req_l_->warning (_ ("No ties were created!")); - } - + if (!tie_p_arr_.size ()) + { + req_l_->warning (_ ("No ties were created!")); } + } } + void Tie_engraver::do_pre_move_processing () { @@ -168,14 +136,14 @@ Tie_engraver::do_pre_move_processing () } now_heads_.clear (); - Scalar dir (get_property ("tieVerticalDirection", 0)); - Scalar dir2 (get_property ("verticalDirection", 0)); + SCM dir (get_property ("tieVerticalDirection", 0)); + SCM dir2 (get_property ("verticalDirection", 0)); Direction tie_dir = CENTER; - if (dir.length_i () && dir.isnum_b ()) - tie_dir = (Direction) sign (int(dir)); - else if (dir2.length_i () && dir2.isnum_b ()) - tie_dir = (Direction) sign (int (dir2)); + if (SCM_NUMBERP(dir)) + tie_dir = to_dir (dir); + else if (isdir_b (dir2)) + tie_dir = to_dir (dir2); for (int i=0; i< tie_p_arr_.size (); i++) { @@ -188,7 +156,8 @@ Tie_engraver::do_pre_move_processing () void Tie_engraver::do_post_move_processing () { - if (get_property ("automaticMelismata",0).to_bool ()) + SCM m = get_property ("automaticMelismata",0); + if (gh_boolean_p (m) && gh_scm2bool (m)) { set_melisma (false); } diff --git a/lily/time-signature-engraver.cc b/lily/time-signature-engraver.cc index a71769709f..d9051d59ae 100644 --- a/lily/time-signature-engraver.cc +++ b/lily/time-signature-engraver.cc @@ -54,10 +54,10 @@ Time_signature_engraver::do_pre_move_processing() { if (time_signature_p_) { - Scalar sigstyle = get_property ("timeSignatureStyle", 0); - if (sigstyle.length_i ()) + SCM sigstyle = get_property ("timeSignatureStyle", 0); + if (gh_string_p (sigstyle)) { - time_signature_p_->time_sig_type_str_ = sigstyle; + time_signature_p_->time_sig_type_str_ = ly_scm2string (sigstyle); } typeset_element (time_signature_p_); diff --git a/lily/time-signature.cc b/lily/time-signature.cc index 75bbaa2ee2..a4960abc7b 100644 --- a/lily/time-signature.cc +++ b/lily/time-signature.cc @@ -7,7 +7,7 @@ */ -#include "scalar.hh" + #include "molecule.hh" #include "time-signature.hh" #include "paper-def.hh" diff --git a/lily/timing-engraver.cc b/lily/timing-engraver.cc index 3fa208f15d..29ee1d6d8c 100644 --- a/lily/timing-engraver.cc +++ b/lily/timing-engraver.cc @@ -53,12 +53,15 @@ Timing_engraver::which_bar () if (!now_mom ()) return "|"; - Scalar nonauto = get_property ("barNonAuto", 0); - if (!nonauto.to_bool ()) + SCM nonauto = get_property ("barNonAuto", 0); + if (!gh_boolean_p (nonauto) && gh_scm2bool (nonauto)) { - Scalar always = get_property ("barAlways", 0); - if (!time_.whole_in_measure_ || always.to_bool ()) - return get_property ("defaultBarType" ,0); + SCM always = get_property ("barAlways", 0); + if (!time_.whole_in_measure_ || gh_boolean_p (always) && gh_scm2bool (always)) + { + SCM def=get_property ("defaultBarType" ,0); + return (gh_string_p (def))? ly_scm2string (def) : ""; + } } return ""; } diff --git a/lily/timing-translator.cc b/lily/timing-translator.cc index 92db7ee737..82ab9dc0be 100644 --- a/lily/timing-translator.cc +++ b/lily/timing-translator.cc @@ -94,14 +94,12 @@ Timing_translator::do_process_requests() Translator_group * tr=0; - Scalar barn = get_property ("currentBarNumber", &tr); - if (!barn.empty_b () && barn.isnum_b ()) + SCM barn = get_property ("currentBarNumber", &tr); + if (SCM_NUMBERP(barn)) { - time_.bars_i_ = int(barn); - tr->set_property ("currentBarNumber", ""); + time_.bars_i_ = gh_scm2int (barn); + tr->set_property ("currentBarNumber", SCM_UNDEFINED); } - - } @@ -119,7 +117,8 @@ Timing_translator::do_pre_move_processing() while (!global_l); /* allbars == ! skipbars */ - bool allbars = ! get_property ("skipBars", 0).to_bool (); + SCM sb = get_property ("skipBars", 0); + bool allbars = !(gh_boolean_p (sb)&&gh_scm2bool (sb)); // urg: multi bar rests: should always process whole of first bar? if (!time_.cadenza_b_ && allbars) diff --git a/lily/translation-property.cc b/lily/translation-property.cc index 8811d85d9b..42e4364349 100644 --- a/lily/translation-property.cc +++ b/lily/translation-property.cc @@ -9,12 +9,12 @@ #include "translation-property.hh" #include "debug.hh" - - void Translation_property::do_print () const { #ifndef NPRINT - DEBUG_OUT << "." << var_str_ << " = " << value_; + DEBUG_OUT << "." << var_str_ << " = " ; + if (flower_dstream && !flower_dstream->silent_b ("Translation_property")) + ly_display_scm (value_); #endif } diff --git a/lily/translator-group.cc b/lily/translator-group.cc index fc4ca2a44d..cffdaf8905 100644 --- a/lily/translator-group.cc +++ b/lily/translator-group.cc @@ -10,7 +10,7 @@ #include "translator-group.hh" #include "translator.hh" #include "debug.hh" -#include "rational.hh" +#include "moment.hh" #include "dictionary-iter.hh" #include "killing-cons.tcc" @@ -373,10 +373,8 @@ Translator_group::do_print() const #ifndef NPRINT if (!flower_dstream) return ; - for (Dictionary_iter i (properties_dict_); i.ok (); i++) - { - DEBUG_OUT << i.key () << "=" << i.val () << '\n'; - } + + gh_display (properties_dict_.self_scm_); if (status == ORPHAN) { DEBUG_OUT << "consists of: "; @@ -449,29 +447,29 @@ Translator_group::do_add_processing () } } -Scalar +SCM Translator_group::get_property (String id, Translator_group **where_l) const { - if (properties_dict_.elem_b (id)) + SCM sym = ly_symbol (id); + if (properties_dict_.elem_b (sym)) { if (where_l) *where_l = (Translator_group*) this; // ugh - return properties_dict_[id]; + return properties_dict_[sym]; } -#if 1 if (daddy_trans_l_) return daddy_trans_l_->get_property (id, where_l); -#endif if (where_l) *where_l = 0; - return ""; + + return SCM_UNDEFINED; } void -Translator_group::set_property (String id, Scalar val) +Translator_group::set_property (String id, SCM val) { - properties_dict_[id] = val; + properties_dict_[ly_symbol (id)] = val; } diff --git a/lily/translator.cc b/lily/translator.cc index a5a3b68d51..218a8c1423 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -11,7 +11,7 @@ #include "debug.hh" #include "translator-group.hh" -#include "rational.hh" +#include "moment.hh" char const* Translator::name() const @@ -163,7 +163,7 @@ Translator::output_def_l () const return output_def_l_; } -Scalar +SCM Translator::get_property (String id, Translator_group **where_l) const { return daddy_trans_l_->get_property (id, where_l); diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index c067169a8c..ce9c2cd2de 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -35,13 +35,13 @@ void Tuplet_engraver::do_process_requests () { int dir = 0; - Scalar prop = get_property ("tupletDirection", 0); - if (prop.isnum_b()) - dir = (int)prop; + SCM prop = get_property ("tupletDirection", 0); + if (isdir_b (prop)) + dir = to_dir (prop); int visibility = 3; prop = get_property ("tupletVisibility", 0); - if (prop.isnum_b()) - visibility = (int)prop; + if (SCM_NUMBERP(prop)) + visibility = gh_scm2int (prop); // bool ? for (int i= started_span_p_arr_.size (); i < time_scaled_music_arr_.size (); i++) @@ -61,7 +61,9 @@ void Tuplet_engraver::acknowledge_element (Score_element_info i) { bool grace= (i.elem_l_->get_elt_property (grace_scm_sym) != SCM_BOOL_F); - if (grace != get_property ("weAreGraceContext",0).to_bool ()) + SCM wg = get_property ("weAreGraceContext",0); + bool wgb = gh_boolean_p (wg) && gh_scm2bool (wg); + if (grace != wgb) return; if (Note_column *nc = dynamic_cast (i.elem_l_)) diff --git a/lily/tuplet-spanner.cc b/lily/tuplet-spanner.cc index 8ea56cdd42..234a4f982a 100644 --- a/lily/tuplet-spanner.cc +++ b/lily/tuplet-spanner.cc @@ -38,6 +38,10 @@ Tuplet_spanner::do_brew_molecule_p () const SCM visibility_sym =get_elt_property (tuplet_visibility_scm_sym); if (visibility_sym != SCM_BOOL_F) { + /* + ARG. Fixme. + */ + /* Property values: 0 show nothing 1 show number diff --git a/lily/unfolded-repeat-iterator.cc b/lily/unfolded-repeat-iterator.cc index 901d69f80b..347e929b4a 100644 --- a/lily/unfolded-repeat-iterator.cc +++ b/lily/unfolded-repeat-iterator.cc @@ -49,7 +49,7 @@ Unfolded_repeat_iterator::next_element () { done_mom_ += mus->repeat_body_p_->length_mom (); - if (full_unfold_b_) + if (!mus->volta_fold_b_) done_count_ ++; if (alternative_cons_l_) @@ -57,7 +57,7 @@ Unfolded_repeat_iterator::next_element () current_iter_p_ = get_iterator_p (alternative_cons_l_->car_); do_main_b_ = false; } - else if (done_count_ < mus->repeats_i_ && full_unfold_b_) + else if (done_count_ < mus->repeats_i_ && !mus->volta_fold_b_) { current_iter_p_ = get_iterator_p (mus->repeat_body_p_); do_main_b_ = true; @@ -73,20 +73,20 @@ Unfolded_repeat_iterator::next_element () { done_mom_ += alternative_cons_l_->car_->length_mom (); - if (!full_unfold_b_ || + if (mus->volta_fold_b_ || mus->repeats_i_ - done_count_ < alternative_count_i_) alternative_cons_l_ = alternative_cons_l_->next_; /* we've done the main body as well, but didn't go over the other increment. */ - if (full_unfold_b_) + if (mus->volta_fold_b_) done_count_ ++; } if (done_count_ < mus->repeats_i_ && alternative_cons_l_) { - if (!full_unfold_b_) + if (mus->volta_fold_b_) current_iter_p_ = get_iterator_p (alternative_cons_l_->car_); else { @@ -114,8 +114,6 @@ void Unfolded_repeat_iterator::construct_children () { Repeated_music const* mus =dynamic_cast (music_l_); - full_unfold_b_ = playback_b_ || (!mus->volta_fold_b_); - alternative_cons_l_ = (mus->alternatives_p_) ? mus->alternatives_p_->music_p_list_p_->head_ : 0; @@ -167,7 +165,7 @@ void Unfolded_repeat_iterator::do_print () const { #ifndef NPRINT - DEBUG_OUT << "count " << done_count_ << "done time " << done_mom_ << '\n'; + DEBUG_OUT << "count " << done_count_ << "done time " << Rational (done_mom_) << '\n'; DEBUG_OUT << "current: "; current_iter_p_->print(); #endif diff --git a/lily/vertical-align-engraver.cc b/lily/vertical-align-engraver.cc index 9614f5b359..2497fd4f59 100644 --- a/lily/vertical-align-engraver.cc +++ b/lily/vertical-align-engraver.cc @@ -32,22 +32,22 @@ Vertical_align_engraver::do_creation_processing() void Vertical_align_engraver::do_removal_processing() { - Scalar dist (get_property ("maxVerticalAlign", 0)); - if (dist.length_i () && dist.isnum_b ()) + SCM dist (get_property ("maxVerticalAlign", 0)); + if (SCM_NUMBERP(dist)) { - valign_p_->threshold_interval_[BIGGER] = Real (dist); + valign_p_->threshold_interval_[BIGGER] = gh_scm2double (dist); } dist = get_property ("minVerticalAlign", 0); - if (dist.length_i () && dist.isnum_b ()) + if (SCM_NUMBERP(dist)) { - valign_p_->threshold_interval_[SMALLER] = Real (dist); + valign_p_->threshold_interval_[SMALLER] = gh_scm2double (dist); } dist = get_property ("alignmentReference",0); - if (dist.length_i () && dist.isnum_b ()) + if (isdir_b (dist)) { - valign_p_->align_dir_ = (Direction)(int)dist; + valign_p_->align_dir_ = to_dir (dist); } valign_p_->set_bounds(RIGHT,get_staff_info().command_pcol_l ()); typeset_element (valign_p_); diff --git a/ly/accordion-defs.ly b/ly/accordion-defs.ly index b4051d111a..c8caeabfd4 100644 --- a/ly/accordion-defs.ly +++ b/ly/accordion-defs.ly @@ -6,7 +6,7 @@ % 16' = S % -\scmfile "accordion-script.scm"; +#(eval-string (ly-gulp-file "accordion-script.scm")) accDiscant = \script "accDiscant" accDiscantF = \script "accDiscantF" diff --git a/ly/auto-beam-settings.ly b/ly/auto-beam-settings.ly index 71b2c55cab..c3f20c4886 100644 --- a/ly/auto-beam-settings.ly +++ b/ly/auto-beam-settings.ly @@ -1,7 +1,3 @@ -%%In the file ly/auto-beam-settings.ly, all necessary i-iii settings should -%%be listed, here's a new version with more comments, (hw, please include). -%%duh - % auto-beam-settings.ly % setup for auto-beam engraver % @@ -21,47 +17,49 @@ % end beams each 1/2 note % end beams with 16th notes each 1/4 note % end beams with 32th notes each 1/8 note -time3_2beamAutoEnd = "1/2"; -time3_2beamAutoEnd_16 = "1/4"; -time3_2beamAutoEnd_32 = "1/8"; -time3_4beamAutoBegin_8 = "1/4"; -time3_4beamAutoEnd = "3/4"; -time3_4beamAutoBegin_16 = "1/16"; -time3_4beamAutoEnd_16 = "1/4"; -%time3_4beamAutoBegin_32 = "1/8"; -time3_4beamAutoEnd_32 = "1/8"; +time3_2beamAutoEnd = #(make-moment 1 2) +%time3_2beamAutoEnd_16 = #(make-moment 1 4) +time3_2beamAutoEnd_16 = #(make-moment 1 4) +time3_2beamAutoEnd_32 = #(begin (make-moment 1 8)) + +time3_4beamAutoBegin_8 = #(begin (make-moment 1 4)) +time3_4beamAutoEnd = #(begin (make-moment 3 4)) +time3_4beamAutoBegin_16 = #(begin (make-moment 1 16)) +time3_4beamAutoEnd_16 = #(begin (make-moment 1 4)) +%time3_4beamAutoBegin_32 = #(begin (make-moment 1 8)) +time3_4beamAutoEnd_32 = #(begin (make-moment 1 8)) -time3_8beamAutoBegin = "1/8"; -time3_8beamAutoEnd = "3/8"; +time3_8beamAutoBegin = #(begin (make-moment 1 8)) +time3_8beamAutoEnd = #(begin (make-moment 3 8)) % in common time: % end beams each 1/2 note % end beams with 32th notes each 1/8 note % end beams with 1/8 triplets each 1/4 note -time4_4beamAutoEnd = "1/2"; -time4_4beamAutoEnd_12 = "1/4"; -time4_4beamAutoEnd_16 = "1/4"; -time4_4beamAutoEnd_32 = "1/8"; +time4_4beamAutoEnd = #(begin (make-moment 1 2)) +time4_4beamAutoEnd_12 = #(begin (make-moment 1 4)) +time4_4beamAutoEnd_16 = #(begin (make-moment 1 4)) +time4_4beamAutoEnd_32 = #(begin (make-moment 1 8)) -time4_8beamAutoEnd = "1/4"; -time4_8beamAutoEnd_16 = "1/4"; -time4_8beamAutoEnd_32 = "1/8"; +time4_8beamAutoEnd = #(begin (make-moment 1 4)) +time4_8beamAutoEnd_16 = #(begin (make-moment 1 4)) +time4_8beamAutoEnd_32 = #(begin (make-moment 1 8)) -time4_16beamAutoEnd = "1/8"; +time4_16beamAutoEnd = #(begin (make-moment 1 8)) -time6_8beamAutoEnd = "3/8"; -time6_8beamAutoEnd_16 = "3/8"; -time6_8beamAutoEnd_32 = "1/8"; +time6_8beamAutoEnd = #(begin (make-moment 3 8)) +time6_8beamAutoEnd_16 = #(begin (make-moment 3 8)) +time6_8beamAutoEnd_32 = #(begin (make-moment 1 8)) -time9_8beamAutoEnd = "3/8"; -time9_8beamAutoEnd_16 = "3/8"; -time9_8beamAutoEnd_32 = "1/8"; +time9_8beamAutoEnd = #(begin (make-moment 3 8)) +time9_8beamAutoEnd_16 = #(begin (make-moment 3 8)) +time9_8beamAutoEnd_32 = #(begin (make-moment 1 8)) -time12_8beamAutoEnd = "3/8"; -time12_8beamAutoEnd_16 = "3/8"; -time12_8beamAutoEnd_32 = "1/8"; +time12_8beamAutoEnd = #(begin (make-moment 3 8)) +time12_8beamAutoEnd_16 = #(begin (make-moment 3 8)) +time12_8beamAutoEnd_32 = #(begin (make-moment 1 8)) @@ -70,10 +68,10 @@ time12_8beamAutoEnd_32 = "1/8"; Users may override in most cases, simply by issuing % from here on consider ending beam every 1/4 note - \property Voice.beamAutoEnd = "1/4" + \property Voice.beamAutoEnd = #(make-moment 1 4) % no autobeaming - \property Voice.beamAuto = "0" + \property Voice.beamAuto = ##f or, more globally, by doing: @@ -81,7 +79,7 @@ or, more globally, by doing: \translator{ \VoiceContext % consider ending beam at every 1/2 note - beamAutoEnd = "1/2"; + beamAutoEnd = #(make-moment 1 2) } } diff --git a/ly/declarations.ly b/ly/declarations.ly index a6e51b9395..5643839893 100644 --- a/ly/declarations.ly +++ b/ly/declarations.ly @@ -34,8 +34,8 @@ lydian = 7 phrygian = 8 dorian = 10 -melisma = \property Staff.melismaBusy = "1" -melismaEnd = \property Staff.melismaBusy = "0" +melisma = \property Staff.melismaBusy = ##t +melismaEnd = \property Staff.melismaBusy = ##f diff --git a/ly/engraver.ly b/ly/engraver.ly index 1e8acfac43..b323524d32 100644 --- a/ly/engraver.ly +++ b/ly/engraver.ly @@ -5,8 +5,8 @@ StaffContext=\translator { \type "Engraver_group_engraver"; \name Staff ; - barAuto = "1"; - voltaVisibility = "1"; + barAuto = ##t + voltaVisibility = ##t \consists "Multi_measure_rest_engraver"; \consists "Bar_engraver"; @@ -33,16 +33,15 @@ StaffContext=\translator { %{ \consists "Staff_margin_engraver"; %} - defaultClef = treble; - - marginBreakPriority = "-5"; + defaultClef = #"treble" + marginBreakPriority = #-5 \consists "Separating_line_group_engraver"; \consists "Font_size_engraver"; \accepts "Voice"; - dynamicStyle = "dynamic"; + dynamicStyle = #"dynamic" }; \translator{\StaffContext } @@ -66,7 +65,8 @@ StaffContext=\translator { RhythmicStaffContext=\translator{ \type "Engraver_group_engraver"; - numberOfStaffLines = "1"; + numberOfStaffLines = #1 + barSize = \staffheight; \consists "Pitch_squash_engraver"; \consists "Separating_line_group_engraver"; @@ -82,7 +82,7 @@ RhythmicStaffContext=\translator{ \translator{\RhythmicStaffContext} VoiceContext = \translator { \type "Engraver_group_engraver"; - dynamicPadding = "5.0"; + dynamicPadding = #5.0 \consists "Dynamic_engraver"; % must come before text_engraver. \name Voice ; @@ -99,7 +99,7 @@ VoiceContext = \translator { % ugh. Order matters here. \consists "Melisma_engraver"; - textScriptPadding = "3.0"; + textScriptPadding = #3.0 \consists "Text_engraver"; \consists "Script_engraver"; \consists "Script_column_engraver"; @@ -122,6 +122,7 @@ GraceContext=\translator { \consists "Stem_engraver"; \consists "Beam_engraver"; \consists "Slur_engraver"; + \consists "Auto_beam_engraver"; \include "auto-beam-settings.ly"; \consists "Align_note_column_engraver"; @@ -129,11 +130,11 @@ GraceContext=\translator { \consists "Rhythmic_column_engraver"; \consists "Dynamic_engraver"; - stemStyle = "grace"; - weAreGraceContext = "1"; - fontSize = "-1"; - stemLength = "6.0"; - verticalDirection = "1"; + stemStyle = #"grace" + weAreGraceContext = ##t + fontSize = #-1 + stemLength = #6.0 + verticalDirection = \up ; graceAccidentalSpace= 1.5 * \interline; }; @@ -153,9 +154,7 @@ GrandStaffContext=\translator{ \consists "Span_bar_engraver"; \consists "Piano_bar_engraver"; - \accepts "Staff"; - }; \translator{\GrandStaffContext} @@ -174,7 +173,6 @@ PianoStaffContext = \translator{\GrandStaffContext StaffGroupContext= \translator { \type "Engraver_group_engraver"; \consists "Span_bar_engraver"; - \consists "Staff_group_bar_engraver"; \name StaffGroup; @@ -186,6 +184,7 @@ StaffGroupContext= \translator { \accepts "Lyrics"; \accepts "ChordNames"; }; + \translator { \StaffGroupContext } % UGH! JUNKME @@ -248,8 +247,8 @@ StupidScore = \translator { BarNumberingStaffContext = \translator { \StaffContext - barColumnPriority = "0"; - marginBreakPriority = "-4"; + barColumnPriority = #0 + marginBreakPriority = #-4 \consists "Mark_engraver"; \consists "Bar_number_engraver"; }; @@ -263,8 +262,8 @@ HaraKiriStaffContext = \translator { OrchestralPartStaffContext = \translator { \StaffContext - barColumnPriority = "0"; - marginBreakPriority = "-4"; + barColumnPriority = #0 + marginBreakPriority = #-4 \consists "Mark_engraver"; \consists "Bar_number_engraver"; }; @@ -280,8 +279,8 @@ ScoreContext = \translator { \consists "Spacing_engraver"; \consists "Vertical_align_engraver"; alignmentReference = \down; - defaultClef = treble; - defaultBarType = "|"; + defaultClef = #"treble" + defaultBarType = #"|" \accepts "Staff"; \accepts "StaffGroup"; \accepts "RhythmicStaff"; @@ -297,8 +296,8 @@ ScoreContext = \translator { OrchestralScoreContext= \translator { \ScoreContext - barScriptPadding = "2.0"; % dimension \pt - markScriptPadding = "4.0"; + barScriptPadding = #2.0 % dimension \pt + markScriptPadding = #4.0 \consists "Bar_number_engraver"; \consists "Mark_engraver"; diff --git a/ly/nederlands.ly b/ly/nederlands.ly index 78fc35ed04..b5a6d360bd 100644 --- a/ly/nederlands.ly +++ b/ly/nederlands.ly @@ -1,13 +1,5 @@ %{ common dutch names for notes. "es" means flat, "is" means sharp - - - - - Please note that, while these names are used to enter *notes*, they - actually are *melodic*s, i.e. they represent a pitch solely. Notes - have a rhythmic part too. This is the reason that we don't write 'note { .. }' - %} \notenames { @@ -56,6 +48,7 @@ % upper case: 1 octave lower. % + %% deprecated. Ceses = \musicalpitch { -2 0 -2 } Ces = \musicalpitch { -2 0 -1 } diff --git a/ly/params.ly b/ly/params.ly index 96b0057fa8..a3e0eba66c 100644 --- a/ly/params.ly +++ b/ly/params.ly @@ -225,7 +225,7 @@ mmrest_x_minimum = 1.4*\staffheight; % chop off this much when next to pp / ff sign. crescendo_shorten = 4.0 * \interline; crescendo_thickness = \stafflinethickness; -crescendo_height = 1.5 * \interline; +crescendo_height = 0.666 * \interline; % in internote. restcollision_minimum_dist = 3.0; diff --git a/ly/property.ly b/ly/property.ly index ea41ac9656..ddc99ba507 100644 --- a/ly/property.ly +++ b/ly/property.ly @@ -8,7 +8,7 @@ SEE THE REFERENCE MANUAL FOR EXPLANATIONS. %} -\version "1.2.0"; +\version "1.2.16"; %hmm, (these) abbrevs suck, imo % i guess they're meant as some form of doco @@ -17,52 +17,28 @@ stemup = \property Voice.verticalDirection = \up stemboth= \property Voice.verticalDirection = \center stemdown = \property Voice.verticalDirection = \down -slurup = \notes { - s1*0 - \property Voice.slurVerticalDirection = \up - } -slurboth= \notes { - s1*0 - \property Voice.slurVerticalDirection = \center -} -slurdown = \notes { - s1*0 - \property Voice.slurVerticalDirection = \down -} - -shifton = \property Voice.horizontalNoteShift = 1 -shiftoff = \property Voice.horizontalNoteShift = 0 +slurup = \property Voice.slurVerticalDirection = \up +slurboth = \property Voice.slurVerticalDirection = \center +slurdown = \property Voice.slurVerticalDirection = \down +shifton = \property Voice.horizontalNoteShift = #1 +shiftoff = \property Voice.horizontalNoteShift = #0 onevoice = { \stemboth \shiftoff } -%{ THESE ARE DEPRECATED %} -voiceone = - \context Voice = one { +voiceone = \stemup +voicetwo = \stemdown +voicethree = { \stemup + \shifton } -voicetwo = - \context Voice = two { - \stemdown -} - -voicethree = - \context Voice = three { - \stemup - -} - -voicefour = - \context Voice = four { +voicefour = { \stemdown \shifton } -%{ END OF DEPRECATED %} - - % ugh, cluttering global namespace... % ugh2. @@ -97,26 +73,26 @@ slurnormal = \property Voice.slurDash = "" -slurdotted = +slurdotted = \property Voice.slurDash = 1 -tupletoff = { +tupletoff = \property Voice.tupletVisibility = 0 -} -tupleton = { + +tupleton = \property Voice.tupletVisibility = 3 -} -tiny = { - \property Voice.fontSize= "-2" -} -small = { - \property Voice.fontSize= "-1" -} +tiny = + \property Voice.fontSize= -2 + + +small = + \property Voice.fontSize= -1 + normalsize = { - \property Voice.fontSize= "0" + \property Voice.fontSize= 0 } normalkey = { @@ -130,13 +106,13 @@ specialkey = { % End the incipit and print a ``normal line start''. endincipit = \notes{ \partial 16; s16 % Hack to handle e.g. \bar ".|"; \endincipit - \property Staff.clefStyle = "fullSizeChanges" + \property Staff.clefStyle = #"fullSizeChanges" \nobreak \bar ""; } -autoBeamOff = \property Voice.noAutoBeaming = "1" -autoBeamOn = \property Voice.noAutoBeaming = "" +autoBeamOff = \property Voice.noAutoBeaming = #t +autoBeamOn = \property Voice.noAutoBeaming = ##f -emptyText = \property Voice.textEmptyDimension = "1" -fatText = \property Voice.textEmptyDimension = "" +emptyText = \property Voice.textEmptyDimension = ##t +fatText = \property Voice.textEmptyDimension = ##f diff --git a/ly/script.ly b/ly/script.ly index 38f89853d2..d6c35d9c55 100644 --- a/ly/script.ly +++ b/ly/script.ly @@ -1,5 +1,6 @@ -\scmfile "script.scm"; + +#(eval-string (ly-gulp-file "script.scm")) "dash-hat" = "marcato" "dash-plus" = "stopped" @@ -44,4 +45,4 @@ prallmordent = \script "prallmordent" upprall = \script "upprall" downprall = \script "downprall" segno = \script "segno" -coda = \script "coda" \ No newline at end of file +coda = \script "coda" diff --git a/make/lilypond.spec.in b/make/lilypond.spec.in index 74c0e642e9..91c6e7ca02 100644 --- a/make/lilypond.spec.in +++ b/make/lilypond.spec.in @@ -22,10 +22,7 @@ Group: Applications/Publishing %description documentation @BLURB@ -The documentation package is rather big, due to the many pictures and -different documentation formats. It is really a rip-off from the -LilyPond website. If you have direct internet access, you may always -read the documentation documentation there: http://www.lilypond.org. +The documentation of LilyPond, both in HTML and PostScript. %prep %setup diff --git a/make/mutopia-targets.make b/make/mutopia-targets.make index 7bc061169d..35b8afd3be 100644 --- a/make/mutopia-targets.make +++ b/make/mutopia-targets.make @@ -2,12 +2,14 @@ all: $(OUT_FILES) - local-WWW: $(ly_examples) $(fly_examples) $(ps_examples) $(png_examples) (cd $(outdir); $(PYTHON) ../$(buildscripts)/mutopia-index.py --prefix=../ --suffix=/$(outdir) $(html_subdirs) $(all_examples)) echo $^ > $(depth)/wwwlist # $(footify) $(outdir)/index.html +local-web: + $(MAKE) CONFIGSUFFIX=www local-WWW + convert-mudela: local-convert-mudela $(LOOP) diff --git a/make/out/lilypond.lsm b/make/out/lilypond.lsm index 2997e73783..cbb9b6fba6 100644 --- a/make/out/lilypond.lsm +++ b/make/out/lilypond.lsm @@ -1,15 +1,15 @@ Begin3 Title: LilyPond -Version: 1.2.15 -Entered-date: 18OCT99 +Version: 1.3.0 +Entered-date: 26OCT99 Description: Keywords: music notation typesetting midi fonts engraving Author: hanwen@cs.uu.nl (Han-Wen Nienhuys) janneke@gnu.org (Jan Nieuwenhuizen) Maintained-by: hanwen@stack.nl (Han-Wen Nienhuys) Primary-site: sunsite.unc.edu /pub/Linux/apps/sound/convert - 1000k lilypond-1.2.15.tar.gz + 1000k lilypond-1.3.0.tar.gz Original-site: ftp.cs.uu.nl /pub/GNU/LilyPond/development/ - 1000k lilypond-1.2.15.tar.gz + 1000k lilypond-1.3.0.tar.gz Copying-policy: GPL End diff --git a/make/out/lilypond.spec b/make/out/lilypond.spec index 7105c3e1f6..3e62d1f6d1 100644 --- a/make/out/lilypond.spec +++ b/make/out/lilypond.spec @@ -1,9 +1,9 @@ Name: lilypond -Version: 1.2.15 +Version: 1.3.0 Release: 1 Copyright: GPL Group: Applications/Publishing -Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.2.15.tar.gz +Source0: ftp.cs.uu.nl:/pub/GNU/LilyPond/development/lilypond-1.3.0.tar.gz Summary: A program for printing sheet music. URL: http://www.cs.uu.nl/~hanwen/lilypond Packager: Han-Wen Nienhuys @@ -22,10 +22,7 @@ Group: Applications/Publishing %description documentation -The documentation package is rather big, due to the many pictures and -different documentation formats. It is really a rip-off from the -LilyPond website. If you have direct internet access, you may always -read the documentation documentation there: http://www.lilypond.org. +The documentation of LilyPond, both in HTML and PostScript. %prep %setup diff --git a/mutopia/J.S.Bach/Solo-Cello-Suites/allemande-cello.ly b/mutopia/J.S.Bach/Solo-Cello-Suites/allemande-cello.ly index da8e76a773..473a743eca 100644 --- a/mutopia/J.S.Bach/Solo-Cello-Suites/allemande-cello.ly +++ b/mutopia/J.S.Bach/Solo-Cello-Suites/allemande-cello.ly @@ -1,6 +1,5 @@ - \version "1.2.0"; \include "allemande-urtext.ly"; diff --git a/po/GNUmakefile b/po/GNUmakefile index c6540da3b1..fb421f7890 100644 --- a/po/GNUmakefile +++ b/po/GNUmakefile @@ -15,7 +15,6 @@ EXTRA_DIST_FILES = TODO $(PO_FILES) $(POT_FILES) STEPMAKE_TEMPLATES=podir include $(depth)/make/stepmake.make -include $(stepdir)/po-rules.make default: $(MO_FILES) diff --git a/scm/lily.scm b/scm/lily.scm index 8eafa4922a..de49911154 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -8,6 +8,9 @@ ;(debug-enable 'backtrace) ;;; library funtions + +; :use-module (ice-9 regex)) + (define (xnumbers->string l) (string-append diff --git a/scripts/mudela-book.py b/scripts/mudela-book.py index 1328087387..59bde3bbd7 100644 --- a/scripts/mudela-book.py +++ b/scripts/mudela-book.py @@ -682,7 +682,7 @@ def compile_all_files (chunks): system ('lilypond %s %s' % (lilyopts, texfiles)) for e in eps: - cmd = r"""tex %s; dvips -E -o %s %s""" % \ + cmd = r"""tex '\nonstopmode \input %s'; dvips -E -o %s %s""" % \ (e, e + '.eps', e) system (cmd) diff --git a/stepmake/bin/package-diff.py b/stepmake/bin/package-diff.py index 3fc89f375f..927cb0999e 100644 --- a/stepmake/bin/package-diff.py +++ b/stepmake/bin/package-diff.py @@ -52,9 +52,23 @@ def help (): ' -T, --dir-to=TO diff to directory TO\n' ) +def cleanup (): + global from_diff, to_diff, prev_cwd + os.chdir ('/tmp/package-diff') + sys.stderr.write ('Cleaning ... ') + os.system ('rm -fr %s %s' % (from_diff, to_diff)) + sys.stderr.write ('\n') + os.chdir (prev_cwd) + def untar (fn): # os.system ('pwd'); - sys.stderr.write ('untarring ' + fn + '\n') + try: + open (fn) + except: + sys.stderr.write ("Can't find tarball: %s\n" % fn) + cleanup () + sys.exit (1) + sys.stderr.write ("Untarring: %s\n" % fn) os.system ('gzip --quiet -dc ' + fn + '| tar xf - ') sys.stderr.flush () @@ -62,8 +76,13 @@ def remove_automatic (dirnames): files = [] for d in dirnames: - for p in pats: - files = files + find.find (p, d) + try: + for p in pats: + files = files + find.find (p, d) + except: + sys.stderr.write ("Can't find dir: %s\n" % d) + cleanup () + sys.exit (1) dirs = map (lambda d: find.find ('out', d), dirnames) dirs = reduce (lambda x,y: x + y, dirs) @@ -271,10 +290,5 @@ else: os.chdir (to_diff) makediff (from_diff, to_diff, patch_name) -os.chdir ('/tmp/package-diff') -sys.stderr.write ('cleaning ... ') -os.system ('rm -fr %s %s' % (from_diff, to_diff)) -sys.stderr.write ('\n') -os.chdir (prev_cwd) - +cleanup () diff --git a/stepmake/bin/release.py b/stepmake/bin/release.py index 9cad793748..cc6d6ec5ed 100755 --- a/stepmake/bin/release.py +++ b/stepmake/bin/release.py @@ -60,6 +60,7 @@ except: pass os.link(orig, os.path.join (package.release_dir, tarball)) +# urg: howto check exit code? os.system(sys.executable + ' ' + package.topdir + '/stepmake/bin/package-diff.py --package=' + topdir) diffname = pn + '.diff.gz' @@ -67,6 +68,10 @@ rel_pn = package.patch_dir + diffname diffname = os.path.join (outdir, diffname) -os.rename(diffname, rel_pn) +try: + os.rename(diffname, rel_pn) +except: + sys.stderr.write ("Can't find diff: %s\n" % diffname) + sys.exit (1) os.link(rel_pn, diffname) diff --git a/stepmake/stepmake/documentation-targets.make b/stepmake/stepmake/documentation-targets.make index fc2d648a1f..7223b973c4 100644 --- a/stepmake/stepmake/documentation-targets.make +++ b/stepmake/stepmake/documentation-targets.make @@ -1,14 +1,12 @@ default: -do-doc: $(OUTTXT_FILES) - local-WWW: $(OUTHTML_FILES) echo $^ > $(depth)/wwwlist -doc: do-doc - +local-web: + $(MAKE) CONFIGSUFFIX=www local-WWW footify: $(footify) $(sort $(wildcard $(outdir)/*.html out/*.html out-www/*.html)) diff --git a/stepmake/stepmake/documentation-vars.make b/stepmake/stepmake/documentation-vars.make index 82861d8227..6fb5343eae 100644 --- a/stepmake/stepmake/documentation-vars.make +++ b/stepmake/stepmake/documentation-vars.make @@ -7,20 +7,3 @@ footify=$(PYTHON) $(step-bindir)/add-html-footer.py --name $(PACKAGE_NAME) --ver footify-all-command=$(footify) `$(FIND) . -name '*.html' -print` -# -YO_FILES := $(wildcard *.yo) -POD_FILES := $(wildcard *.pod) -TEXINFO_FILES := $(wildcard *.texinfo) -OUTYO_FILES = $(addprefix $(outdir)/,$(YO_FILES)) -OUTPOD_FILES = $(addprefix $(outdir)/,$(POD_FILES)) -OUTTEXINFO_FILES = $(addprefix $(outdir)/,$(TEXINFO_FILES)) - -# -ALL_DOC_FILES = $(POD_FILES) $(TEXINFO_FILES) $(YO_FILES) -OUTTXT_FILES = $(OUTYO_FILES:.yo=.txt) $(OUTIN_FILES:.yo=.txt) -OUTHTML_FILES = $(OUTYO_FILES:.yo=.html) $(OUTIN_FILES:.yo=.html) - -OUTREADME_TXT_FILES=$(addprefix $(outdir)/,$(addsuffix .txt, $(README_TOP_FILES))) -OUTREADME_HTML_FILES=$(addprefix $(outdir)/,$(addsuffix .html, $(README_TOP_FILES))) - -ALL_SOURCES += $(ALL_DOC_FILES) diff --git a/stepmake/stepmake/generic-targets.make b/stepmake/stepmake/generic-targets.make index 327e1e9207..d2b2f9914d 100644 --- a/stepmake/stepmake/generic-targets.make +++ b/stepmake/stepmake/generic-targets.make @@ -82,10 +82,10 @@ Note that all commands recurse into SUBSDIRS\n\ local-help: -doc: -#UGH - true # $(MAKE) -C $(depth)/Documentation all +doc: local-doc + $(LOOP) +local-doc: # Ugh. C++ specific. doc++: diff --git a/stepmake/stepmake/metapost-rules.make b/stepmake/stepmake/metapost-rules.make index 2ecf0bc232..7f820ab4e5 100644 --- a/stepmake/stepmake/metapost-rules.make +++ b/stepmake/stepmake/metapost-rules.make @@ -9,5 +9,5 @@ mfplain.mem: $(MFPLAIN_MP) $(outdir)/%.pfa: $(outdir)/%.0 $(PYTHON) $(depth)/buildscripts/ps-to-pfa.py --output $(basename $<).pfa $< rm -f $(basename $(@F)).[0-9]* - rm -f $(basename $<).log $(basename $<).tfm + rm -f $(basename $<).log diff --git a/stepmake/stepmake/pod-vars.make b/stepmake/stepmake/pod-vars.make new file mode 100644 index 0000000000..541da42c94 --- /dev/null +++ b/stepmake/stepmake/pod-vars.make @@ -0,0 +1,3 @@ + +POD_FILES := $(wildcard *.pod) +OUTPOD_FILES = $(addprefix $(outdir)/,$(POD_FILES)) diff --git a/stepmake/stepmake/texinfo-rules.make b/stepmake/stepmake/texinfo-rules.make index 8879351964..7b013a29e7 100644 --- a/stepmake/stepmake/texinfo-rules.make +++ b/stepmake/stepmake/texinfo-rules.make @@ -19,3 +19,4 @@ $(outdir)/%.txt: $(outdir)/%.texi $(outdir)/%.texi: %.texi cp $< $@ + diff --git a/stepmake/stepmake/texinfo-targets.make b/stepmake/stepmake/texinfo-targets.make index 313f8a23e7..ca47789ef0 100644 --- a/stepmake/stepmake/texinfo-targets.make +++ b/stepmake/stepmake/texinfo-targets.make @@ -1,3 +1,5 @@ # empty local-WWW: $(addprefix $(outdir)/,$(TEXI_FILES:.texi=.html)) + +local-doc: $(OUTTXT_FILES) diff --git a/stepmake/stepmake/texinfo-vars.make b/stepmake/stepmake/texinfo-vars.make index 3a7e7ae04c..2447edd7a6 100644 --- a/stepmake/stepmake/texinfo-vars.make +++ b/stepmake/stepmake/texinfo-vars.make @@ -1,4 +1,6 @@ TEXI_FILES = $(wildcard *.texi) -EXTRA_DIST_FILES += $(TEXI_FILES) +ALL_SOURCES += $(TEXI_FILES) + +OUTTXT_FILES += $(addprefix $(outdir)/,$(TEXI_FILES:.texi=.txt)) diff --git a/stepmake/stepmake/yodl-vars.make b/stepmake/stepmake/yodl-vars.make new file mode 100644 index 0000000000..b97bb19492 --- /dev/null +++ b/stepmake/stepmake/yodl-vars.make @@ -0,0 +1,6 @@ + +YO_FILES := $(wildcard *.yo) +OUTYO_FILES = $(addprefix $(outdir)/,$(YO_FILES)) + +OUTTXT_FILES = $(OUTYO_FILES:.yo=.txt) $(OUTIN_FILES:.yo=.txt) +OUTHTML_FILES = $(OUTYO_FILES:.yo=.html) $(OUTIN_FILES:.yo=.html) diff --git a/stepmake/stepmake/yolily-toplevel-targets.make b/stepmake/stepmake/yolily-toplevel-targets.make index 72612a2cfb..4de1e45739 100644 --- a/stepmake/stepmake/yolily-toplevel-targets.make +++ b/stepmake/stepmake/yolily-toplevel-targets.make @@ -18,7 +18,7 @@ htmldoc: rm -f `find . -name \*.html~ -print` $(footify-all-command) find `find Documentation -type d -name 'out-www'` -not -name '*dvi' -not -name '*ly' -not -name '*tex' -not -name '*.ps' -not -name 'out-www' > wwwlist - tar cfz $(outdir)/htmldoc.tar.gz `cat wwwlist` `ls *.png out-www/$(distname).diff.gz $(ERRORLOG)` index.html + tar cfz $(outdir)/htmldoc.tar.gz `cat wwwlist` `ls *.png $(ERRORLOG)` index.html localclean: rm -f wwwlist diff --git a/tex/titledefs.tex b/tex/titledefs.tex index 876dff5213..5b02ba912f 100644 --- a/tex/titledefs.tex +++ b/tex/titledefs.tex @@ -14,7 +14,7 @@ \def\theinstrument{} \def\theopus{} \def\thepiece{} -\def\themetre{} +\def\themeter{} \def\thepoet{} % % duh. LaTeX has a \title too. @@ -25,7 +25,7 @@ \newcommand*{\instrument}[1]{\def\theinstrument{#1}} \newcommand*{\opus}[1]{\def\theopus{#1}} \newcommand*{\piece}[1]{\def\thepiece{#1}} -\newcommand*{\metre}[1]{\def\themetre{#1}} +\newcommand*{\meter}[1]{\def\themeter{#1}} \newcommand*{\poet}[1]{\def\thepoet{#1}} % \newcommand*{\mudelatitle}[1]{\def\thetitle{#1}} @@ -35,8 +35,8 @@ \newcommand*{\mudelainstrument}[1]{\def\theinstrument{#1}} \newcommand*{\mudelaopus}[1]{\def\theopus{#1}} \newcommand*{\mudelapiece}[1]{\def\thepiece{#1}} -\newcommand*{\mudelametre}[1]{\def\themetre{#1}} -\newcommand*{\mudelameter}[1]{\def\themetre{#1}} +\newcommand*{\mudelametre}[1]{\def\themeter{#1}} +\newcommand*{\mudelameter}[1]{\def\themeter{#1}} \newcommand*{\mudelapoet}[1]{\def\thepoet{#1}} % % @@ -53,7 +53,7 @@ \edef\saveparskip{\parskip}\parskip-5mm \begin{minipage}[t]{0.45\textwidth} \ifx\mudelanull\thepoet\else{\thepoet}\\ \fi - \ifx\mudelanull\themetre\else{\themetre}\\ \fi + \ifx\mudelanull\themeter\else{\themeter}\\ \fi \end{minipage}\hspace*{\fill} \begin{minipage}[t]{0.45\textwidth} \begin{flushright}