@include contributor/programming-work.itexi
@include contributor/release-work.itexi
@include contributor/build-notes.itexi
-@include contributor/feta-font.itexi
+@include contributor/emmentaler-font.itexi
@include contributor/administration.itexi
@node LilyPond grammar
--- /dev/null
+@c -*- coding: utf-8; mode: texinfo; -*-
+@node Modifying the Emmentaler font
+@chapter Modifying the Emmentaler font
+
+@menu
+* Overview of the Emmentaler font::
+* Font creation tools::
+* Adding a new font section::
+* Adding a new glyph::
+* Building the changed font::
+* METAFONT formatting rules::
+@end menu
+
+@node Overview of the Emmentaler font
+@section Overview of the Emmentaler font
+
+Emmentaler was created specifically for use in LilyPond. The font
+consists of two @emph{sub-sets} of glyphs. @qq{Feta}, used for clasical
+notation and @qq{Parmesan}, used for Ancient notation. The sources of
+which are all found in mf/*.mf.
+
+The font is merged from a number of subfonts. Each subfont can contain
+at most 224 glyphs. This is because each subfont is limited to a
+one-byte address space (256 glyphs maximum) and we avoid the first 32
+points in that address space, since they are non-printing control
+characters in ASCII.
+
+In LilyPond, glyphs are accessed by a @q{glyph name}, rather than by
+code point. Therefore, the name of a glyph is significant.
+
+Information about correctly creating glyphs is found in @file{mf/README}.
+Please make sure you read and understand this file.
+
+TODO -- we should get mf/README automatically generated from texinfo
+source and include it here.
+
+
+@node Font creation tools
+@section Font creation tools
+
+The sources for Emmentaler are written in metafont. The definitive
+reference for metafont is "The METAFONT book" -- the source of which is
+available at CTAN.
+
+mf2pt1 is used to create type 1 fonts from the metafont sources.
+
+FontForge is used to postprocess the output of mf2pt1 and clean up
+details of the font. It can also be used by a developer to
+display the resulting glyph shapes.
+
+
+@node Adding a new font section
+@section Adding a new font section
+
+The font is divided into sections, each of which contains less
+than 224 glyphs. If more than 224 glyphs are included in a section,
+an error will be generated.
+
+Each of the sections is contained in a separate @code{.mf} file. The
+files are named according to the type of glyphs in that section.
+
+When adding a new section, it will be necessary to add the following:
+
+@itemize
+@item
+The code for the glyphs, in a file @code{<section-name>.mf}
+@item
+Driver files used to create the font in different sizes
+@item
+An entry in the generic file used to create the font, or a new
+generic file
+@item
+If necessary, new entries in the GNUmakefile
+@item
+An entry in @file{scripts/build/gen-emmentaler-scripts.py}
+@end itemize
+
+See the examples in @code{mf/} for more information.
+
+
+@node Adding a new glyph
+@section Adding a new glyph
+
+Adding a new glyph is done by modifying the .mf file to which the
+glyph will be added.
+
+Necessary functions to draw the glyph can be added anywhere in the file,
+but it is standard to put them immediately before the glyph definition.
+
+The glyph definition begins with:
+
+@example
+fet_beginchar ("glyph description", "glyphname");
+@end example
+
+@noindent
+with @code{glyph description} replaced with a short description of the
+glyph, and @code{glyphname} replaced with the glyphname, which is chosen
+to comply with the naming rules in @file{mf/README}.
+
+The metafont code used to draw the glyph follows the @code{fet_beginchar}
+entry. The glyph is finished with:
+
+@example
+fet_endchar;
+@end example
+
+
+@node Building the changed font
+@section Building the changed font
+
+In order to rebuild the font after making the changes, the existing
+font files must be deleted. The simplest and quickest way to do this
+is to do:
+
+@example
+rm mf/out/*
+make
+@end example
+
+
+@node METAFONT formatting rules
+@section METAFONT formatting rules
+
+There are special formatting rules for METAFONT files.
+
+Tabs are used for the indentation of commands.
+
+When a path contains more than two points, put each point on a
+separate line, with the operator at the beginning of the line.
+The operators are indented to the same depth as the initial point
+on the path using spaces. The indentation mechanism is illustrated
+below, with @samp{------->} indicating a tab character and any other
+indentation created using spaces.
+
+@example
+def draw_something (test) =
+------->if test:
+------->------->fill z1
+------->-------> -- z2
+------->-------> -- z3
+------->-------> .. cycle;
+------->fi;
+enddef;
+@end example
+++ /dev/null
-@c -*- coding: utf-8; mode: texinfo; -*-
-@node Modifying the Emmentaler font
-@chapter Modifying the Emmentaler font
-
-@menu
-* Overview of the Emmentaler font::
-* Font creation tools::
-* Adding a new font section::
-* Adding a new glyph::
-* Building the changed font::
-* METAFONT formatting rules::
-@end menu
-
-@node Overview of the Emmentaler font
-@section Overview of the Emmentaler font
-
-Emmentaler was created specifically for use in LilyPond. The font
-consists of two @emph{sub-sets} of glyphs. @qq{Feta}, used for clasical
-notation and @qq{Parmesan}, used for Ancient notation. The sources of
-which are all found in mf/*.mf.
-
-The font is merged from a number of subfonts. Each subfont can contain
-at most 224 glyphs. This is because each subfont is limited to a
-one-byte address space (256 glyphs maximum) and we avoid the first 32
-points in that address space, since they are non-printing control
-characters in ASCII.
-
-In LilyPond, glyphs are accessed by a @q{glyph name}, rather than by
-code point. Therefore, the name of a glyph is significant.
-
-Information about correctly creating glyphs is found in @file{mf/README}.
-Please make sure you read and understand this file.
-
-TODO -- we should get mf/README automatically generated from texinfo
-source and include it here.
-
-
-@node Font creation tools
-@section Font creation tools
-
-The sources for Emmentaler are written in metafont. The definitive
-reference for metafont is "The METAFONT book" -- the source of which is
-available at CTAN.
-
-mf2pt1 is used to create type 1 fonts from the metafont sources.
-
-FontForge is used to postprocess the output of mf2pt1 and clean up
-details of the font. It can also be used by a developer to
-display the resulting glyph shapes.
-
-
-@node Adding a new font section
-@section Adding a new font section
-
-The font is divided into sections, each of which contains less
-than 224 glyphs. If more than 224 glyphs are included in a section,
-an error will be generated.
-
-Each of the sections is contained in a separate @code{.mf} file. The
-files are named according to the type of glyphs in that section.
-
-When adding a new section, it will be necessary to add the following:
-
-@itemize
-@item
-The code for the glyphs, in a file @code{<section-name>.mf}
-@item
-Driver files used to create the font in different sizes
-@item
-An entry in the generic file used to create the font, or a new
-generic file
-@item
-If necessary, new entries in the GNUmakefile
-@item
-An entry in @file{scripts/build/gen-emmentaler-scripts.py}
-@end itemize
-
-See the examples in @code{mf/} for more information.
-
-
-@node Adding a new glyph
-@section Adding a new glyph
-
-Adding a new glyph is done by modifying the .mf file to which the
-glyph will be added.
-
-Necessary functions to draw the glyph can be added anywhere in the file,
-but it is standard to put them immediately before the glyph definition.
-
-The glyph definition begins with:
-
-@example
-fet_beginchar ("glyph description", "glyphname");
-@end example
-
-@noindent
-with @code{glyph description} replaced with a short description of the
-glyph, and @code{glyphname} replaced with the glyphname, which is chosen
-to comply with the naming rules in @file{mf/README}.
-
-The metafont code used to draw the glyph follows the @code{fet_beginchar}
-entry. The glyph is finished with:
-
-@example
-fet_endchar;
-@end example
-
-
-@node Building the changed font
-@section Building the changed font
-
-In order to rebuild the font after making the changes, the existing
-font files must be deleted. The simplest and quickest way to do this
-is to do:
-
-@example
-rm mf/out/*
-make
-@end example
-
-
-@node METAFONT formatting rules
-@section METAFONT formatting rules
-
-There are special formatting rules for METAFONT files.
-
-Tabs are used for the indentation of commands.
-
-When a path contains more than two points, put each point on a
-separate line, with the operator at the beginning of the line.
-The operators are indented to the same depth as the initial point
-on the path using spaces. The indentation mechanism is illustrated
-below, with @samp{------->} indicating a tab character and any other
-indentation created using spaces.
-
-@example
-def draw_something (test) =
-------->if test:
-------->------->fill z1
-------->-------> -- z2
-------->-------> -- z3
-------->-------> .. cycle;
-------->fi;
-enddef;
-@end example
margin: 0 0 0.5em 0;
}
+/* Used for google summer of code project ideas, for example. */
+.bigger-subsubheadings h4 {
+ font-size: 1.17em;
+ margin: 1.5em 0 0.5em 0;
+}
+
.column-center-top ul,
.column-center-middle-color2 ul,
.column-center-middle-color3 ul,
@divEnd
-@divClass{column-center-middle-color2}
+@divClass{column-center-middle-color2 bigger-subsubheadings}
@subheading Project Ideas List
Below is a list of GSoC project ideas (last update: January 2017), but
A full list of all the current open issues can be found
@uref{http://sourceforge.net/p/testlilyissues/issues/, here}.
-@divEnd
-@divClass{column-center-middle-color3}
-@subheading Improve internal chord structure
+@subsubheading Improve internal chord structure
The internal representation of LilyPond chords is not powerful enough
to capture the nomenclature of jazz chords. Currently the chord has
representation is developed, the output formatting of chord names can
be improved.
-@strong{Difficulty:} Easy/medium
-@strong{Requirements:} Scheme (Guile), but the level necessary can be
+@emph{Difficulty:} Easy/medium
+
+@emph{Requirements:} Scheme (Guile), but the level necessary can be
easily learned
-@strong{Recommended:} Chord theory and naming
-@strong{Mentor:} Carl Sorensen
-@divEnd
+@emph{Recommended:} Chord theory and naming
+
+@emph{Mentor:} Carl Sorensen
-@divClass{column-center-middle-color3}
-@subheading Adopt the SMuFL music font encoding standard
+
+@subsubheading Adopt the SMuFL music font encoding standard
For several years now a new standard for music fonts has been around:
@uref{http://www.smufl.org/, SMuFL}, which is also discussed as becoming part of
could be modified to use notation fonts installed as system fonts instead of
inside the LilyPond installation.
-@strong{Difficulty:} Easy/medium
-@strong{Requirements:} C++ and willingness to get familiar with LilyPond
+@emph{Difficulty}: Easy/medium
+
+@emph{Requirements}: C++ and willingness to get familiar with LilyPond
internals.
-@strong{Recommended:} Interest and experience in working with font files.
+
+@emph{Recommended}: Interest and experience in working with font files.
A little bit of METAFONT.
-@strong{Mentors:} Werner Lemberg, Abraham Lee
-@divEnd
+@emph{Mentors}: Werner Lemberg, Abraham Lee
-@divClass{column-center-middle-color3}
-@subheading Adding variants of font glyphs
+
+@subsubheading Adding variants of font glyphs
@divClass{keep-bullets}
@itemize
@end itemize
@divEnd
-@strong{Difficulty:} easy
-@strong{Requirements:} MetaFont, C++, good eye for details
-@strong{Recommended knowledge:} basic LilyPond knowledge
-@strong{Mentor:} Werner Lemberg
+@emph{Difficulty:} easy
-@divEnd
+@emph{Requirements:} MetaFont, C++, good eye for details
+
+@emph{Recommended knowledge:} basic LilyPond knowledge
+
+@emph{Mentor:} Werner Lemberg
-@divClass{column-center-middle-color3}
-@subheading Contemporary Notation
+
+@subsubheading Contemporary Notation
LilyPond is very good at creating non-standard notation. Having to
@emph{code} every graphical element instead of simply @emph{drawing}
of a given composer, extended playing techniques for a specific
instrument or a certain category of effects.
-@strong{Difficulty:} medium
-@strong{Requirements:} Scheme (interaction with LilyPond internals),
+@emph{Difficulty:} medium
+
+@emph{Requirements:} Scheme (interaction with LilyPond internals),
contemporary notation techniques
-@strong{Recommended:} sense of building hierarchical frameworks
-@strong{Mentors:} @strong{NN,} Urs Liska
-@divEnd
+@emph{Recommended:} sense of building hierarchical frameworks
-@divClass{column-center-middle-color3}
-@subheading Rewrite LibreOffice LilyPond Extension with Python
+@emph{Mentors:} @emph{NN,} Urs Liska
+
+
+@subsubheading Rewrite LibreOffice LilyPond Extension with Python
The @uref{http://ooolilypond.sourceforge.net/, OOoLilyPond} extension
made it possible to conveniently include LilyPond score snippets in
for example syntax highlighting, entry helpers, score wizards or musical
transformations.
-@strong{Difficulty:} easy/medium
-@strong{Requirements:} Python, PyQt, LilyPond basics, LibreOffice
+@emph{Difficulty:} easy/medium
+
+@emph{Requirements:} Python, PyQt, LilyPond basics, LibreOffice
extension basics
-@strong{Recommended knowledge:} Familiarity with Frescobaldi code based
+
+@emph{Recommended knowledge:} Familiarity with Frescobaldi code based
or willingness to learn during bonding period
-@strong{Mentor(s):} Joram Berger, Urs Liska, (Thorsten Behrens/LibreOffice)
-@divEnd
+@emph{Mentor(s):} Joram Berger, Urs Liska, (Thorsten Behrens/LibreOffice)
-@divClass{column-center-middle-color3}
-@subheading Automated testing and documentation for openLilyLib
+
+@subsubheading Automated testing and documentation for openLilyLib
@uref{https://github.com/openlilylib, openLilyLib} is an extension
framework for LilyPond code providing a “snippets” repository and a
openLilyLib's @uref{https://openlilylib.org, website}. Development of
such a SPA @emph{can} be part of the GSoC project, but is optional.
-@strong{Difficulty:} medium
-@strong{Requirements:} Python or Scheme, static website generator(s) or
+@emph{Difficulty:} medium
+
+@emph{Requirements:} Python or Scheme, static website generator(s) or
(Node.js based) dynamic web application technology. Continuous
Integration (can be learned during the bonding period)
-@strong{Mentors:} Urs Liska, Matteo Ceccarello
-@divEnd
+@emph{Mentors:} Urs Liska, Matteo Ceccarello
-@divClass{column-center-middle-color3}
-@subheading MusicXML
+
+@subsubheading MusicXML
Improving MusicXML import and export functions:
another XML library than the one provided by guile-2 in order to have
this feature available in current LilyPond (which is based on guile-1.8).
-@strong{Difficulty:} medium
-@strong{Requirements:} MusicXML, Python, Scheme, basic LilyPond knowledge
-@strong{Recommended:} Familiarity with other scorewriters (for cross-testing)
-@strong{Mentor:} Jan-Peter Voigt
+@emph{Difficulty:} medium
+
+@emph{Requirements:} MusicXML, Python, Scheme, basic LilyPond knowledge
+
+@emph{Recommended:} Familiarity with other scorewriters (for cross-testing)
+
+@emph{Mentor:} Jan-Peter Voigt
@divEnd
+
@divClass{column-center-middle-color2}
@subheading Information for Applicants/Participants
@divEnd
-@divClass{column-center-middle-color2}
-@subheading Unused Google Summer of Code project suggestions
+@divClass{column-center-middle-color2 bigger-subsubheadings}
+@subheading Inactive Google Summer of Code project suggestions
The following list describes GSoC projects that had been proposed
in recent years and which are still considered valuable but for
which we currently don't have mentors available.
-@divEnd
-@divClass{column-center-middle-color3}
-@subheading Improve slurs and ties
+@subsubheading Improve slurs and ties
The engraving quality of slurs and ties is often unsatisfactory. Ties
@q{broken} by clef or staff changes are not handled well. The project
could include collecting and sorting examples of bad output, deciding on
the intended output and writing code to improve them.
-@strong{Difficulty:} hard
-@strong{Requirements:} C++, experience with writing heuristics
-@strong{Recommended knowledge:} LilyPond knowledge, aesthetic sense
+@emph{Difficulty:} hard
+@emph{Requirements:} C++, experience with writing heuristics
-@divEnd
+@emph{Recommended knowledge:} LilyPond knowledge, aesthetic sense
-@divClass{column-center-middle-color3}
-@subheading Grace notes
+
+@subsubheading Grace notes
Fix problems with synchronization of grace notes. Grace notes can
interfere with LilyPond's timing and cause odd effects, especially when
@uref{https://sourceforge.net/p/testlilyissues/issues/34/,bugs} in
LilyPond.
-@strong{Difficulty:} medium
-@strong{Requirements:} C++, MIDI
-@strong{Recommended:} familiarity with LilyPond internals
+@emph{Difficulty:} medium
-@divEnd
+@emph{Requirements:} C++, MIDI
+
+@emph{Recommended:} familiarity with LilyPond internals
-@divClass{column-center-middle-color3}
-@subheading Improve default beam positioning
+
+@subsubheading Improve default beam positioning
For regular, cross-staff, broken and kneed beams. Beaming should depend
on context and neighbor notes (see section 2.2 of
@uref{http://imslp.org/wiki/Repository_of_Music-Notation_Mistakes_%28Coulon%2C_Jean-Pierre%29,
this book}). If possible also reduce beaming-computation time.
-@strong{Difficulty:} medium
-@strong{Requirements:} C++, experience with writing heuristics
-@strong{Recommended knowledge:} aesthetic sense
+@emph{Difficulty:} medium
-@divEnd
+@emph{Requirements:} C++, experience with writing heuristics
-@divClass{column-center-middle-color3}
-@subheading Help improve compilation behavior
+@emph{Recommended knowledge:} aesthetic sense
+
+
+@subsubheading Help improve compilation behavior
Automatic code analysis tools, like valgrind memory leak detection or
callgrind code profilers, provide valuable information about possible
flaws in our C++ code. Cleaning up warnings would allow us to automate
the rejection of any patch which introduced extra warnings.
-@strong{Difficulty:} medium
-@strong{Requirements:} C++
+@emph{Difficulty:} medium
+
+@emph{Requirements:} C++
@divEnd
string
get_working_directory ()
{
- char cwd[PATH_MAX];
- // getcwd returns NULL upon a failure, contents of cwd would be undefined!
- return string (getcwd (cwd, PATH_MAX));
+#ifdef PATH_MAX
+ vector<char> cwd (PATH_MAX);
+#else
+ vector<char> cwd (1024);
+#endif
+ while (getcwd (cwd.data (), cwd.size ()) == NULL)
+ {
+ if (errno != ERANGE)
+ {
+ // getcwd () fails.
+ return "";
+ }
+ cwd.resize (cwd.size () * 2);
+ }
+ return string (cwd.data ());
}
/* Join components to full file_name. */
#include "file-path.hh"
+#include "file-name.hh"
#include <limits.h>
#include <unistd.h>
{
char const *extensions[] = {"ly", "", 0};
string file = "init";
- char cwd[PATH_MAX];
- if (!getcwd (cwd, PATH_MAX))
+ if (get_working_directory().empty())
{
cerr << "Could not get current work directory\n";
exit (1);
engraver_demo =
#(make-engraver
((initialize translator)
- (format 1 "\n\n~16a: (initialize)\n" (t->m translator)))
+ (format (current-error-port) "\n\n~16a: (initialize)\n" (t->m translator)))
((start-translation-timestep translator)
- (format 1 "~16a: (start-translation-timestep)\n" (t->m translator)))
+ (format (current-error-port) "~16a: (start-translation-timestep)\n" (t->m translator)))
(listeners
((rest-event engraver event)
(let ((grob (ly:engraver-make-grob engraver 'TextScript event)))
(ly:grob-set-property! grob 'text "hi")
- (format 1 "~16a: detected this rest event: ~a\n~16a: created this grob: ~a\n"
+ (format (current-error-port) "~16a: detected this rest event: ~a\n~16a: created this grob: ~a\n"
(t->m engraver) event (t->m engraver) grob))))
(acknowledgers
((note-head-interface engraver grob source-engraver)
- (format 1 "~16a: saw ~a coming from ~a\n"
+ (format (current-error-port) "~16a: saw ~a coming from ~a\n"
(t->m engraver) grob source-engraver)))
(end-acknowledgers
((beam-interface engraver grob source-engraver)
- (format 1 "~16a: saw end of ~a coming from ~a\n"
+ (format (current-error-port) "~16a: saw end of ~a coming from ~a\n"
(t->m engraver) grob source-engraver)))
((process-music translator)
- (format 1 "~16a: (process-music)\n" (t->m translator)))
+ (format (current-error-port) "~16a: (process-music)\n" (t->m translator)))
((process-acknowledged translator)
- (format 1 "~16a: (process-acknowledged)\n" (t->m translator)))
+ (format (current-error-port) "~16a: (process-acknowledged)\n" (t->m translator)))
((stop-translation-timestep translator)
- (format 1 "~16a: (stop-translation-timestep)\n" (t->m translator)))
+ (format (current-error-port) "~16a: (stop-translation-timestep)\n" (t->m translator)))
((finalize translator)
- (format 1 "~16a: (finalize)\n" (t->m translator))))
+ (format (current-error-port) "~16a: (finalize)\n" (t->m translator))))
\layout {
\context {
{
mmrest_ = make_spanner ("MultiMeasureRest", rest_ev_->self_scm ());
text_.push_back (make_spanner ("MultiMeasureRestNumber",
- rest_ev_->self_scm ()));
+ mmrest_->self_scm ()));
if (text_events_.size ())
{
"rest "
"rest-collision "
"stem "
+ "glissando-skip "
);
}
| STRING {
if (!parser->lexer_->is_lyric_state ())
- parser->parser_error (@1, _ ("unrecognized string, not in text script or \\lyricmode"));
+ parser->parser_error (@1, _f ("not a note name: %s", ly_scm2string ($1)));
$$ = $1;
}
| LYRIC_ELEMENT
"head-direction "
"note-head "
"thickness "
+ "line-thickness "
);
MAKE_SCHEME_CALLBACK (Semi_tie, calc_control_points, 1)
(set! never-embed-font-list (list))
(if (ly:get-option 'font-export-dir)
(let ((dirname (format #f "~a" (ly:get-option 'font-export-dir))))
- (if (file-exists? dirname)
- (ly:debug
- (_ "Font export directory `~a' already exists.") dirname)
- (begin
- (ly:debug
- (_ "Making font export directory `~a'.") dirname)
- (mkdir dirname)))))
+ (ly:debug
+ (_ "Making font export directory `~a'.") dirname)
+ (catch
+ 'system-error
+ (lambda ()
+ ;; mkdir:
+ ;; When the directory already exists, it raises system-error.
+ (mkdir dirname))
+ (lambda stuff
+ ;; Catch the system-error
+ (if (= EEXIST (system-error-errno stuff))
+ ;; If the directory already exists, avoid error.
+ (ly:debug
+ (_ "Font export directory `~a' already exists.") dirname)
+ ;; If the cause is something else, re-throw the error.
+ (throw 'system-error (cdr stuff)))))))
(if load-fonts?
(for-each (lambda (f)
(format port "\n%%BeginFont: ~a\n" (car f))