From: Francisco Vila Date: Sun, 26 Mar 2017 08:56:04 +0000 (+0200) Subject: Merge branch 'master' into translation X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=8d0fb9fe466754fcbd516b5155325bcd04f851b4;hp=1d7689f7135892cb16448f43356b9cb758cb6685;p=lilypond.git Merge branch 'master' into translation --- diff --git a/Documentation/contributor.texi b/Documentation/contributor.texi index 77b562ee5a..ac485a3962 100644 --- a/Documentation/contributor.texi +++ b/Documentation/contributor.texi @@ -94,7 +94,7 @@ Appendices @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 diff --git a/Documentation/contributor/emmentaler-font.itexi b/Documentation/contributor/emmentaler-font.itexi new file mode 100644 index 0000000000..4c4c81b57f --- /dev/null +++ b/Documentation/contributor/emmentaler-font.itexi @@ -0,0 +1,145 @@ +@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{.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 diff --git a/Documentation/contributor/feta-font.itexi b/Documentation/contributor/feta-font.itexi deleted file mode 100644 index 4c4c81b57f..0000000000 --- a/Documentation/contributor/feta-font.itexi +++ /dev/null @@ -1,145 +0,0 @@ -@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{.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 diff --git a/Documentation/css/lilypond-website.css b/Documentation/css/lilypond-website.css index 936af77b75..fb90a9defc 100644 --- a/Documentation/css/lilypond-website.css +++ b/Documentation/css/lilypond-website.css @@ -708,6 +708,12 @@ div.float-center a.clickable { 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, diff --git a/Documentation/web/community.itexi b/Documentation/web/community.itexi index 7d27daf66e..2f4cf32720 100644 --- a/Documentation/web/community.itexi +++ b/Documentation/web/community.itexi @@ -907,7 +907,7 @@ encourage you to get in touch with our community ahead of that. @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 @@ -923,10 +923,8 @@ early as possible. 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 @@ -937,16 +935,17 @@ complex chords must be developed. As a bonus, once the internal 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 @@ -963,17 +962,18 @@ glyphs. As an optional part of this project LilyPond's font loading mechanism 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 @@ -990,15 +990,16 @@ it. @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} @@ -1014,16 +1015,17 @@ cover specific contemporary notation, such as for example the style 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 @@ -1039,17 +1041,18 @@ functionality from @uref{http://frescobaldi.org, Frescobaldi}, such as 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 @@ -1086,16 +1089,16 @@ a Single Page Application could retrieve content for display on 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: @@ -1118,13 +1121,17 @@ by David Garfinkle. It should be checked if it is possible to use 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 @@ -1406,32 +1413,29 @@ Developers' changelogs by version: @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 @@ -1440,36 +1444,37 @@ This is one of the longest-standing and one of the more embarrassing @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 diff --git a/flower/file-name.cc b/flower/file-name.cc index c65d8fc7ed..990e3d6d91 100644 --- a/flower/file-name.cc +++ b/flower/file-name.cc @@ -77,9 +77,21 @@ dir_name (const string &file_name) 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 cwd (PATH_MAX); +#else + vector 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. */ diff --git a/flower/test-file-path.cc b/flower/test-file-path.cc index a20364b98c..8a891afeea 100644 --- a/flower/test-file-path.cc +++ b/flower/test-file-path.cc @@ -1,4 +1,5 @@ #include "file-path.hh" +#include "file-name.hh" #include #include @@ -10,8 +11,7 @@ TEST (File_path, Find) { 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); diff --git a/input/regression/scheme-engraver.ly b/input/regression/scheme-engraver.ly index 0f31685f91..cd1b848c35 100644 --- a/input/regression/scheme-engraver.ly +++ b/input/regression/scheme-engraver.ly @@ -14,31 +14,31 @@ 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 { diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index d66779f6ff..ff1e155abc 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -120,7 +120,7 @@ Multi_measure_rest_engraver::initialize_grobs () { 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 ()) { diff --git a/lily/note-column.cc b/lily/note-column.cc index 1d79fee652..b3f7e4aab9 100644 --- a/lily/note-column.cc +++ b/lily/note-column.cc @@ -251,4 +251,5 @@ ADD_INTERFACE (Note_column, "rest " "rest-collision " "stem " + "glissando-skip " ); diff --git a/lily/parser.yy b/lily/parser.yy index 35d858c46f..d4ab27c2bb 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -3600,7 +3600,7 @@ lyric_element: } | 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 diff --git a/lily/semi-tie.cc b/lily/semi-tie.cc index 0d31a2e073..2d0c1133a8 100644 --- a/lily/semi-tie.cc +++ b/lily/semi-tie.cc @@ -49,6 +49,7 @@ ADD_INTERFACE (Semi_tie, "head-direction " "note-head " "thickness " + "line-thickness " ); MAKE_SCHEME_CALLBACK (Semi_tie, calc_control_points, 1) diff --git a/scm/framework-ps.scm b/scm/framework-ps.scm index aee522e0fa..9498b2ac9d 100644 --- a/scm/framework-ps.scm +++ b/scm/framework-ps.scm @@ -538,13 +538,22 @@ (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))