Pattr commited on
Commit
2935922
·
1 Parent(s): 13b1f1e

Upload 1139 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +7 -0
  2. lilypond-2.24.2/bin/abc2ly.py +1557 -0
  3. lilypond-2.24.2/bin/convert-ly.py +445 -0
  4. lilypond-2.24.2/bin/etf2ly.py +1326 -0
  5. lilypond-2.24.2/bin/gspawn-win64-helper-console.exe +0 -0
  6. lilypond-2.24.2/bin/libgio-2.0-0.dll +3 -0
  7. lilypond-2.24.2/bin/libglib-2.0-0.dll +3 -0
  8. lilypond-2.24.2/bin/libgmodule-2.0-0.dll +0 -0
  9. lilypond-2.24.2/bin/libgobject-2.0-0.dll +0 -0
  10. lilypond-2.24.2/bin/libintl-8.dll +0 -0
  11. lilypond-2.24.2/bin/lilymidi.py +304 -0
  12. lilypond-2.24.2/bin/lilypond-book.py +790 -0
  13. lilypond-2.24.2/bin/lilypond-invoke-editor.py +135 -0
  14. lilypond-2.24.2/bin/lilypond.exe +3 -0
  15. lilypond-2.24.2/bin/lilysong.py +273 -0
  16. lilypond-2.24.2/bin/midi2ly.py +1329 -0
  17. lilypond-2.24.2/bin/musicxml2ly.py +0 -0
  18. lilypond-2.24.2/bin/pyexpat.pyd +0 -0
  19. lilypond-2.24.2/bin/python.exe +0 -0
  20. lilypond-2.24.2/bin/python310.dll +3 -0
  21. lilypond-2.24.2/bin/python310.zip +3 -0
  22. lilypond-2.24.2/etc/fonts/conf.d/10-hinting-slight.conf +15 -0
  23. lilypond-2.24.2/etc/fonts/conf.d/10-scale-bitmap-fonts.conf +83 -0
  24. lilypond-2.24.2/etc/fonts/conf.d/10-sub-pixel-none.conf +15 -0
  25. lilypond-2.24.2/etc/fonts/conf.d/10-yes-antialias.conf +8 -0
  26. lilypond-2.24.2/etc/fonts/conf.d/11-lcdfilter-default.conf +17 -0
  27. lilypond-2.24.2/etc/fonts/conf.d/20-unhint-small-vera.conf +49 -0
  28. lilypond-2.24.2/etc/fonts/conf.d/30-metric-aliases.conf +637 -0
  29. lilypond-2.24.2/etc/fonts/conf.d/40-nonlatin.conf +332 -0
  30. lilypond-2.24.2/etc/fonts/conf.d/45-generic.conf +136 -0
  31. lilypond-2.24.2/etc/fonts/conf.d/45-latin.conf +301 -0
  32. lilypond-2.24.2/etc/fonts/conf.d/48-spacing.conf +16 -0
  33. lilypond-2.24.2/etc/fonts/conf.d/49-sansserif.conf +22 -0
  34. lilypond-2.24.2/etc/fonts/conf.d/50-user.conf +16 -0
  35. lilypond-2.24.2/etc/fonts/conf.d/51-local.conf +7 -0
  36. lilypond-2.24.2/etc/fonts/conf.d/60-generic.conf +64 -0
  37. lilypond-2.24.2/etc/fonts/conf.d/60-latin.conf +88 -0
  38. lilypond-2.24.2/etc/fonts/conf.d/65-fonts-persian.conf +418 -0
  39. lilypond-2.24.2/etc/fonts/conf.d/65-nonlatin.conf +228 -0
  40. lilypond-2.24.2/etc/fonts/conf.d/69-unifont.conf +28 -0
  41. lilypond-2.24.2/etc/fonts/conf.d/80-delicious.conf +19 -0
  42. lilypond-2.24.2/etc/fonts/conf.d/90-synthetic.conf +64 -0
  43. lilypond-2.24.2/etc/fonts/conf.d/README +23 -0
  44. lilypond-2.24.2/etc/fonts/fonts.conf +101 -0
  45. lilypond-2.24.2/etc/relocate/fontconfig.reloc +2 -0
  46. lilypond-2.24.2/etc/relocate/guile.reloc +2 -0
  47. lilypond-2.24.2/etc/relocate/libexec.reloc +1 -0
  48. lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/and-let-star.go +0 -0
  49. lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/arrays.go +0 -0
  50. lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/atomic.go +0 -0
.gitattributes CHANGED
@@ -32,3 +32,10 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ lilypond-2.24.2/bin/libgio-2.0-0.dll filter=lfs diff=lfs merge=lfs -text
36
+ lilypond-2.24.2/bin/libglib-2.0-0.dll filter=lfs diff=lfs merge=lfs -text
37
+ lilypond-2.24.2/bin/lilypond.exe filter=lfs diff=lfs merge=lfs -text
38
+ lilypond-2.24.2/bin/python310.dll filter=lfs diff=lfs merge=lfs -text
39
+ lilypond-2.24.2/lib/guile/2.2/ccache/system/vm/assembler.go filter=lfs diff=lfs merge=lfs -text
40
+ lilypond-2.24.2/lib/guile/2.2/ccache/system/vm/dwarf.go filter=lfs diff=lfs merge=lfs -text
41
+ lilypond-2.24.2/libexec/gs.exe filter=lfs diff=lfs merge=lfs -text
lilypond-2.24.2/bin/abc2ly.py ADDED
@@ -0,0 +1,1557 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # once upon a rainy monday afternoon.
5
+
6
+ # This file is part of LilyPond, the GNU music typesetter.
7
+ #
8
+ # Copyright (C) 1999--2022 Han-Wen Nienhuys <[email protected]>
9
+ # Jan Nieuwenhuizen <[email protected]>
10
+ #
11
+ # LilyPond is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # LilyPond is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ #
25
+ # ...
26
+ #
27
+ # (not finished.)
28
+ # ABC standard v1.6: http://abcnotation.com/
29
+ #
30
+ # Enhancements (Roy R. Rankin)
31
+ #
32
+ # Header section moved to top of lilypond file
33
+ # handle treble, treble-8, alto, and bass clef
34
+ # Handle voices (V: headers) with clef and part names, multiple voices
35
+ # Handle w: lyrics with multiple verses
36
+ # Handle key mode names for minor, major, phrygian, ionian, locrian, aeolian,
37
+ # mixolydian, lydian, dorian
38
+ # Handle part names from V: header
39
+ # Tuplets handling fixed up
40
+ # Lines starting with |: not discarded as header lines
41
+ # Multiple T: and C: header entries handled
42
+ # Accidental maintained until next bar check
43
+ # Silent rests supported
44
+ # articulations fermata, upbow, downbow, ltoe, accent, tenuto supported
45
+ # Chord strings([-^]"string") can contain a '#'
46
+ # Header fields enclosed by [] in notes string processed
47
+ # W: words output after tune as abc2ps does it (they failed before)
48
+
49
+ # Enhancements (Laura Conrad)
50
+ #
51
+ # Barring now preserved between ABC and lilypond
52
+ # the default placement for text in abc is above the staff.
53
+ # %%LY now supported.
54
+ # \breve and \longa supported.
55
+ # M:none doesn't crash lily.
56
+ # lilypond '--' supported.
57
+
58
+ # Enhancements (Guy Gascoigne-Piggford)
59
+ #
60
+ # Add support for maintaining ABC's notion of beaming, this is selectable
61
+ # from the command line with a -b or --beam option.
62
+ # Fixd a problem where on cygwin empty lines weren't being correctly identifed
63
+ # and so were complaining, but still generating the correct output.
64
+
65
+ # Limitations
66
+ #
67
+ # Multiple tunes in single file not supported
68
+ # Blank T: header lines should write score and open a new score
69
+ # Not all header fields supported
70
+ # ABC line breaks are ignored
71
+ # Block comments generate error and are ignored
72
+ # Postscript commands are ignored
73
+ # lyrics not resynchronized by line breaks (lyrics must fully match notes)
74
+ # %%LY slyrics can't be directly before a w: line.
75
+ # ???
76
+
77
+
78
+ # TODO:
79
+ #
80
+ # * coding style
81
+ # * lilylib
82
+ # * GNU style messages: warning:FILE:LINE:
83
+ # * l10n
84
+ #
85
+ # Convert to new chord styles.
86
+ #
87
+ # UNDEF -> None
88
+ #
89
+
90
+ import __main__
91
+ import getopt
92
+ import gettext
93
+ import os
94
+ import re
95
+ import sys
96
+
97
+ """
98
+
99
+ # relocate-preamble.py.in
100
+ #
101
+ # This file is part of LilyPond, the GNU music typesetter.
102
+ #
103
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
104
+ #
105
+ # LilyPond is free software: you can redistribute it and/or modify
106
+ # it under the terms of the GNU General Public License as published by
107
+ # the Free Software Foundation, either version 3 of the License, or
108
+ # (at your option) any later version.
109
+ #
110
+ # LilyPond is distributed in the hope that it will be useful,
111
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
112
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
113
+ # GNU General Public License for more details.
114
+ #
115
+ # You should have received a copy of the GNU General Public License
116
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
117
+ #
118
+
119
+ This is generic code, used for all python scripts.
120
+
121
+ The quotes are to ensure that the source .py file can still be
122
+ run as a python script, but does not include any sys.path handling.
123
+ Otherwise, the lilypond-book calls inside the build
124
+ might modify installed .pyc files.
125
+
126
+ """
127
+
128
+ # This is needed for installations with a non-default layout, ie where share/
129
+ # is not next to bin/.
130
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
131
+
132
+ # Dynamic relocation, for installations with a default layout including GUB,
133
+ # but also for execution from the build directory.
134
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
135
+ topdir = os.path.dirname (bindir)
136
+ if bindir.endswith (r'/scripts/out'):
137
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
138
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
139
+ for v in [ 'current', '2.24.2' ]:
140
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
141
+
142
+ """
143
+ """
144
+
145
+ # Load translation and install _() into Python's builtins namespace.
146
+ gettext.install('lilypond', '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale')
147
+
148
+ import lilylib as ly
149
+
150
+ version = '2.24.2'
151
+ if version == '@' + 'TOPLEVEL_VERSION' + '@':
152
+ version = '(unknown version)' # uGUHGUHGHGUGH
153
+
154
+ UNDEF = 255
155
+ state = UNDEF
156
+ voice_idx_dict = {}
157
+ header = {}
158
+ header['footnotes'] = ''
159
+ lyrics = []
160
+ slyrics = []
161
+ voices = []
162
+ state_list = []
163
+ repeat_state = [0] * 8
164
+ current_voice_idx = -1
165
+ current_lyric_idx = -1
166
+ lyric_idx = -1
167
+ part_names = 0
168
+ default_len = 8
169
+ length_specified = 0
170
+ nobarlines = 0
171
+ global_key = [0] * 7 # UGH
172
+ names = ["One", "Two", "Three"]
173
+ DIGITS = '0123456789'
174
+ HSPACE = ' \t'
175
+ midi_specs = ''
176
+
177
+
178
+ def error(msg):
179
+ sys.stderr.write(msg)
180
+ if global_options.strict:
181
+ sys.exit(1)
182
+
183
+
184
+ def alphabet(i):
185
+ return chr(i + ord('A'))
186
+
187
+
188
+ def check_clef(s):
189
+ # the number gives the base_octave
190
+ clefs = [("treble", "treble", 0),
191
+ ("treble1", "french", 0),
192
+ ("bass3", "varbaritone", 0),
193
+ ("bass", "bass", 0),
194
+ ("alto4", "tenor", 0),
195
+ ("alto2", "mezzosoprano", 0),
196
+ ("alto1", "soprano", 0),
197
+ ("alto", "alto", 0),
198
+ ("perc", "percussion", 0)]
199
+ modifier = [("-8va", "_8", -1),
200
+ ("-8", "_8", -1),
201
+ (r"\+8", "^8", +1),
202
+ ("8", "_8", -1)]
203
+
204
+ if not s:
205
+ return ''
206
+ clef = None
207
+ octave = 0
208
+ for c in clefs:
209
+ m = re.match('^'+c[0], s)
210
+ if m:
211
+ (clef, octave) = (c[1], c[2])
212
+ s = s[m.end():]
213
+ break
214
+ if not clef:
215
+ return s
216
+
217
+ mod = ""
218
+ for md in modifier:
219
+ m = re.match('^'+md[0], s)
220
+ if m:
221
+ mod = md[1]
222
+ octave += md[2]
223
+ s = s[m.end():]
224
+ break
225
+
226
+ state.base_octave = octave
227
+ voices_append("\\clef \""+clef+mod+"\"\n")
228
+ return s
229
+
230
+
231
+ def select_voice(name, rol):
232
+ if name not in voice_idx_dict:
233
+ state_list.append(Parser_state())
234
+ voices.append('')
235
+ slyrics.append([])
236
+ voice_idx_dict[name] = len(voices) - 1
237
+ __main__.current_voice_idx = voice_idx_dict[name]
238
+ __main__.state = state_list[current_voice_idx]
239
+ while rol != '':
240
+ m = re.match('^([^ \t=]*)=(.*)$', rol) # find keywork
241
+ if m:
242
+ keyword = m.group(1)
243
+ rol = m.group(2)
244
+ a = re.match('^("[^"]*"|[^ \t]*) *(.*)$', rol)
245
+ if a:
246
+ value = a.group(1)
247
+ rol = a.group(2)
248
+ if keyword == 'clef':
249
+ check_clef(value)
250
+ elif keyword == "name":
251
+ value = re.sub('\\\\', '\\\\\\\\', value)
252
+ # < 2.2
253
+ voices_append("\\set Staff.instrument = %s\n" % value)
254
+
255
+ __main__.part_names = 1
256
+ elif keyword == "sname" or keyword == "snm":
257
+ voices_append("\\set Staff.instr = %s\n" % value)
258
+ else:
259
+ break
260
+
261
+
262
+ def dump_header(outf, hdr):
263
+ outf.write('\\header {\n')
264
+ ks = sorted(hdr.keys())
265
+ for k in ks:
266
+ hdr[k] = re.sub('"', '\\"', hdr[k])
267
+ outf.write('\t%s = "%s"\n' % (k, hdr[k]))
268
+ outf.write('}')
269
+
270
+
271
+ def dump_lyrics(outf):
272
+ if lyrics:
273
+ outf.write("\n\\markup \\column {\n")
274
+ for i in range(len(lyrics)):
275
+ outf.write(lyrics[i])
276
+ outf.write("\n")
277
+ outf.write("}\n")
278
+
279
+
280
+ def dump_default_bar(outf):
281
+ """
282
+ Nowadays abc2ly outputs explicits barlines (?)
283
+ """
284
+ # < 2.2
285
+ outf.write("\n\\set Score.measureBarType = \"\"\n")
286
+
287
+
288
+ def dump_slyrics(outf):
289
+ ks = sorted(voice_idx_dict.keys())
290
+ for k in ks:
291
+ if re.match('[1-9]', k):
292
+ m = alphabet(int(k))
293
+ else:
294
+ m = k
295
+ for i in range(len(slyrics[voice_idx_dict[k]])):
296
+ l = alphabet(i)
297
+ outf.write("\nwords%sV%s = \\lyricmode {" % (m, l))
298
+ outf.write("\n" + slyrics[voice_idx_dict[k]][i])
299
+ outf.write("\n}")
300
+
301
+
302
+ def dump_voices(outf):
303
+ global doing_alternative, in_repeat
304
+ ks = sorted(voice_idx_dict.keys())
305
+ for k in ks:
306
+ if re.match('[1-9]', k):
307
+ m = alphabet(int(k))
308
+ else:
309
+ m = k
310
+ outf.write("\nvoice%s = {" % m)
311
+ dump_default_bar(outf)
312
+ if repeat_state[voice_idx_dict[k]]:
313
+ outf.write("\n\\repeat volta 2 {")
314
+ outf.write("\n" + voices[voice_idx_dict[k]])
315
+ if not using_old:
316
+ if doing_alternative[voice_idx_dict[k]]:
317
+ outf.write("}")
318
+ if in_repeat[voice_idx_dict[k]]:
319
+ outf.write("}")
320
+ outf.write("\n}")
321
+
322
+
323
+ def try_parse_q(a):
324
+ # assume that Q takes the form "Q:'opt. description' 1/4=120"
325
+ # There are other possibilities, but they are deprecated
326
+ r = re.compile(r'^(.*) *([0-9]+) */ *([0-9]+) *=* *([0-9]+)\s*')
327
+ m = r.match(a)
328
+ if m:
329
+ descr = m.group(1) # possibly empty
330
+ numerator = int(m.group(2))
331
+ denominator = int(m.group(3))
332
+ tempo = m.group(4)
333
+ dur = duration_to_lilypond_duration((numerator, denominator), 1, 0)
334
+ voices_append("\\tempo " + descr + " " + dur + "=" + tempo + "\n")
335
+ else:
336
+ # Parsing of numeric tempi, as these are fairly
337
+ # common. The spec says the number is a "beat" so using
338
+ # a quarter note as the standard time
339
+ numericQ = re.compile('[0-9]+')
340
+ m = numericQ.match(a)
341
+ if m:
342
+ voices_append("\\tempo 4=" + m.group(0))
343
+ else:
344
+ sys.stderr.write(
345
+ "abc2ly: Warning, unable to parse Q specification: %s\n" % a)
346
+
347
+
348
+ def dump_score(outf):
349
+ outf.write(r"""
350
+
351
+ \score{
352
+ <<
353
+ """)
354
+
355
+ ks = sorted(voice_idx_dict.keys())
356
+ for k in ks:
357
+ if re.match('[1-9]', k):
358
+ m = alphabet(int(k))
359
+ else:
360
+ m = k
361
+ if k == 'default' and len(voice_idx_dict) > 1:
362
+ break
363
+ outf.write("\n\t\\context Staff=\"%s\"\n\t{\n" % k)
364
+ if k != 'default':
365
+ outf.write("\t \\voicedefault\n")
366
+ outf.write("\t \\voice%s " % m)
367
+ outf.write("\n\t}\n")
368
+
369
+ l = ord('A')
370
+ for lyrics in slyrics[voice_idx_dict[k]]:
371
+ outf.write("\n\t\\addlyrics {\n")
372
+ if re.match('[1-9]', k):
373
+ m = alphabet(int(k))
374
+ else:
375
+ m = k
376
+
377
+ outf.write(" \\words%sV%s } " % (m, chr(l)))
378
+ l += 1
379
+
380
+ outf.write("\n >>")
381
+ outf.write("\n\t\\layout {\n")
382
+ outf.write("\t}\n\t\\midi {%s}\n}\n" % midi_specs)
383
+
384
+
385
+ def set_default_length(s):
386
+ global length_specified
387
+ m = re.search('1/([0-9]+)', s)
388
+ if m:
389
+ __main__.default_len = int(m.group(1))
390
+ length_specified = 1
391
+
392
+
393
+ def set_default_len_from_time_sig(s):
394
+ m = re.search('([0-9]+)/([0-9]+)', s)
395
+ if m:
396
+ n = int(m.group(1))
397
+ d = int(m.group(2))
398
+ if (n * 1.0)/(d * 1.0) < 0.75:
399
+ __main__.default_len = 16
400
+ else:
401
+ __main__.default_len = 8
402
+
403
+
404
+ def gulp_file(f):
405
+ try:
406
+ i = open(f, encoding="utf8")
407
+ i.seek(0, 2)
408
+ n = i.tell()
409
+ i.seek(0, 0)
410
+ except FileNotFoundError:
411
+ sys.stderr.write("cannot open file: `%s'\n" % f)
412
+ return ''
413
+ s = i.read(n)
414
+ if len(s) <= 0:
415
+ sys.stderr.write("gulped empty file: `%s'\n" % f)
416
+ i.close()
417
+ return s
418
+
419
+
420
+ # pitch manipulation. Tuples are (name, alteration).
421
+ # 0 is (central) C. Alteration -1 is a flat, Alteration +1 is a sharp
422
+ # pitch in semitones.
423
+ def semitone_pitch(tup):
424
+ p = 0
425
+
426
+ t = tup[0]
427
+ p = p + 12 * (t // 7)
428
+ t = t % 7
429
+
430
+ if t > 2:
431
+ p = p - 1
432
+
433
+ p = p + t * 2 + tup[1]
434
+ return p
435
+
436
+
437
+ def fifth_above_pitch(tup):
438
+ (n, a) = (tup[0] + 4, tup[1])
439
+
440
+ difference = 7 - (semitone_pitch((n, a)) - semitone_pitch(tup))
441
+ a = a + difference
442
+
443
+ return (n, a)
444
+
445
+
446
+ def sharp_keys():
447
+ p = (0, 0)
448
+ l = []
449
+ k = 0
450
+ while True:
451
+ l.append(p)
452
+ (t, a) = fifth_above_pitch(p)
453
+ if semitone_pitch((t, a)) % 12 == 0:
454
+ break
455
+
456
+ p = (t % 7, a)
457
+ return l
458
+
459
+
460
+ def flat_keys():
461
+ p = (0, 0)
462
+ l = []
463
+ k = 0
464
+ while True:
465
+ l.append(p)
466
+ (t, a) = quart_above_pitch(p)
467
+ if semitone_pitch((t, a)) % 12 == 0:
468
+ break
469
+
470
+ p = (t % 7, a)
471
+ return l
472
+
473
+
474
+ def quart_above_pitch(tup):
475
+ (n, a) = (tup[0] + 3, tup[1])
476
+
477
+ difference = 5 - (semitone_pitch((n, a)) - semitone_pitch(tup))
478
+ a = a + difference
479
+
480
+ return (n, a)
481
+
482
+
483
+ key_lookup = { # abc to lilypond key mode names
484
+ 'm': 'minor',
485
+ 'min': 'minor',
486
+ 'maj': 'major',
487
+ 'major': 'major',
488
+ 'phr': 'phrygian',
489
+ 'ion': 'ionian',
490
+ 'loc': 'locrian',
491
+ 'aeo': 'aeolian',
492
+ 'mix': 'mixolydian',
493
+ 'mixolydian': 'mixolydian',
494
+ 'lyd': 'lydian',
495
+ 'dor': 'dorian',
496
+ 'dorian': 'dorian'
497
+ }
498
+
499
+
500
+ def lily_key(k):
501
+ if k == 'none':
502
+ return
503
+ orig = "" + k
504
+ # UGR
505
+ k = k.lower()
506
+ key = k[0]
507
+ # UGH
508
+ k = k[1:]
509
+ if k and k[0] == '#':
510
+ key = key + 'is'
511
+ k = k[1:]
512
+ elif k and k[0] == 'b':
513
+ key = key + 'es'
514
+ k = k[1:]
515
+ if not k:
516
+ return '%s \\major' % key
517
+
518
+ type = k[0:3]
519
+ if type not in key_lookup:
520
+ # ugh, use lilylib, say WARNING:FILE:LINE:
521
+ sys.stderr.write("abc2ly:warning:")
522
+ sys.stderr.write("ignoring unknown key: `%s'" % orig)
523
+ sys.stderr.write('\n')
524
+ return 0
525
+ return "%s \\%s" % (key, key_lookup[type])
526
+
527
+
528
+ def shift_key(note, acc, shift):
529
+ s = semitone_pitch((note, acc))
530
+ s = (s + shift + 12) % 12
531
+ if s <= 4:
532
+ n = s // 2
533
+ a = s % 2
534
+ else:
535
+ n = (s + 1) // 2
536
+ a = (s + 1) % 2
537
+ if a:
538
+ n = n + 1
539
+ a = -1
540
+ return (n, a)
541
+
542
+
543
+ key_shift = { # semitone shifts for key mode names
544
+ 'm': 3,
545
+ 'min': 3,
546
+ 'minor': 3,
547
+ 'maj': 0,
548
+ 'major': 0,
549
+ 'phr': -4,
550
+ 'phrygian': -4,
551
+ 'ion': 0,
552
+ 'ionian': 0,
553
+ 'loc': 1,
554
+ 'locrian': 1,
555
+ 'aeo': 3,
556
+ 'aeolian': 3,
557
+ 'mix': 5,
558
+ 'mixolydian': 5,
559
+ 'lyd': -5,
560
+ 'lydian': -5,
561
+ 'dor': -2,
562
+ 'dorian': -2
563
+ }
564
+
565
+
566
+ def compute_key(k):
567
+ k = k.lower()
568
+ intkey = (ord(k[0]) - ord('a') + 5) % 7
569
+ intkeyacc = 0
570
+ k = k[1:]
571
+
572
+ if k and k[0] == 'b':
573
+ intkeyacc = -1
574
+ k = k[1:]
575
+ elif k and k[0] == '#':
576
+ intkeyacc = 1
577
+ k = k[1:]
578
+ k = k[0:3]
579
+ if k and k in key_shift:
580
+ (intkey, intkeyacc) = shift_key(intkey, intkeyacc, key_shift[k])
581
+ keytup = (intkey, intkeyacc)
582
+
583
+ sharp_key_seq = sharp_keys()
584
+ flat_key_seq = flat_keys()
585
+
586
+ accseq = None
587
+ accsign = 0
588
+ if keytup in sharp_key_seq:
589
+ accsign = 1
590
+ key_count = sharp_key_seq.index(keytup)
591
+ accseq = [(4*x - 1) % 7 for x in range(1, key_count + 1)]
592
+
593
+ elif keytup in flat_key_seq:
594
+ accsign = -1
595
+ key_count = flat_key_seq.index(keytup)
596
+ accseq = [(3*x + 3) % 7 for x in range(1, key_count + 1)]
597
+ else:
598
+ error("Huh?")
599
+ raise Exception("Huh")
600
+
601
+ key_table = [0] * 7
602
+ for a in accseq:
603
+ key_table[a] = key_table[a] + accsign
604
+
605
+ return key_table
606
+
607
+
608
+ tup_lookup = {
609
+ '2': '3/2',
610
+ '3': '2/3',
611
+ '4': '4/3',
612
+ '5': '4/5',
613
+ '6': '4/6',
614
+ '7': '6/7',
615
+ '9': '8/9',
616
+ }
617
+
618
+
619
+ def try_parse_tuplet_begin(s, state):
620
+ if re.match(r'\([2-9]', s):
621
+ dig = s[1]
622
+ s = s[2:]
623
+ prev_tuplet_state = state.parsing_tuplet
624
+ state.parsing_tuplet = int(dig[0])
625
+ if prev_tuplet_state:
626
+ voices_append("}")
627
+ voices_append("\\times %s {" % tup_lookup[dig])
628
+ return s
629
+
630
+
631
+ def try_parse_group_end(s, state):
632
+ if s and s[0] in HSPACE:
633
+ s = s[1:]
634
+ close_beam_state(state)
635
+ return s
636
+
637
+
638
+ def header_append(key, a):
639
+ s = ''
640
+ if key in header:
641
+ s = header[key] + "\n"
642
+ header[key] = s + a
643
+
644
+
645
+ def wordwrap(a, v):
646
+ linelen = len(v) - v.rfind('\n')
647
+ if linelen + len(a) > 80:
648
+ v = v + '\n'
649
+ return v + a + ' '
650
+
651
+
652
+ def stuff_append(stuff, idx, a):
653
+ if not stuff:
654
+ stuff.append(a)
655
+ else:
656
+ stuff[idx] = wordwrap(a, stuff[idx])
657
+
658
+ # ignore wordwrap since we are adding to the previous word
659
+
660
+
661
+ def stuff_append_back(stuff, idx, a):
662
+ if not stuff:
663
+ stuff.append(a)
664
+ else:
665
+ point = len(stuff[idx])-1
666
+ while stuff[idx][point] == ' ':
667
+ point = point - 1
668
+ point = point + 1
669
+ stuff[idx] = stuff[idx][:point] + a + stuff[idx][point:]
670
+
671
+
672
+ def voices_append(a):
673
+ if current_voice_idx < 0:
674
+ select_voice('default', '')
675
+ stuff_append(voices, current_voice_idx, a)
676
+
677
+ # word wrap really makes it hard to bind beams to the end of notes since it
678
+ # pushes out whitespace on every call. The _back functions do an append
679
+ # prior to the last space, effectively tagging whatever they are given
680
+ # onto the last note
681
+
682
+
683
+ def voices_append_back(a):
684
+ if current_voice_idx < 0:
685
+ select_voice('default', '')
686
+ stuff_append_back(voices, current_voice_idx, a)
687
+
688
+
689
+ def repeat_prepend():
690
+ global repeat_state
691
+ if current_voice_idx < 0:
692
+ select_voice('default', '')
693
+ if not using_old:
694
+ repeat_state[current_voice_idx] = 't'
695
+
696
+
697
+ def lyrics_append(a):
698
+ a = re.sub('#', '\\#', a) # latex does not like naked #'s
699
+ a = re.sub('"', '\\"', a) # latex does not like naked "'s
700
+ a = ' \\line { "' + a + '" }\n'
701
+ stuff_append(lyrics, current_lyric_idx, a)
702
+
703
+ # break lyrics to words and put "'s around words containing numbers and '"'s
704
+
705
+
706
+ def fix_lyric(s):
707
+ ret = ''
708
+ while s != '':
709
+ m = re.match('[ \t]*([^ \t]*)[ \t]*(.*$)', s)
710
+ if m:
711
+ word = m.group(1)
712
+ s = m.group(2)
713
+ word = re.sub('"', '\\"', word) # escape "
714
+ if re.match(r'.*[0-9"\(]', word):
715
+ word = re.sub('_', ' ', word) # _ causes probs inside ""
716
+ ret = ret + '\"' + word + '\" '
717
+ else:
718
+ ret = ret + word + ' '
719
+ else:
720
+ return ret
721
+ return ret
722
+
723
+
724
+ def slyrics_append(a):
725
+ a = re.sub('_', ' _ ', a) # _ to ' _ '
726
+ # split words with "-" unless was originally "--"
727
+ a = re.sub('([^-])-([^-])', '\\1- \\2', a)
728
+ a = re.sub('\\\\- ', '-', a) # unless \-
729
+ a = re.sub('~', '_', a) # ~ to space('_')
730
+ a = re.sub(r'\*', '_ ', a) # * to to space
731
+ a = re.sub('#', '\\#', a) # latex does not like naked #'s
732
+ if re.match(r'.*[0-9"\(]', a): # put numbers and " and ( into quoted string
733
+ a = fix_lyric(a)
734
+ a = re.sub('$', ' ', a) # insure space between lines
735
+ __main__.lyric_idx = lyric_idx + 1
736
+ if len(slyrics[current_voice_idx]) <= lyric_idx:
737
+ slyrics[current_voice_idx].append(a)
738
+ else:
739
+ v = slyrics[current_voice_idx][lyric_idx]
740
+ slyrics[current_voice_idx][lyric_idx] = wordwrap(
741
+ a, slyrics[current_voice_idx][lyric_idx])
742
+
743
+
744
+ def try_parse_header_line(ln, state):
745
+ global length_specified
746
+ m = re.match('^([A-Za-z]): *(.*)$', ln)
747
+
748
+ if m:
749
+ g = m.group(1)
750
+ a = m.group(2)
751
+ if g == 'T': # title
752
+ a = re.sub('[ \t]*$', '', a) # strip trailing blanks
753
+ if 'title' in header:
754
+ if a:
755
+ if len(header['title']):
756
+ # the non-ascii character
757
+ # in the string below is a
758
+ # punctuation dash. (TeX ---)
759
+ header['title'] = header['title'] + ' — ' + a
760
+ else:
761
+ header['subtitle'] = a
762
+ else:
763
+ header['title'] = a
764
+ if g == 'M': # Meter
765
+ if a == 'C':
766
+ if not state.common_time:
767
+ state.common_time = 1
768
+ voices_append(
769
+ " \\override Staff.TimeSignature.style = #'C\n")
770
+ a = '4/4'
771
+ if a == 'C|':
772
+ if not state.common_time:
773
+ state.common_time = 1
774
+ voices_append(
775
+ "\\override Staff.TimeSignature.style = #'C\n")
776
+ a = '2/2'
777
+ if not length_specified:
778
+ set_default_len_from_time_sig(a)
779
+ else:
780
+ length_specified = 0
781
+ if not a == 'none':
782
+ voices_append('\\time %s' % a)
783
+ state.next_bar = ''
784
+ if g == 'K': # KEY
785
+ a = check_clef(a)
786
+ if a:
787
+ # separate clef info
788
+ m = re.match('^([^ \t]*) *([^ ]*)( *)(.*)$', a)
789
+ if m:
790
+ # there may or may not be a space
791
+ # between the key letter and the mode
792
+ # convert the mode to lower-case before comparing
793
+ mode = m.group(2)[0:3].lower()
794
+ if mode in key_lookup:
795
+ # use the full mode, not only the first three letters
796
+ key_info = m.group(1) + m.group(2).lower()
797
+ clef_info = a[m.start(4):]
798
+ else:
799
+ key_info = m.group(1)
800
+ clef_info = a[m.start(2):]
801
+ __main__.global_key = compute_key(key_info)
802
+ k = lily_key(key_info)
803
+ if k:
804
+ voices_append('\\key %s' % k)
805
+ check_clef(clef_info)
806
+ else:
807
+ __main__.global_key = compute_key(a)
808
+ k = lily_key(a)
809
+ if k:
810
+ voices_append('\\key %s \\major' % k)
811
+ if g == 'N': # Notes
812
+ header['footnotes'] = header['footnotes'] + '\\\\\\\\' + a
813
+ if g == 'O': # Origin
814
+ header['origin'] = a
815
+ if g == 'X': # Reference Number
816
+ header['crossRefNumber'] = a
817
+ if g == 'A': # Area
818
+ header['area'] = a
819
+ if g == 'H': # History
820
+ header_append('history', a)
821
+ if g == 'B': # Book
822
+ header['book'] = a
823
+ if g == 'C': # Composer
824
+ if 'composer' in header:
825
+ if a:
826
+ header['composer'] = header['composer'] + '\\\\\\\\' + a
827
+ else:
828
+ header['composer'] = a
829
+ if g == 'S':
830
+ header['subtitle'] = a
831
+ if g == 'L': # Default note length
832
+ set_default_length(ln)
833
+ if g == 'V': # Voice
834
+ voice = re.sub(' .*$', '', a)
835
+ rest = re.sub('^[^ \t]* *', '', a)
836
+ if state.next_bar:
837
+ voices_append(state.next_bar)
838
+ state.next_bar = ''
839
+ select_voice(voice, rest)
840
+ if g == 'W': # Words
841
+ lyrics_append(a)
842
+ if g == 'w': # vocals
843
+ slyrics_append(a)
844
+ if g == 'Q': # tempo
845
+ try_parse_q(a)
846
+ if g == 'R': # Rhythm (e.g. jig, reel, hornpipe)
847
+ header['meter'] = a
848
+ if g == 'Z': # Transcription (e.g. Steve Mansfield 1/2/2000)
849
+ header['transcription'] = a
850
+ return ''
851
+ return ln
852
+
853
+ # we use in this order specified accidental, active accidental for bar,
854
+ # active accidental for key
855
+
856
+
857
+ def pitch_to_lilypond_name(name, acc, bar_acc, key):
858
+ s = ''
859
+ if acc == UNDEF:
860
+ if not nobarlines:
861
+ acc = bar_acc
862
+ if acc == UNDEF:
863
+ acc = key
864
+ if acc == -1:
865
+ s = 'es'
866
+ elif acc == 1:
867
+ s = 'is'
868
+
869
+ if name > 4:
870
+ name = name - 7
871
+ return chr(name + ord('c')) + s
872
+
873
+
874
+ def octave_to_lilypond_quotes(o):
875
+ o = o + 2
876
+ s = ''
877
+ if o < 0:
878
+ o = -o
879
+ s = ','
880
+ else:
881
+ s = '\''
882
+
883
+ return s * o
884
+
885
+
886
+ def parse_num(s):
887
+ durstr = ''
888
+ while s and s[0] in DIGITS:
889
+ durstr = durstr + s[0]
890
+ s = s[1:]
891
+
892
+ n = None
893
+ if durstr:
894
+ n = int(durstr)
895
+ return (s, n)
896
+
897
+
898
+ def duration_to_lilypond_duration(multiply_tup, defaultlen, dots):
899
+ base = 1
900
+ # (num / den) / defaultlen < 1/base
901
+ while base * multiply_tup[0] < multiply_tup[1]:
902
+ base = base * 2
903
+ if base == 1:
904
+ if (multiply_tup[0] / multiply_tup[1]) == 2:
905
+ base = '\\breve'
906
+ if (multiply_tup[0] / multiply_tup[1]) == 3:
907
+ base = '\\breve'
908
+ dots = 1
909
+ if (multiply_tup[0] / multiply_tup[1]) == 4:
910
+ base = '\\longa'
911
+ return '%s%s' % (base, '.' * dots)
912
+
913
+
914
+ class Parser_state:
915
+ def __init__(self):
916
+ self.in_acc = {}
917
+ self.next_articulation = ''
918
+ self.next_bar = ''
919
+ self.next_dots = 0
920
+ self.next_den = 1
921
+ self.parsing_tuplet = 0
922
+ self.plus_chord = 0
923
+ self.base_octave = 0
924
+ self.common_time = 0
925
+ self.parsing_beam = 0
926
+
927
+
928
+ # return (str, num,den,dots)
929
+ def parse_duration(s, parser_state):
930
+ num = 0
931
+ den = parser_state.next_den
932
+ parser_state.next_den = 1
933
+
934
+ (s, num) = parse_num(s)
935
+ if not num:
936
+ num = 1
937
+ if len(s):
938
+ if s[0] == '/':
939
+ if len(s[0]):
940
+ while s[:1] == '/':
941
+ s = s[1:]
942
+ d = 2
943
+ if s[0] in DIGITS:
944
+ (s, d) = parse_num(s)
945
+
946
+ den = den * d
947
+
948
+ den = den * default_len
949
+
950
+ current_dots = parser_state.next_dots
951
+ parser_state.next_dots = 0
952
+ if re.match('[ \t]*[<>]', s):
953
+ while s[0] in HSPACE:
954
+ s = s[1:]
955
+ while s[0] == '>':
956
+ s = s[1:]
957
+ current_dots = current_dots + 1
958
+ parser_state.next_den = parser_state.next_den * 2
959
+
960
+ while s[0] == '<':
961
+ s = s[1:]
962
+ den = den * 2
963
+ parser_state.next_dots = parser_state.next_dots + 1
964
+
965
+ try_dots = [3, 2, 1]
966
+ for d in try_dots:
967
+ f = 1 << d
968
+ multiplier = (2*f-1)
969
+ if num % multiplier == 0 and den % f == 0:
970
+ num = num / multiplier
971
+ den = den / f
972
+ current_dots = current_dots + d
973
+
974
+ return (s, num, den, current_dots)
975
+
976
+
977
+ def try_parse_rest(s, parser_state):
978
+ if not s or s[0] != 'z' and s[0] != 'x':
979
+ return s
980
+
981
+ __main__.lyric_idx = -1
982
+
983
+ if parser_state.next_bar:
984
+ voices_append(parser_state.next_bar)
985
+ parser_state.next_bar = ''
986
+
987
+ if s[0] == 'z':
988
+ rest = 'r'
989
+ else:
990
+ rest = 's'
991
+ s = s[1:]
992
+
993
+ (s, num, den, d) = parse_duration(s, parser_state)
994
+ voices_append(
995
+ '%s%s' % (rest, duration_to_lilypond_duration((num, den), default_len, d)))
996
+ if parser_state.next_articulation:
997
+ voices_append(parser_state.next_articulation)
998
+ parser_state.next_articulation = ''
999
+
1000
+ return s
1001
+
1002
+
1003
+ artic_tbl = {
1004
+ '.': '-.',
1005
+ 'T': '^\\trill',
1006
+ 'H': '^\\fermata',
1007
+ 'u': '^\\upbow',
1008
+ 'K': '^\\ltoe',
1009
+ 'k': '^\\accent',
1010
+ 'M': '^\\tenuto',
1011
+ '~': '^"~" ',
1012
+ 'J': '', # ignore slide
1013
+ 'R': '', # ignore roll
1014
+ 'S': '^\\segno',
1015
+ 'O': '^\\coda',
1016
+ 'v': '^\\downbow'
1017
+ }
1018
+
1019
+
1020
+ def try_parse_articulation(s, state):
1021
+ while s and s[:1] in artic_tbl:
1022
+ state.next_articulation = state.next_articulation + artic_tbl[s[:1]]
1023
+ if not artic_tbl[s[:1]]:
1024
+ sys.stderr.write("Warning: ignoring `%s'\n" % s[:1])
1025
+
1026
+ s = s[1:]
1027
+
1028
+ # s7m2 input doesn't care about spaces
1029
+ if re.match(r'[ \t]*\(', s):
1030
+ s = s.lstrip()
1031
+
1032
+ slur_begin = 0
1033
+ while s[:1] == '(' and s[1] not in DIGITS:
1034
+ slur_begin = slur_begin + 1
1035
+ state.next_articulation = state.next_articulation + '('
1036
+ s = s[1:]
1037
+
1038
+ return s
1039
+
1040
+ #
1041
+ # remember accidental for rest of bar
1042
+ #
1043
+
1044
+
1045
+ def set_bar_acc(note, octave, acc, state):
1046
+ if acc == UNDEF:
1047
+ return
1048
+ n_oct = note + octave * 7
1049
+ state.in_acc[n_oct] = acc
1050
+
1051
+ # get accidental set in this bar or UNDEF if not set
1052
+
1053
+
1054
+ def get_bar_acc(note, octave, state):
1055
+ n_oct = note + octave * 7
1056
+ if n_oct in state.in_acc:
1057
+ return state.in_acc[n_oct]
1058
+ else:
1059
+ return UNDEF
1060
+
1061
+
1062
+ def clear_bar_acc(state):
1063
+ state.in_acc = {}
1064
+
1065
+
1066
+ # if we are parsing a beam, close it off
1067
+ def close_beam_state(state):
1068
+ if state.parsing_beam and global_options.beams:
1069
+ state.parsing_beam = 0
1070
+ voices_append_back(']')
1071
+
1072
+
1073
+ # WAT IS ABC EEN ONTZETTENDE PROGRAMMEERPOEP !
1074
+ def try_parse_note(s, parser_state):
1075
+ mud = ''
1076
+
1077
+ slur_begin = 0
1078
+ if not s:
1079
+ return s
1080
+
1081
+ articulation = ''
1082
+ acc = UNDEF
1083
+ if s[0] in '^=_':
1084
+ c = s[0]
1085
+ s = s[1:]
1086
+ if c == '^':
1087
+ acc = 1
1088
+ if c == '=':
1089
+ acc = 0
1090
+ if c == '_':
1091
+ acc = -1
1092
+
1093
+ octave = parser_state.base_octave
1094
+ if s[0] in "ABCDEFG":
1095
+ s = s[0].lower() + s[1:]
1096
+ octave = octave - 1
1097
+
1098
+ notename = 0
1099
+ if s[0] in "abcdefg":
1100
+ notename = (ord(s[0]) - ord('a') + 5) % 7
1101
+ s = s[1:]
1102
+ else:
1103
+ return s # failed; not a note!
1104
+
1105
+ __main__.lyric_idx = -1
1106
+
1107
+ if parser_state.next_bar:
1108
+ voices_append(parser_state.next_bar)
1109
+ parser_state.next_bar = ''
1110
+
1111
+ while s[0] == ',':
1112
+ octave = octave - 1
1113
+ s = s[1:]
1114
+ while s[0] == '\'':
1115
+ octave = octave + 1
1116
+ s = s[1:]
1117
+
1118
+ (s, num, den, current_dots) = parse_duration(s, parser_state)
1119
+
1120
+ if re.match(r'[ \t]*\)', s):
1121
+ s = s.lstrip()
1122
+
1123
+ slur_end = 0
1124
+ while s[:1] == ')':
1125
+ slur_end = slur_end + 1
1126
+ s = s[1:]
1127
+
1128
+ bar_acc = get_bar_acc(notename, octave, parser_state)
1129
+ pit = pitch_to_lilypond_name(notename, acc, bar_acc, global_key[notename])
1130
+ oct = octave_to_lilypond_quotes(octave)
1131
+ if acc != UNDEF and (acc == global_key[notename] or acc == bar_acc):
1132
+ mod = '!'
1133
+ else:
1134
+ mod = ''
1135
+ voices_append("%s%s%s%s" %
1136
+ (pit, oct, mod,
1137
+ duration_to_lilypond_duration((num, den), default_len, current_dots)))
1138
+
1139
+ set_bar_acc(notename, octave, acc, parser_state)
1140
+ if parser_state.next_articulation:
1141
+ articulation = articulation + parser_state.next_articulation
1142
+ parser_state.next_articulation = ''
1143
+
1144
+ voices_append(articulation)
1145
+
1146
+ if slur_begin:
1147
+ voices_append('-(' * slur_begin)
1148
+ if slur_end:
1149
+ voices_append('-)' * slur_end)
1150
+
1151
+ if parser_state.parsing_tuplet:
1152
+ parser_state.parsing_tuplet = parser_state.parsing_tuplet - 1
1153
+ if not parser_state.parsing_tuplet:
1154
+ voices_append("}")
1155
+
1156
+ if global_options.beams and \
1157
+ s[0] in '^=_ABCDEFGabcdefg' and \
1158
+ not parser_state.parsing_beam and \
1159
+ not parser_state.parsing_tuplet:
1160
+ parser_state.parsing_beam = 1
1161
+ voices_append_back('[')
1162
+
1163
+ return s
1164
+
1165
+
1166
+ def junk_space(s, state):
1167
+ while s and s[0] in '\t\n\r ':
1168
+ s = s[1:]
1169
+ close_beam_state(state)
1170
+
1171
+ return s
1172
+
1173
+
1174
+ def try_parse_guitar_chord(s, state):
1175
+ if s[:1] == '"':
1176
+ s = s[1:]
1177
+ gc = ''
1178
+ if s[0] == '_' or (s[0] == '^'):
1179
+ position = s[0]
1180
+ s = s[1:]
1181
+ else:
1182
+ position = '^'
1183
+ while s and s[0] != '"':
1184
+ gc = gc + s[0]
1185
+ s = s[1:]
1186
+
1187
+ if s:
1188
+ s = s[1:]
1189
+ gc = re.sub('#', '\\#', gc) # escape '#'s
1190
+ state.next_articulation = ("%c\"%s\"" % (position, gc)) \
1191
+ + state.next_articulation
1192
+ return s
1193
+
1194
+
1195
+ def try_parse_escape(s):
1196
+ if not s or s[0] != '\\':
1197
+ return s
1198
+
1199
+ s = s[1:]
1200
+ if s[:1] == 'K':
1201
+ key_table = compute_key()
1202
+ return s
1203
+
1204
+
1205
+ #
1206
+ # |] thin-thick double bar line
1207
+ # || thin-thin double bar line
1208
+ # [| thick-thin double bar line
1209
+ # :| left repeat
1210
+ # |: right repeat
1211
+ # :: left-right repeat
1212
+ # |1 volta 1
1213
+ # |2 volta 2
1214
+ old_bar_dict = {
1215
+ '|]': '|.',
1216
+ '||': '||',
1217
+ '[|': '||',
1218
+ ':|': ':|.',
1219
+ '|:': '|:',
1220
+ '::': ':|.|:',
1221
+ '|1': '|',
1222
+ '|2': '|',
1223
+ ':|2': ':|.',
1224
+ '|': '|'
1225
+ }
1226
+ bar_dict = {
1227
+ '|]': '\\bar "|."',
1228
+ '||': '\\bar "||"',
1229
+ '[|': '\\bar "||"',
1230
+ ':|': '}',
1231
+ '|:': '\\repeat volta 2 {',
1232
+ '::': '} \\repeat volta 2 {',
1233
+ '|1': '} \\alternative{{',
1234
+ '|2': '} {',
1235
+ ':|2': '} {',
1236
+ '|': '\\bar "|"'
1237
+ }
1238
+
1239
+
1240
+ warn_about = ['|:', '::', ':|', '|1', ':|2', '|2']
1241
+ alternative_opener = ['|1', '|2', ':|2']
1242
+ repeat_ender = ['::', ':|']
1243
+ repeat_opener = ['::', '|:']
1244
+ in_repeat = [''] * 8
1245
+ doing_alternative = [''] * 8
1246
+ using_old = ''
1247
+
1248
+ def try_parse_bar(string, state):
1249
+ global in_repeat, doing_alternative, using_old
1250
+ do_curly = ''
1251
+ bs = None
1252
+ if current_voice_idx < 0:
1253
+ select_voice('default', '')
1254
+ # first try the longer one
1255
+ for trylen in [3, 2, 1]:
1256
+ if string[:trylen] and string[:trylen] in bar_dict:
1257
+ s = string[:trylen]
1258
+ if using_old:
1259
+ bs = "\\bar \"%s\"" % old_bar_dict[s]
1260
+ else:
1261
+ bs = "%s" % bar_dict[s]
1262
+ string = string[trylen:]
1263
+ if s in alternative_opener:
1264
+ if not in_repeat[current_voice_idx]:
1265
+ using_old = 't'
1266
+ bs = "\\bar \"%s\"" % old_bar_dict[s]
1267
+ else:
1268
+ doing_alternative[current_voice_idx] = 't'
1269
+
1270
+ if s in repeat_ender:
1271
+ if not in_repeat[current_voice_idx]:
1272
+ sys.stderr.write(
1273
+ "Warning: inserting repeat to beginning of notes.\n")
1274
+ repeat_prepend()
1275
+ in_repeat[current_voice_idx] = ''
1276
+ else:
1277
+ if doing_alternative[current_voice_idx]:
1278
+ do_curly = 't'
1279
+ if using_old:
1280
+ bs = "\\bar \"%s\"" % old_bar_dict[s]
1281
+ else:
1282
+ bs = bar_dict[s]
1283
+ doing_alternative[current_voice_idx] = ''
1284
+ in_repeat[current_voice_idx] = ''
1285
+ if s in repeat_opener:
1286
+ in_repeat[current_voice_idx] = 't'
1287
+ if using_old:
1288
+ bs = "\\bar \"%s\"" % old_bar_dict[s]
1289
+ else:
1290
+ bs = bar_dict[s]
1291
+ break
1292
+ if string[:1] == '|':
1293
+ state.next_bar = '|\n'
1294
+ string = string[1:]
1295
+ clear_bar_acc(state)
1296
+ close_beam_state(state)
1297
+
1298
+ if string[:1] == '}':
1299
+ close_beam_state(state)
1300
+
1301
+ if bs is not None or state.next_bar != '':
1302
+ if state.parsing_tuplet:
1303
+ state.parsing_tuplet = 0
1304
+ voices_append('} ')
1305
+
1306
+ if bs is not None:
1307
+ clear_bar_acc(state)
1308
+ close_beam_state(state)
1309
+ voices_append(bs)
1310
+ if do_curly != '':
1311
+ voices_append("} ")
1312
+ do_curly = ''
1313
+ return string
1314
+
1315
+
1316
+ def try_parse_tie(s):
1317
+ if s[:1] == '-':
1318
+ s = s[1:]
1319
+ voices_append(' ~ ')
1320
+ return s
1321
+
1322
+
1323
+ def bracket_escape(s, state):
1324
+ m = re.match(r'^([^\]]*)] *(.*)$', s)
1325
+ if m:
1326
+ cmd = m.group(1)
1327
+ s = m.group(2)
1328
+ try_parse_header_line(cmd, state)
1329
+ return s
1330
+
1331
+
1332
+ def try_parse_chord_delims(s, state):
1333
+ if s[:1] == '[':
1334
+ s = s[1:]
1335
+ if re.match('[A-Z]:', s): # bracket escape
1336
+ return bracket_escape(s, state)
1337
+ if state.next_bar:
1338
+ voices_append(state.next_bar)
1339
+ state.next_bar = ''
1340
+ voices_append('<<')
1341
+
1342
+ if s[:1] == '+':
1343
+ s = s[1:]
1344
+ if state.plus_chord:
1345
+ voices_append('>>')
1346
+ state.plus_chord = 0
1347
+ else:
1348
+ if state.next_bar:
1349
+ voices_append(state.next_bar)
1350
+ state.next_bar = ''
1351
+ voices_append('<<')
1352
+ state.plus_chord = 1
1353
+
1354
+ ch = ''
1355
+ if s[:1] == ']':
1356
+ s = s[1:]
1357
+ ch = '>>'
1358
+
1359
+ end = 0
1360
+ while s[:1] == ')':
1361
+ end = end + 1
1362
+ s = s[1:]
1363
+
1364
+ voices_append("\\spanrequest \\stop \"slur\"" * end)
1365
+ voices_append(ch)
1366
+ return s
1367
+
1368
+
1369
+ def try_parse_grace_delims(s, state):
1370
+ if s[:1] == '{':
1371
+ if state.next_bar:
1372
+ voices_append(state.next_bar)
1373
+ state.next_bar = ''
1374
+ s = s[1:]
1375
+ voices_append('\\grace { ')
1376
+
1377
+ if s[:1] == '}':
1378
+ s = s[1:]
1379
+ voices_append('}')
1380
+
1381
+ return s
1382
+
1383
+
1384
+ def try_parse_comment(s):
1385
+ global nobarlines
1386
+ if s[0] == '%':
1387
+ if s[0:5] == '%MIDI':
1388
+ # the nobarlines option is necessary for an abc to lilypond translator for
1389
+ # exactly the same reason abc2midi needs it: abc requires the user to enter
1390
+ # the note that will be printed, and MIDI and lilypond expect entry of the
1391
+ # pitch that will be played.
1392
+ #
1393
+ # In standard 19th century musical notation, the algorithm for translating
1394
+ # between printed note and pitch involves using the barlines to determine
1395
+ # the scope of the accidentals.
1396
+ #
1397
+ # Since ABC is frequently used for music in styles that do not use this
1398
+ # convention, such as most music written before 1700, or ethnic music in
1399
+ # non-western scales, it is necessary to be able to tell a translator that
1400
+ # the barlines should not affect its interpretation of the pitch.
1401
+ if 'nobarlines' in s:
1402
+ nobarlines = 1
1403
+ elif s[0:3] == '%LY':
1404
+ p = s.find('voices')
1405
+ if p > -1:
1406
+ voices_append(s[p+7:])
1407
+ voices_append("\n")
1408
+ p = s.find('slyrics')
1409
+ if p > -1:
1410
+ slyrics_append(s[p+8:])
1411
+
1412
+ # write other kinds of appending if we ever need them.
1413
+ return s
1414
+
1415
+
1416
+ lineno = 0
1417
+ happy_count = 100
1418
+
1419
+
1420
+ def parse_file(fn):
1421
+ f = open(fn, encoding='utf-8')
1422
+ ls = f.readlines()
1423
+ ls = [re.sub("\r$", '', x) for x in ls]
1424
+
1425
+ select_voice('default', '')
1426
+ global lineno
1427
+ lineno = 0
1428
+ if not global_options.quiet:
1429
+ sys.stderr.write("Line ... ")
1430
+ sys.stderr.flush()
1431
+ __main__.state = state_list[current_voice_idx]
1432
+
1433
+ for ln in ls:
1434
+ lineno = lineno + 1
1435
+
1436
+ if not lineno % happy_count:
1437
+ sys.stderr.write('[%d]' % lineno)
1438
+ sys.stderr.flush()
1439
+ m = re.match('^([^%]*)%(.*)$', ln) # add comments to current voice
1440
+ if m:
1441
+ if m.group(2):
1442
+ try_parse_comment(m.group(2))
1443
+ voices_append('%% %s\n' % m.group(2))
1444
+ ln = m.group(1)
1445
+
1446
+ orig_ln = ln
1447
+
1448
+ ln = junk_space(ln, state)
1449
+ ln = try_parse_header_line(ln, state)
1450
+
1451
+ # Try nibbling characters off until the line doesn't change.
1452
+ prev_ln = ''
1453
+ while ln != prev_ln:
1454
+ prev_ln = ln
1455
+ ln = try_parse_chord_delims(ln, state)
1456
+ ln = try_parse_rest(ln, state)
1457
+ ln = try_parse_articulation(ln, state)
1458
+ ln = try_parse_note(ln, state)
1459
+ ln = try_parse_bar(ln, state)
1460
+ ln = try_parse_tie(ln)
1461
+ ln = try_parse_escape(ln)
1462
+ ln = try_parse_guitar_chord(ln, state)
1463
+ ln = try_parse_tuplet_begin(ln, state)
1464
+ ln = try_parse_group_end(ln, state)
1465
+ ln = try_parse_grace_delims(ln, state)
1466
+ ln = junk_space(ln, state)
1467
+
1468
+ if ln:
1469
+ error("%s: %d: Huh? Don't understand\n" % (fn, lineno))
1470
+ left = orig_ln[0:-len(ln)]
1471
+ sys.stderr.write(left + '\n')
1472
+ sys.stderr.write(' ' * len(left) + ln + '\n')
1473
+
1474
+
1475
+ def identify():
1476
+ if not global_options.quiet:
1477
+ sys.stderr.write("%s from LilyPond %s\n" % (ly.program_name, version))
1478
+
1479
+
1480
+ authors = """
1481
+ Written by Han-Wen Nienhuys <[email protected]>, Laura Conrad
1482
+ <[email protected]>, Roy Rankin <Roy.Rankin@@alcatel.com.au>.
1483
+ """
1484
+
1485
+
1486
+ def print_version():
1487
+ print(r"""abc2ly (GNU lilypond) %s""" % version)
1488
+
1489
+
1490
+ def get_option_parser():
1491
+ p = ly.get_option_parser(usage=_("%s [OPTION]... FILE") % 'abc2ly',
1492
+ description=_('''abc2ly converts ABC music files (see
1493
+ %s) to LilyPond input.
1494
+ ''') % 'http://abcnotation.com/abc2mtex/abc.txt',
1495
+ add_help_option=False)
1496
+
1497
+ p.version = "abc2ly (LilyPond) 2.24.2"
1498
+ p.add_option("--version",
1499
+ action="version",
1500
+ help=_("show version number and exit"))
1501
+ p.add_option("-h", "--help",
1502
+ action="help",
1503
+ help=_("show this help and exit"))
1504
+ p.add_option("-o", "--output", metavar='FILE',
1505
+ action="store",
1506
+ help=_("write output to FILE"))
1507
+ p.add_option("-s", "--strict",
1508
+ action="store_true",
1509
+ help=_("be strict about success"))
1510
+ p.add_option('-b', '--beams',
1511
+ action="store_true",
1512
+ help=_("preserve ABC's notion of beams"))
1513
+ p.add_option('-q', '--quiet',
1514
+ action="store_true",
1515
+ help=_("suppress progress messages"))
1516
+ p.add_option_group('',
1517
+ description=(
1518
+ _('Report bugs via %s')
1519
+ % '[email protected]') + '\n')
1520
+ return p
1521
+
1522
+
1523
+ option_parser = get_option_parser()
1524
+ (global_options, files) = option_parser.parse_args()
1525
+
1526
+
1527
+ identify()
1528
+
1529
+ header['tagline'] = 'Lily was here %s -- automatically converted from ABC' % version
1530
+ for f in files:
1531
+ if f == '-':
1532
+ f = ''
1533
+
1534
+ if not global_options.quiet:
1535
+ sys.stderr.write('Parsing `%s\'...\n' % f)
1536
+ parse_file(f)
1537
+
1538
+ if not global_options.output:
1539
+ global_options.output = os.path.basename(
1540
+ os.path.splitext(f)[0]) + ".ly"
1541
+ if not global_options.quiet:
1542
+ sys.stderr.write('lilypond output to: `%s\'...' %
1543
+ global_options.output)
1544
+ outf = open(global_options.output, 'w', encoding='utf-8')
1545
+
1546
+ # don't substitute @VERSION@. We want this to reflect
1547
+ # the last version that was verified to work.
1548
+ outf.write('\\version "2.7.40"\n')
1549
+
1550
+ # dump_global (outf)
1551
+ dump_header(outf, header)
1552
+ dump_slyrics(outf)
1553
+ dump_voices(outf)
1554
+ dump_score(outf)
1555
+ dump_lyrics(outf)
1556
+ if not global_options.quiet:
1557
+ sys.stderr.write('\n')
lilypond-2.24.2/bin/convert-ly.py ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+
3
+ # convert-ly.py -- Update old LilyPond input files (fix name?)
4
+ # converting rules are found in python/convertrules.py
5
+
6
+ # This file is part of LilyPond, the GNU music typesetter.
7
+ #
8
+ # Copyright (C) 1998--2022 Han-Wen Nienhuys <[email protected]>
9
+ # Jan Nieuwenhuizen <[email protected]>
10
+ #
11
+ # LilyPond is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # LilyPond is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ import gettext
25
+ import io
26
+ import os
27
+ import re
28
+ import shutil
29
+ import sys
30
+
31
+ """
32
+
33
+ # relocate-preamble.py.in
34
+ #
35
+ # This file is part of LilyPond, the GNU music typesetter.
36
+ #
37
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
38
+ #
39
+ # LilyPond is free software: you can redistribute it and/or modify
40
+ # it under the terms of the GNU General Public License as published by
41
+ # the Free Software Foundation, either version 3 of the License, or
42
+ # (at your option) any later version.
43
+ #
44
+ # LilyPond is distributed in the hope that it will be useful,
45
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47
+ # GNU General Public License for more details.
48
+ #
49
+ # You should have received a copy of the GNU General Public License
50
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
51
+ #
52
+
53
+ This is generic code, used for all python scripts.
54
+
55
+ The quotes are to ensure that the source .py file can still be
56
+ run as a python script, but does not include any sys.path handling.
57
+ Otherwise, the lilypond-book calls inside the build
58
+ might modify installed .pyc files.
59
+
60
+ """
61
+
62
+ # This is needed for installations with a non-default layout, ie where share/
63
+ # is not next to bin/.
64
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
65
+
66
+ # Dynamic relocation, for installations with a default layout including GUB,
67
+ # but also for execution from the build directory.
68
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
69
+ topdir = os.path.dirname (bindir)
70
+ if bindir.endswith (r'/scripts/out'):
71
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
72
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
73
+ for v in [ 'current', '2.24.2' ]:
74
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
75
+
76
+ """
77
+ """
78
+
79
+ # Load translation and install _() into Python's builtins namespace.
80
+ gettext.install('lilypond', '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale')
81
+
82
+ import convertrules
83
+ import lilylib as ly
84
+
85
+ lilypond_version_re_str = '\\\\version *\"([0-9.]+)"'
86
+ lilypond_version_re = re.compile(lilypond_version_re_str)
87
+
88
+ lilypond_version_strict_re_str = '\\\\version *\"([0-9]+(?:[.]([0-9]+))([.][0-9]+)?)"'
89
+ lilypond_version_strict_re = re.compile(lilypond_version_strict_re_str)
90
+
91
+ help_summary = (
92
+ _('''Update LilyPond input to newer version. By default, update from the
93
+ version taken from the \\version command, to the current LilyPond version.''')
94
+ + "\n"
95
+ + _("If FILE is `-', read from standard input.")
96
+ + "\n\n"
97
+ + _("Examples:")
98
+ + '''
99
+ $ convert-ly -e old.ly
100
+ $ convert-ly --from=2.3.28 --to=2.5.21 foobar.ly > foobar-new.ly
101
+ ''')
102
+
103
+ copyright = ('Jan Nieuwenhuizen <[email protected]>',
104
+ 'Han-Wen Nienhuys <[email protected]>')
105
+
106
+ program_version = '2.24.2'
107
+
108
+ authors = ('Jan Nieuwenhuizen <[email protected]>',
109
+ 'Han-Wen Nienhuys <[email protected]>')
110
+
111
+
112
+ def identify():
113
+ ly.progress('%s (GNU LilyPond) %s\n' % (ly.program_name, program_version))
114
+
115
+
116
+ def warranty():
117
+ identify()
118
+ sys.stdout.write('''
119
+ %s
120
+
121
+ %s
122
+
123
+ %s
124
+ %s
125
+ ''' % (_('Copyright (c) %s by') % '2001--2023',
126
+ ' '.join(authors),
127
+ _('Distributed under terms of the GNU General Public License.'),
128
+ _('It comes with NO WARRANTY.')))
129
+
130
+
131
+ def get_option_parser():
132
+ p = ly.get_option_parser(usage=_("%s [OPTION]... FILE") % 'convert-ly',
133
+ description=help_summary,
134
+ add_help_option=False)
135
+
136
+ p.version = "2.24.2"
137
+ p.add_option("--version",
138
+ action="version",
139
+ help=_("show version number and exit"))
140
+
141
+ p.add_option("-h", "--help",
142
+ action="help",
143
+ help=_("show this help and exit"))
144
+
145
+ p.add_option('-f', '--from',
146
+ action="store",
147
+ metavar=_("VERSION"),
148
+ dest="from_version",
149
+ help=_(
150
+ "start from VERSION [default: \\version found in file]"),
151
+ default='')
152
+
153
+ p.add_option('-e', '--edit', help=_("edit in place"),
154
+ action='store_true')
155
+
156
+ p.add_option("-l", "--loglevel",
157
+ help=_("Print log messages according to LOGLEVEL "
158
+ "(NONE, ERROR, WARNING, PROGRESS (default), DEBUG)"),
159
+ metavar=_("LOGLEVEL"),
160
+ action='callback',
161
+ callback=ly.handle_loglevel_option,
162
+ type='string')
163
+
164
+ p.add_option('-n', '--no-version',
165
+ help=_("do not add \\version command if missing"),
166
+ action='store_true',
167
+ dest='skip_version_add',
168
+ default=False)
169
+
170
+ p.add_option('-c', '--current-version',
171
+ help=_("force updating \\version number to %s") % program_version,
172
+ action='store_true',
173
+ dest='force_current_version',
174
+ default=False)
175
+
176
+ p.add_option('-d', '--diff-version-update',
177
+ help=_("only update \\version number if file is modified"),
178
+ action='store_true',
179
+ dest='diff_version_update',
180
+ default=False)
181
+
182
+ p.add_option("-s", '--show-rules',
183
+ help=_("show rules [default: -f 0, -t %s]") % program_version,
184
+ dest='show_rules',
185
+ action='store_true', default=False)
186
+
187
+ p.add_option('-t', '--to',
188
+ help=_("convert to VERSION [default: %s]") % program_version,
189
+ metavar=_('VERSION'),
190
+ action='store',
191
+ dest="to_version",
192
+ default='')
193
+
194
+ p.add_option('-b', '--backup-numbered',
195
+ help=_("make a numbered backup [default: filename.ext~]"),
196
+ action='store_true',
197
+ dest="backup_numbered",
198
+ default='')
199
+
200
+ p.add_option('-w', '--warranty', help=_("show warranty and copyright"),
201
+ action='store_true',
202
+ ),
203
+ p.add_option_group('',
204
+ description=(
205
+ _("Report bugs via %s")
206
+ % '[email protected]') + '\n')
207
+
208
+ return p
209
+
210
+
211
+ def str_to_tuple(s):
212
+ return tuple([int(n) for n in s.split('.')])
213
+
214
+ def tup_to_str(t):
215
+ return '.'.join(['%s' % x for x in t])
216
+
217
+ def latest_version():
218
+ return convertrules.conversions[-1][0]
219
+
220
+
221
+ def show_rules(file, from_version, to_version):
222
+ for x in convertrules.conversions:
223
+ if (not from_version or x[0] > from_version) \
224
+ and (not to_version or x[0] <= to_version):
225
+ file.write('%s: %s\n' % (tup_to_str(x[0]), x[2]))
226
+
227
+ def do_conversion(s, from_version, to_version):
228
+ """Apply conversions from FROM_VERSION to TO_VERSION. Return
229
+ tuple (LAST,LASTCHANGED,STR,ERRORS), with the last applied conversion,
230
+ the last conversion resulting in a change, the resulting
231
+ string and the number of errors."""
232
+ conv_list = [conv for conv in convertrules.conversions if from_version < conv[0] <= to_version]
233
+
234
+ ly.progress(_("Applying conversion: "), newline=False)
235
+
236
+ last_conversion = None
237
+ last_change = None
238
+ errors = 0
239
+ try:
240
+ for x in conv_list:
241
+ if x != conv_list[-1]:
242
+ ly.progress(tup_to_str(x[0]), newline=False)
243
+ ly.progress(', ', newline=False)
244
+ else:
245
+ ly.progress(tup_to_str(x[0]))
246
+ newstr = x[1](s)
247
+ last_conversion = x[0]
248
+ if newstr != s:
249
+ last_change = last_conversion
250
+ s = newstr
251
+
252
+ except convertrules.FatalConversionError:
253
+ ly.error(_("Error while converting")
254
+ + '\n'
255
+ + _("Stopping at last successful rule"))
256
+ errors += 1
257
+
258
+ return (last_conversion, last_change, s, errors)
259
+
260
+
261
+ def guess_lilypond_version(input):
262
+ m = lilypond_version_strict_re.search(input)
263
+ # Accept a missing third component if the second component
264
+ # is even. That works because we don't have conversion rules
265
+ # within stable releases, as the syntax doesn't change.
266
+ if m and (m.group(3) is not None or int(m.group(2))%2 == 0):
267
+ return m.group(1)
268
+ m = lilypond_version_re.search(input)
269
+ if m:
270
+ raise InvalidVersion(m.group(1))
271
+ else:
272
+ return ''
273
+
274
+
275
+ class FatalConversionError (Exception):
276
+ pass
277
+
278
+
279
+ class UnknownVersion (Exception):
280
+ pass
281
+
282
+
283
+ class InvalidVersion (Exception):
284
+ def __init__(self, version):
285
+ self.version = version
286
+
287
+
288
+ def back_up(file, numbered):
289
+ if numbered:
290
+ n = 0
291
+ while True:
292
+ n = n + 1
293
+ back_up = file + '.~' + str(n) + '~'
294
+ if not os.path.exists(back_up):
295
+ break
296
+ else:
297
+ back_up = file + '~'
298
+ shutil.copy2(file, back_up)
299
+ return back_up
300
+
301
+
302
+ def do_one_file(infile_name):
303
+ ly.progress(_("Processing `%s\'... ") % infile_name, True)
304
+
305
+ if infile_name:
306
+ infile = open(infile_name, 'rb')
307
+ original = infile.read()
308
+ infile.close()
309
+
310
+ # Cope early with encoding change in 2.5.13: Try UTF-8 and attempt
311
+ # conversion from latin1 if that fails.
312
+ try:
313
+ input = original.decode('utf-8')
314
+ except UnicodeError:
315
+ ly.progress(_("Attempting conversion from `latin1'..."))
316
+ input = original.decode('latin1')
317
+
318
+ # Convert platform-dependent newline character sequences
319
+ # to `\n`. This is default behaviour when opening files in
320
+ # text mode, which does not work for us, though, since we do not
321
+ # know the encoding in advance.
322
+ input = io.StringIO(input, newline=None).read()
323
+ else:
324
+ input = sys.stdin.read()
325
+
326
+ to_version = None
327
+ org_version = None
328
+ guess = guess_lilypond_version(input)
329
+ org_version = guess and str_to_tuple(guess)
330
+ from_version = global_options.from_version or org_version
331
+ if not from_version:
332
+ raise UnknownVersion()
333
+
334
+ if global_options.to_version:
335
+ to_version = global_options.to_version
336
+ else:
337
+ to_version = latest_version()
338
+
339
+ (last, last_change, result, errors) = \
340
+ do_conversion(input, from_version, to_version)
341
+
342
+ if global_options.force_current_version and \
343
+ (last is None or last == to_version):
344
+ last = str_to_tuple(program_version)
345
+ if last:
346
+ if global_options.diff_version_update:
347
+ # Note that last_change can be set even if the result is
348
+ # the same if two conversion rules cancelled out
349
+ if result == input:
350
+ # make no (actual) change to the version number
351
+ last = org_version or from_version
352
+ else:
353
+ last = last_change
354
+ # If the last update was to an unstable version
355
+ # number, and the final update target is no longer in
356
+ # the same unstable series, we update to the stable
357
+ # series following the unstable version.
358
+ if last[1] % 2: # unstable
359
+ next_stable = (last[0], last[1]+1, 0)
360
+ if next_stable <= to_version:
361
+ last = next_stable
362
+
363
+ newversion = r'\version "%s"' % tup_to_str(last)
364
+ if lilypond_version_re.search(result):
365
+ result = re.sub(lilypond_version_re_str,
366
+ '\\' + newversion, result)
367
+ elif not global_options.skip_version_add:
368
+ result = newversion + '\n' + result
369
+
370
+ ly.progress('\n')
371
+
372
+ if global_options.edit:
373
+ backup = back_up(infile_name, global_options.backup_numbered)
374
+ outfile = open(infile_name, 'w', encoding='utf-8')
375
+ else:
376
+ outfile = sys.stdout
377
+
378
+ outfile.write(result)
379
+
380
+ sys.stderr.flush()
381
+
382
+ return errors
383
+
384
+
385
+ def do_options():
386
+ opt_parser = get_option_parser()
387
+ (options, args) = opt_parser.parse_args()
388
+
389
+ if options.warranty:
390
+ warranty()
391
+ sys.exit(0)
392
+
393
+ if options.from_version:
394
+ options.from_version = str_to_tuple(options.from_version)
395
+ if options.to_version:
396
+ options.to_version = str_to_tuple(options.to_version)
397
+
398
+ options.outfile_name = ''
399
+ global global_options
400
+ global_options = options
401
+
402
+ if not args and not options.show_rules:
403
+ opt_parser.print_help()
404
+ sys.exit(2)
405
+
406
+ return args
407
+
408
+
409
+ def main():
410
+ files = do_options()
411
+
412
+ # should parse files[] to read \version?
413
+ if global_options.show_rules:
414
+ show_rules(sys.stdout, global_options.from_version,
415
+ global_options.to_version)
416
+ sys.exit(0)
417
+
418
+ identify()
419
+
420
+ errors = 0
421
+ for f in files:
422
+ if f == '-':
423
+ f = ''
424
+ elif not os.path.isfile(f):
425
+ ly.error(_("%s: Unable to open file") % f)
426
+ errors += 1
427
+ continue
428
+ try:
429
+ errors += do_one_file(f)
430
+ except UnknownVersion:
431
+ ly.error(_("%s: Unable to determine version. Skipping") % f)
432
+ errors += 1
433
+ except InvalidVersion as v:
434
+ ly.error(_("%s: Invalid version string `%s' \n"
435
+ "Valid version strings consist of three numbers, "
436
+ "separated by dots, e.g. `2.8.12'") % (f, v.version))
437
+ errors += 1
438
+
439
+ if errors:
440
+ ly.warning(gettext.ngettext("There was %d error.",
441
+ "There were %d errors.", errors) % errors)
442
+ sys.exit(1)
443
+
444
+
445
+ main()
lilypond-2.24.2/bin/etf2ly.py ADDED
@@ -0,0 +1,1326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+
3
+ # This file is part of LilyPond, the GNU music typesetter.
4
+ #
5
+ # Copyright (C) 2001--2022 Han-Wen Nienhuys <[email protected]>
6
+ # Jan Nieuwenhuizen <[email protected]>
7
+ #
8
+ # LilyPond is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # LilyPond is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ # info mostly taken from looking at files. See also
22
+ # https://www.gnu.org/software/lilypond/src/Developers/Details/etfformat.html
23
+
24
+ # This supports
25
+ #
26
+ # * notes
27
+ # * rests
28
+ # * ties
29
+ # * slurs
30
+ # * lyrics
31
+ # * articulation
32
+ # * grace notes
33
+ # * tuplets
34
+ #
35
+
36
+ # todo:
37
+ # * slur/stem directions
38
+ # * voices (2nd half of frame?)
39
+ # * more intelligent lyrics
40
+ # * beams (better use autobeam?)
41
+ # * more robust: try entertainer.etf (freenote)
42
+ # * dynamics
43
+ # * empty measures (eg. twopt03.etf from freenote)
44
+ #
45
+
46
+
47
+ import __main__
48
+ import getopt
49
+ import gettext
50
+ import os
51
+ import re
52
+ import sys
53
+
54
+ authors = ('Jan Nieuwenhuizen <[email protected]>',
55
+ 'Han-Wen Nienhuys <[email protected]>')
56
+
57
+ version = '2.24.2'
58
+ if version == '@' + 'TOPLEVEL_VERSION' + '@':
59
+ version = '(unknown version)' # uGUHGUHGHGUGH
60
+
61
+ """
62
+
63
+ # relocate-preamble.py.in
64
+ #
65
+ # This file is part of LilyPond, the GNU music typesetter.
66
+ #
67
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
68
+ #
69
+ # LilyPond is free software: you can redistribute it and/or modify
70
+ # it under the terms of the GNU General Public License as published by
71
+ # the Free Software Foundation, either version 3 of the License, or
72
+ # (at your option) any later version.
73
+ #
74
+ # LilyPond is distributed in the hope that it will be useful,
75
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
76
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77
+ # GNU General Public License for more details.
78
+ #
79
+ # You should have received a copy of the GNU General Public License
80
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
81
+ #
82
+
83
+ This is generic code, used for all python scripts.
84
+
85
+ The quotes are to ensure that the source .py file can still be
86
+ run as a python script, but does not include any sys.path handling.
87
+ Otherwise, the lilypond-book calls inside the build
88
+ might modify installed .pyc files.
89
+
90
+ """
91
+
92
+ # This is needed for installations with a non-default layout, ie where share/
93
+ # is not next to bin/.
94
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
95
+
96
+ # Dynamic relocation, for installations with a default layout including GUB,
97
+ # but also for execution from the build directory.
98
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
99
+ topdir = os.path.dirname (bindir)
100
+ if bindir.endswith (r'/scripts/out'):
101
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
102
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
103
+ for v in [ 'current', '2.24.2' ]:
104
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
105
+
106
+ """
107
+ """
108
+
109
+ ################################################################
110
+ # Load translation and install _() into Python's builtins namespace.
111
+ gettext.install('lilypond', '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale')
112
+
113
+ import lilylib as ly
114
+
115
+ finale_clefs = ['treble', 'alto', 'tenor', 'bass',
116
+ 'percussion', 'treble_8', 'bass_8', 'baritone']
117
+
118
+
119
+ def lily_clef(fin):
120
+ try:
121
+ return finale_clefs[fin]
122
+ except IndexError:
123
+ sys.stderr.write('\nHuh? Found clef number %d\n' % fin)
124
+
125
+ return 'treble'
126
+
127
+
128
+ def gulp_file(f):
129
+ return open(f, encoding='utf-8').read()
130
+
131
+
132
+ # notename 0 == central C
133
+ distances = [0, 2, 4, 5, 7, 9, 11, 12]
134
+
135
+
136
+ def semitones(name, acc):
137
+ return (name / 7) * 12 + distances[name % 7] + acc
138
+
139
+ # represent pitches as (notename, alteration), relative to C-major scale
140
+
141
+
142
+ def transpose(orig, delta):
143
+ (oname, oacc) = orig
144
+ (dname, dacc) = delta
145
+
146
+ old_pitch = semitones(oname, oacc)
147
+ delta_pitch = semitones(dname, dacc)
148
+ nname = (oname + dname)
149
+ nacc = oacc
150
+ new_pitch = semitones(nname, nacc)
151
+
152
+ nacc = nacc - (new_pitch - old_pitch - delta_pitch)
153
+
154
+ return (nname, nacc)
155
+
156
+
157
+ def interpret_finale_key_sig(finale_id):
158
+ """
159
+ find the transposition of C-major scale that belongs here.
160
+
161
+ we are not going to insert the correct major/minor, we only want to
162
+ have the correct number of accidentals
163
+ """
164
+
165
+ p = (0, 0)
166
+
167
+ bank_number = finale_id >> 8
168
+ accidental_bits = finale_id & 0xff
169
+
170
+ if 0 <= accidental_bits < 7:
171
+ while accidental_bits > 0:
172
+ p = transpose(p, (4, 0)) # a fifth up
173
+ accidental_bits = accidental_bits - 1
174
+ elif 248 < accidental_bits <= 255:
175
+ while accidental_bits < 256:
176
+ p = transpose(p, (3, 0))
177
+ accidental_bits = accidental_bits + 1
178
+
179
+ if bank_number == 1:
180
+ # minor scale
181
+ p = transpose(p, (5, 0))
182
+ p = (p[0] % 7, p[1])
183
+
184
+ return KeySignature(p, bank_number)
185
+
186
+ # should cache this.
187
+
188
+
189
+ def find_scale(keysig):
190
+ cscale = [(x, 0) for x in range(0, 7)]
191
+ # print "cscale: ", cscale
192
+ ascale = [(x, 0) for x in range(-2, 5)]
193
+ # print "ascale: ", ascale
194
+ transposition = keysig.pitch
195
+ if keysig.sig_type == 1:
196
+ transposition = transpose(transposition, (2, -1))
197
+ transposition = (transposition[0] % 7, transposition[1])
198
+ trscale = list(map(lambda x, k=transposition: transpose(x, k), ascale))
199
+ else:
200
+ trscale = list(map(lambda x, k=transposition: transpose(x, k), cscale))
201
+ # print "trscale: ", trscale
202
+ return trscale
203
+
204
+
205
+ def EDU_to_duration(edu):
206
+ log = 1
207
+ d = 4096
208
+ while d > edu:
209
+ d = d >> 1
210
+ log = log << 1
211
+
212
+ edu = edu - d
213
+ dots = 0
214
+ if edu == d / 2:
215
+ dots = 1
216
+ elif edu == d*3/4:
217
+ dots = 2
218
+ return (log, dots)
219
+
220
+
221
+ def rational_to_lily_skip(rat):
222
+ (n, d) = rat
223
+
224
+ basedur = 1
225
+ while d and d % 2 == 0:
226
+ basedur = basedur << 1
227
+ d = d >> 1
228
+
229
+ str = 's%d' % basedur
230
+ if n != 1:
231
+ str = str + '*%d' % n
232
+ if d != 1:
233
+ str = str + '/%d' % d
234
+
235
+ return str
236
+
237
+
238
+ def gcd(a, b):
239
+ if b == 0:
240
+ return a
241
+ c = a
242
+ while c:
243
+ c = a % b
244
+ a = b
245
+ b = c
246
+ return a
247
+
248
+
249
+ def rat_simplify(r):
250
+ (n, d) = r
251
+ if d < 0:
252
+ d = -d
253
+ n = -n
254
+ if n == 0:
255
+ return (0, 1)
256
+ else:
257
+ g = gcd(n, d)
258
+ return (n/g, d/g)
259
+
260
+
261
+ def rat_multiply(a, b):
262
+ (x, y) = a
263
+ (p, q) = b
264
+
265
+ return rat_simplify((x*p, y*q))
266
+
267
+
268
+ def rat_add(a, b):
269
+ (x, y) = a
270
+ (p, q) = b
271
+
272
+ return rat_simplify((x*q + p*y, y*q))
273
+
274
+
275
+ def rat_neg(a):
276
+ (p, q) = a
277
+ return (-p, q)
278
+
279
+
280
+ def rat_subtract(a, b):
281
+ return rat_add(a, rat_neg(b))
282
+
283
+
284
+ def lily_notename(tuple2):
285
+ (n, a) = tuple2
286
+ nn = chr((n + 2) % 7 + ord('a'))
287
+
288
+ return nn + {-2: 'eses', -1: 'es', 0: '', 1: 'is', 2: 'isis'}[a]
289
+
290
+
291
+ class Tuplet:
292
+ def __init__(self, number):
293
+ self.start_note = number
294
+ self.finale = []
295
+
296
+ def append_finale(self, fin):
297
+ self.finale.append(fin)
298
+
299
+ def factor(self):
300
+ n = self.finale[0][2]*self.finale[0][3]
301
+ d = self.finale[0][0]*self.finale[0][1]
302
+ return rat_simplify((n, d))
303
+
304
+ def dump_start(self):
305
+ return '\\times %d/%d { ' % self.factor()
306
+
307
+ def dump_end(self):
308
+ return ' }'
309
+
310
+ def calculate(self, chords):
311
+ edu_left = self.finale[0][0] * self.finale[0][1]
312
+
313
+ startch = chords[self.start_note]
314
+ c = startch
315
+ while c and edu_left:
316
+ c.tuplet = self
317
+ if c == startch:
318
+ c.chord_prefix = self.dump_start() + c.chord_prefix
319
+
320
+ if not c.grace:
321
+ edu_left = edu_left - c.EDU_duration()
322
+ if edu_left == 0:
323
+ c.chord_suffix = c.chord_suffix + self.dump_end()
324
+ c = c.__next__
325
+
326
+ if edu_left:
327
+ sys.stderr.write(
328
+ "\nHuh? Tuplet starting at entry %d was too short." % self.start_note)
329
+
330
+
331
+ class Slur:
332
+ def __init__(self, number, params):
333
+ self.number = number
334
+ self.finale = params
335
+
336
+ def append_entry(self, finale_e):
337
+ self.finale.append(finale_e)
338
+
339
+ def calculate(self, chords):
340
+ startnote = self.finale[5]
341
+ endnote = self.finale[3*6 + 2]
342
+ try:
343
+ cs = chords[startnote]
344
+ ce = chords[endnote]
345
+
346
+ if not cs or not ce:
347
+ raise IndexError
348
+
349
+ cs.note_suffix = '-(' + cs.note_suffix
350
+ ce.note_suffix = ce.note_suffix + '-)'
351
+
352
+ except IndexError:
353
+ sys.stderr.write("""\nHuh? Slur no %d between (%d,%d), with %d notes""" % (
354
+ self.number, startnote, endnote, len(chords)))
355
+
356
+
357
+ class Global_measure:
358
+ def __init__(self, number):
359
+ self.timesig = ''
360
+ self.number = number
361
+ self.key_signature = None
362
+ self.scale = None
363
+ self.force_break = 0
364
+
365
+ self.repeats = []
366
+ self.finale = []
367
+
368
+ def __str__(self):
369
+ return repr(self.finale)
370
+
371
+ def set_timesig(self, finale):
372
+ (beats, fdur) = finale
373
+ (log, dots) = EDU_to_duration(fdur)
374
+
375
+ if dots == 1:
376
+ beats = beats * 3
377
+ log = log * 2
378
+ dots = 0
379
+
380
+ if dots != 0:
381
+ sys.stderr.write(
382
+ "\nHuh? Beat duration has dots? (EDU Duration = %d)" % fdur)
383
+ self.timesig = (beats, log)
384
+
385
+ def length(self):
386
+ return self.timesig
387
+
388
+ def set_key_sig(self, finale):
389
+ k = interpret_finale_key_sig(finale)
390
+ self.key_signature = k
391
+ self.scale = find_scale(k)
392
+
393
+ def set_flags(self, flag1, flag2):
394
+
395
+ # flag1 isn't all that interesting.
396
+ if flag2 & 0x8000:
397
+ self.force_break = 1
398
+
399
+ if flag2 & 0x0008:
400
+ self.repeats.append('start')
401
+ if flag2 & 0x0004:
402
+ self.repeats.append('stop')
403
+
404
+ if flag2 & 0x0002:
405
+ if flag2 & 0x0004:
406
+ self.repeats.append('bracket')
407
+
408
+
409
+ articulation_dict = {
410
+ 94: '^',
411
+ 109: '\\prall',
412
+ 84: '\\turn',
413
+ 62: '\\mordent',
414
+ 85: '\\fermata',
415
+ 46: '.',
416
+ # 3: '>',
417
+ # 18: '\arpeggio' ,
418
+ }
419
+
420
+
421
+ class Articulation_def:
422
+ def __init__(self, n, a, b):
423
+ self.finale_glyph = a & 0xff
424
+ self.number = n
425
+
426
+ def dump(self):
427
+ try:
428
+ return articulation_dict[self.finale_glyph]
429
+ except KeyError:
430
+ sys.stderr.write("\nUnknown articulation no. %d" %
431
+ self.finale_glyph)
432
+ sys.stderr.write(
433
+ "\nPlease add an entry to articulation_dict in the Python source")
434
+ return None
435
+
436
+
437
+ class Articulation:
438
+ def __init__(self, a, b, finale):
439
+ self.definition = finale[0]
440
+ self.notenumber = b
441
+
442
+ def calculate(self, chords, defs):
443
+ c = chords[self.notenumber]
444
+
445
+ adef = defs[self.definition]
446
+ lystr = adef.dump()
447
+ if lystr is None:
448
+ lystr = '"art"'
449
+ sys.stderr.write("\nThis happened on note %d" % self.notenumber)
450
+
451
+ c.note_suffix = '-' + lystr
452
+
453
+
454
+ class Syllable:
455
+ def __init__(self, a, b, finale):
456
+ self.chordnum = b
457
+ self.syllable = finale[1]
458
+ self.verse = finale[0]
459
+
460
+ def calculate(self, chords, lyrics):
461
+ self.chord = chords[self.chordnum]
462
+
463
+
464
+ class Verse:
465
+ def __init__(self, number, body):
466
+ self.body = body
467
+ self.number = number
468
+ self.split_syllables()
469
+
470
+ def split_syllables(self):
471
+ ss = re.split('(-| +)', self.body)
472
+
473
+ sep = 0
474
+ syls = [None]
475
+ for s in ss:
476
+ if sep:
477
+ septor = re.sub(" +", "", s)
478
+ septor = re.sub("-", " -- ", septor)
479
+ syls[-1] = syls[-1] + septor
480
+ else:
481
+ syls.append(s)
482
+
483
+ sep = not sep
484
+
485
+ self.syllables = syls
486
+
487
+ def dump(self):
488
+ str = ''
489
+ line = ''
490
+ for s in self.syllables[1:]:
491
+ line = line + ' ' + s
492
+ if len(line) > 72:
493
+ str = str + ' ' * 4 + line + '\n'
494
+ line = ''
495
+
496
+ str = """\nverse%s = \\lyricmode {\n %s }\n""" % (
497
+ encodeint(self.number - 1), str)
498
+ return str
499
+
500
+
501
+ class KeySignature:
502
+ def __init__(self, pitch, sig_type=0):
503
+ self.pitch = pitch
504
+ self.sig_type = sig_type
505
+
506
+ def signature_type(self):
507
+ if self.sig_type == 1:
508
+ return "\\minor"
509
+ else:
510
+ # really only for 0, but we only know about 0 and 1
511
+ return "\\major"
512
+
513
+ def equal(self, other):
514
+ if other and other.pitch == self.pitch and other.sig_type == self.sig_type:
515
+ return 1
516
+ else:
517
+ return 0
518
+
519
+
520
+ class Measure:
521
+ def __init__(self, no):
522
+ self.number = no
523
+ self.frames = [0] * 4
524
+ self.flags = 0
525
+ self.clef = 0
526
+ self.finale = []
527
+ self.global_measure = None
528
+ self.staff = None
529
+ self.valid = 1
530
+
531
+ def valid(self):
532
+ return self.valid
533
+
534
+ def calculate(self):
535
+ fs = []
536
+
537
+ if len(self.finale) < 2:
538
+ fs = self.finale[0]
539
+
540
+ self.clef = fs[1]
541
+ self.frames = [fs[0]]
542
+ else:
543
+ fs = self.finale
544
+ self.clef = fs[0]
545
+ self.flags = fs[1]
546
+ self.frames = fs[2:]
547
+
548
+
549
+ class Frame:
550
+ def __init__(self, finale):
551
+ self.measure = None
552
+ self.finale = finale
553
+ (number, start, end) = finale
554
+ self.number = number
555
+ self.start = start
556
+ self.end = end
557
+ self.chords = []
558
+
559
+ def set_measure(self, m):
560
+ self.measure = m
561
+
562
+ def calculate(self):
563
+
564
+ # do grace notes.
565
+ lastch = None
566
+ in_grace = 0
567
+ for c in self.chords:
568
+ if c.grace and (lastch is None or (not lastch.grace)):
569
+ c.chord_prefix = r'\grace {' + c.chord_prefix
570
+ in_grace = 1
571
+ elif not c.grace and lastch and lastch.grace:
572
+ lastch.chord_suffix = lastch.chord_suffix + ' } '
573
+ in_grace = 0
574
+
575
+ lastch = c
576
+
577
+ if lastch and in_grace:
578
+ lastch.chord_suffix += '}'
579
+
580
+ def dump(self):
581
+ str = '%% FR(%d)\n' % self.number
582
+ left = self.measure.global_measure.length()
583
+
584
+ ln = ''
585
+ for c in self.chords:
586
+ add = c.ly_string() + ' '
587
+ if len(ln) + len(add) > 72:
588
+ str = str + ln + '\n'
589
+ ln = ''
590
+ ln = ln + add
591
+ left = rat_subtract(left, c.length())
592
+
593
+ str = str + ln
594
+
595
+ if left[0] < 0:
596
+ sys.stderr.write("""\nHuh? Going backwards in frame no %d, start/end (%d,%d)""" %
597
+ (self.number, self.start, self.end))
598
+ left = (0, 1)
599
+ if left[0]:
600
+ str = str + rational_to_lily_skip(left)
601
+
602
+ str = str + ' |\n'
603
+ return str
604
+
605
+
606
+ def encodeint(i):
607
+ return chr(i + ord('A'))
608
+
609
+
610
+ class Staff:
611
+ def __init__(self, number):
612
+ self.number = number
613
+ self.measures = []
614
+
615
+ def get_measure(self, no):
616
+ fill_list_to(self.measures, no)
617
+
618
+ if self.measures[no] is None:
619
+ m = Measure(no)
620
+ self.measures[no] = m
621
+ m.staff = self
622
+
623
+ return self.measures[no]
624
+
625
+ def staffid(self):
626
+ return 'staff' + encodeint(self.number - 1)
627
+
628
+ def layerid(self, l):
629
+ return self.staffid() + 'layer%s' % chr(l - 1 + ord('A'))
630
+
631
+ def dump_time_key_sigs(self):
632
+ k = ''
633
+ last_key = None
634
+ last_time = None
635
+ last_clef = None
636
+ gap = (0, 1)
637
+ for m in self.measures[1:]:
638
+ if not m or not m.valid:
639
+ continue # ugh.
640
+
641
+ g = m.global_measure
642
+ e = ''
643
+
644
+ if g:
645
+ if g.key_signature and not g.key_signature.equal(last_key):
646
+ pitch = g.key_signature.pitch
647
+ e = e + "\\key %s %s " % (lily_notename(pitch),
648
+ g.key_signature.signature_type())
649
+
650
+ last_key = g.key_signature
651
+ if last_time != g.timesig:
652
+ e = e + "\\time %d/%d " % g.timesig
653
+ last_time = g.timesig
654
+
655
+ if 'start' in g.repeats:
656
+ e = e + ' \\bar ".|:" '
657
+
658
+ # we don't attempt voltas since they fail easily.
659
+ if 0: # and g.repeat_bar == '|:' or g.repeat_bar == ':|:' or g.bracket:
660
+ strs = []
661
+ if g.repeat_bar == '|:' or g.repeat_bar == ':|:' or g.bracket == 'end':
662
+ strs.append('#f')
663
+
664
+ if g.bracket == 'start':
665
+ strs.append('"0."')
666
+
667
+ str = ' '.join(['(volta %s)' % x for x in strs])
668
+
669
+ e = e + ' \\set Score.repeatCommands = #\'(%s) ' % str
670
+
671
+ if g.force_break:
672
+ e = e + ' \\break '
673
+
674
+ if last_clef != m.clef:
675
+ e = e + '\\clef "%s"' % lily_clef(m.clef)
676
+ last_clef = m.clef
677
+ if e:
678
+ if gap != (0, 1):
679
+ k = k + ' ' + rational_to_lily_skip(gap) + '\n'
680
+ gap = (0, 1)
681
+ k = k + e
682
+
683
+ if g:
684
+ gap = rat_add(gap, g.length())
685
+ if 'stop' in g.repeats:
686
+ k = k + ' \\bar ":|." '
687
+
688
+ k = '%sglobal = { %s }\n\n ' % (self.staffid(), k)
689
+ return k
690
+
691
+ def dump(self):
692
+ str = ''
693
+
694
+ layerids = []
695
+ for x in range(1, 5): # 4 layers.
696
+ laystr = ''
697
+ last_frame = None
698
+ first_frame = None
699
+ gap = (0, 1)
700
+ for m in self.measures[1:]:
701
+ if not m or not m.valid:
702
+ sys.stderr.write(
703
+ "Skipping non-existant or invalid measure\n")
704
+ continue
705
+
706
+ fr = None
707
+ try:
708
+ fr = m.frames[x]
709
+ except IndexError:
710
+ sys.stderr.write("Skipping nonexistent frame %d\n" % x)
711
+ laystr = laystr + \
712
+ "%% non existent frame %d (skipped)\n" % x
713
+ if fr:
714
+ first_frame = fr
715
+ if gap != (0, 1):
716
+ laystr = laystr + \
717
+ '} %s {\n ' % rational_to_lily_skip(gap)
718
+ gap = (0, 1)
719
+ laystr = laystr + fr.dump()
720
+ else:
721
+ if m.global_measure:
722
+ gap = rat_add(gap, m.global_measure.length())
723
+ else:
724
+ sys.stderr.write(
725
+ "No global measure for staff %d measure %d\n"
726
+ % (self.number, m.number))
727
+ if first_frame:
728
+ l = self.layerid(x)
729
+ laystr = '%s = { { %s } }\n\n' % (l, laystr)
730
+ str = str + laystr
731
+ layerids.append(l)
732
+
733
+ str = str + self.dump_time_key_sigs()
734
+ stafdef = '\\%sglobal' % self.staffid()
735
+ for i in layerids:
736
+ stafdef = stafdef + ' \\' + i
737
+
738
+ str = str + '%s = \\context Staff = %s <<\n %s\n >>\n' % \
739
+ (self.staffid(), self.staffid(), stafdef)
740
+ return str
741
+
742
+
743
+ def ziplist(l):
744
+ if len(l) < 2:
745
+ return []
746
+ else:
747
+ return [(l[0], l[1])] + ziplist(l[2:])
748
+
749
+
750
+ class Chord:
751
+ def __init__(self, number, contents):
752
+ self.pitches = []
753
+ self.frame = None
754
+ self.finale = contents[:7]
755
+
756
+ self.notelist = ziplist(contents[7:])
757
+ self.duration = None
758
+ self.next = None
759
+ self.prev = None
760
+ self.number = number
761
+ self.note_prefix = ''
762
+ self.note_suffix = ''
763
+ self.chord_suffix = ''
764
+ self.chord_prefix = ''
765
+ self.tuplet = None
766
+ self.grace = 0
767
+
768
+ def measure(self):
769
+ if not self.frame:
770
+ return None
771
+ return self.frame.measure
772
+
773
+ def length(self):
774
+ if self.grace:
775
+ return (0, 1)
776
+
777
+ l = (1, self.duration[0])
778
+
779
+ d = 1 << self.duration[1]
780
+
781
+ dotfact = rat_subtract((2, 1), (1, d))
782
+ mylen = rat_multiply(dotfact, l)
783
+
784
+ if self.tuplet:
785
+ mylen = rat_multiply(mylen, self.tuplet.factor())
786
+ return mylen
787
+
788
+ def EDU_duration(self):
789
+ return self.finale[2]
790
+
791
+ def set_duration(self):
792
+ self.duration = EDU_to_duration(self.EDU_duration())
793
+
794
+ def calculate(self):
795
+ self.find_realpitch()
796
+ self.set_duration()
797
+
798
+ flag = self.finale[4]
799
+ if Chord.GRACE_MASK & flag:
800
+ self.grace = 1
801
+
802
+ def find_realpitch(self):
803
+
804
+ meas = self.measure()
805
+ tiestart = 0
806
+ if not meas or not meas.global_measure:
807
+ sys.stderr.write('note %d not in measure\n' % self.number)
808
+ elif not meas.global_measure.scale:
809
+ sys.stderr.write(
810
+ 'note %d: no scale in this measure.' % self.number)
811
+ else:
812
+
813
+ for p in self.notelist:
814
+ (pitch, flag) = p
815
+
816
+ nib1 = pitch & 0x0f
817
+
818
+ if nib1 > 8:
819
+ nib1 = -(nib1 - 8)
820
+ rest = pitch / 16
821
+
822
+ scale = meas.global_measure.scale
823
+ (sn, sa) = scale[rest % 7]
824
+ sn = sn + (rest - (rest % 7)) + 7
825
+ acc = sa + nib1
826
+ self.pitches.append((sn, acc))
827
+ tiestart = tiestart or (flag & Chord.TIE_START_MASK)
828
+ if tiestart:
829
+ self.chord_suffix = self.chord_suffix + ' ~ '
830
+
831
+ REST_MASK = 0x40000000
832
+ TIE_START_MASK = 0x40000000
833
+ GRACE_MASK = 0x00800000
834
+
835
+ def ly_string(self):
836
+ s = ''
837
+
838
+ rest = ''
839
+
840
+ if not (self.finale[4] & Chord.REST_MASK):
841
+ rest = 'r'
842
+
843
+ for p in self.pitches:
844
+ (n, a) = p
845
+ o = n / 7
846
+ n = n % 7
847
+
848
+ nn = lily_notename((n, a))
849
+
850
+ if o < 0:
851
+ nn = nn + (',' * -o)
852
+ elif o > 0:
853
+ nn = nn + ('\'' * o)
854
+
855
+ if s:
856
+ s = s + ' '
857
+
858
+ if rest:
859
+ nn = rest
860
+
861
+ s = s + nn
862
+
863
+ if not self.pitches:
864
+ s = 'r'
865
+ if len(self.pitches) > 1:
866
+ s = '<%s>' % s
867
+
868
+ s = s + '%d%s' % (self.duration[0], '.' * self.duration[1])
869
+ s = self.note_prefix + s + self.note_suffix
870
+
871
+ s = self.chord_prefix + s + self.chord_suffix
872
+
873
+ return s
874
+
875
+
876
+ def fill_list_to(list, no):
877
+ """
878
+ Add None to LIST until it contains entry number NO.
879
+ """
880
+ while len(list) <= no:
881
+ list.extend([None] * (no - len(list) + 1))
882
+ return list
883
+
884
+
885
+ def read_finale_value(str):
886
+ """
887
+ Pry off one value from STR. The value may be $hex, decimal, or "string".
888
+ Return: (value, rest-of-STR)
889
+ """
890
+ while str and str[0] in ' \t\n':
891
+ str = str[1:]
892
+
893
+ if not str:
894
+ return (None, str)
895
+
896
+ if str[0] == '$':
897
+ str = str[1:]
898
+
899
+ hex = ''
900
+ while str and str[0] in '0123456789ABCDEF':
901
+ hex = hex + str[0]
902
+ str = str[1:]
903
+
904
+ return (int(hex, 16), str)
905
+ elif str[0] == '"':
906
+ str = str[1:]
907
+ s = ''
908
+ while str and str[0] != '"':
909
+ s = s + str[0]
910
+ str = str[1:]
911
+
912
+ return (s, str)
913
+ elif str[0] in '-0123456789':
914
+ dec = ''
915
+ while str and str[0] in '-0123456789':
916
+ dec = dec + str[0]
917
+ str = str[1:]
918
+
919
+ return (int(dec), str)
920
+ else:
921
+ sys.stderr.write("cannot convert `%s'\n" % str)
922
+ return (None, str)
923
+
924
+
925
+ def parse_etf_file(fn, tag_dict):
926
+ """ Read FN, putting ETF info into
927
+ a giant dictionary. The keys of TAG_DICT indicate which tags
928
+ to put into the dict.
929
+ """
930
+
931
+ sys.stderr.write('parsing ... ')
932
+ f = open(fn, encoding='utf-8')
933
+
934
+ gulp = re.sub('[\n\r]+', '\n', f.read())
935
+ ls = gulp.split('\n^')
936
+
937
+ etf_file_dict = {}
938
+ for k in tag_dict:
939
+ etf_file_dict[k] = {}
940
+
941
+ last_tag = None
942
+ last_numbers = None
943
+
944
+ for l in ls:
945
+ m = re.match(r'^([a-zA-Z0-9&]+)\(([^)]+)\)', l)
946
+ if m and m.group(1) in tag_dict:
947
+ tag = m.group(1)
948
+
949
+ indices = tuple([int(s) for s in m.group(2).split(',')])
950
+ content = l[m.end(2)+1:]
951
+
952
+ tdict = etf_file_dict[tag]
953
+ if indices not in tdict:
954
+ tdict[indices] = []
955
+
956
+ parsed = []
957
+
958
+ if tag == 'verse' or tag == 'block':
959
+ m2 = re.match(r'(.*)\^end', content)
960
+ if m2:
961
+ parsed = [m2.group(1)]
962
+ else:
963
+ while content:
964
+ (v, content) = read_finale_value(content)
965
+ if v is not None:
966
+ parsed.append(v)
967
+
968
+ tdict[indices].extend(parsed)
969
+
970
+ last_indices = indices
971
+ last_tag = tag
972
+
973
+ continue
974
+
975
+ # let's not do this: this really confuses when eE happens to be before a ^text.
976
+ # if last_tag and last_indices:
977
+ # etf_file_dict[last_tag][last_indices].append (l)
978
+
979
+ sys.stderr.write('\n')
980
+ return etf_file_dict
981
+
982
+
983
+ class Etf_file:
984
+ def __init__(self, name):
985
+ self.measures = [None]
986
+ self.chords = [None]
987
+ self.frames = [None]
988
+ self.tuplets = [None]
989
+ self.staffs = [None]
990
+ self.slurs = [None]
991
+ self.articulations = [None]
992
+ self.syllables = [None]
993
+ self.verses = [None]
994
+ self.articulation_defs = [None]
995
+
996
+ # do it
997
+ self.parse(name)
998
+
999
+ def get_global_measure(self, no):
1000
+ fill_list_to(self.measures, no)
1001
+ if self.measures[no] is None:
1002
+ self.measures[no] = Global_measure(no)
1003
+
1004
+ return self.measures[no]
1005
+
1006
+ def get_staff(self, staffno):
1007
+ fill_list_to(self.staffs, staffno)
1008
+ if self.staffs[staffno] is None:
1009
+ self.staffs[staffno] = Staff(staffno)
1010
+
1011
+ return self.staffs[staffno]
1012
+
1013
+ # staff-spec
1014
+ def try_IS(self, indices, contents):
1015
+ pass
1016
+
1017
+ def try_BC(self, indices, contents):
1018
+ bn = indices[0]
1019
+ where = contents[0] / 1024.0
1020
+
1021
+ def try_TP(self, indices, contents):
1022
+ (nil, num) = indices
1023
+
1024
+ if self.tuplets[-1] is None or num != self.tuplets[-1].start_note:
1025
+ self.tuplets.append(Tuplet(num))
1026
+
1027
+ self.tuplets[-1].append_finale(contents)
1028
+
1029
+ def try_IM(self, indices, contents):
1030
+ (a, b) = indices
1031
+ fin = contents
1032
+ self.articulations.append(Articulation(a, b, fin))
1033
+
1034
+ def try_verse(self, indices, contents):
1035
+ a = indices[0]
1036
+ body = contents[0]
1037
+
1038
+ body = re.sub(r"""\^[a-z]+\([^)]+\)""", "", body)
1039
+ body = re.sub(r"\^[a-z]+", "", body)
1040
+ self.verses.append(Verse(a, body))
1041
+
1042
+ def try_ve(self, indices, contents):
1043
+ (a, b) = indices
1044
+ self.syllables.append(Syllable(a, b, contents))
1045
+
1046
+ def try_eE(self, indices, contents):
1047
+ no = indices[0]
1048
+ (prev, next, dur, pos, entryflag, extended, follow) = contents[:7]
1049
+
1050
+ fill_list_to(self.chords, no)
1051
+ self.chords[no] = Chord(no, contents)
1052
+
1053
+ def try_Sx(self, indices, contents):
1054
+ slurno = indices[0]
1055
+ fill_list_to(self.slurs, slurno)
1056
+ self.slurs[slurno] = Slur(slurno, contents)
1057
+
1058
+ def try_IX(self, indices, contents):
1059
+ n = indices[0]
1060
+ a = contents[0]
1061
+ b = contents[1]
1062
+
1063
+ ix = None
1064
+ try:
1065
+ ix = self.articulation_defs[n]
1066
+ except IndexError:
1067
+ ix = Articulation_def(n, a, b)
1068
+ self.articulation_defs.append(Articulation_def(n, a, b))
1069
+
1070
+ def try_GF(self, indices, contents):
1071
+ (staffno, measno) = indices
1072
+
1073
+ st = self.get_staff(staffno)
1074
+ meas = st.get_measure(measno)
1075
+ meas.finale = contents
1076
+
1077
+ def try_FR(self, indices, contents):
1078
+ frameno = indices[0]
1079
+
1080
+ startnote = contents[0]
1081
+ endnote = contents[1]
1082
+
1083
+ fill_list_to(self.frames, frameno)
1084
+
1085
+ self.frames[frameno] = Frame((frameno, startnote, endnote))
1086
+
1087
+ def try_MS(self, indices, contents):
1088
+ measno = indices[0]
1089
+ keynum = contents[1]
1090
+ meas = self. get_global_measure(measno)
1091
+
1092
+ meas.set_key_sig(keynum)
1093
+
1094
+ beats = contents[2]
1095
+ beatlen = contents[3]
1096
+ meas.set_timesig((beats, beatlen))
1097
+
1098
+ meas_flag1 = contents[4]
1099
+ meas_flag2 = contents[5]
1100
+
1101
+ meas.set_flags(meas_flag1, meas_flag2)
1102
+
1103
+ routine_dict = {
1104
+ 'MS': try_MS,
1105
+ 'FR': try_FR,
1106
+ 'GF': try_GF,
1107
+ 'IX': try_IX,
1108
+ 'Sx': try_Sx,
1109
+ 'eE': try_eE,
1110
+ 'verse': try_verse,
1111
+ 've': try_ve,
1112
+ 'IM': try_IM,
1113
+ 'TP': try_TP,
1114
+ 'BC': try_BC,
1115
+ 'IS': try_IS,
1116
+ }
1117
+
1118
+ def parse(self, etf_dict):
1119
+ sys.stderr.write('reconstructing ...')
1120
+ sys.stderr.flush()
1121
+
1122
+ for (tag, routine) in list(Etf_file.routine_dict.items()):
1123
+ ks = list(etf_dict[tag].keys())
1124
+ ks.sort()
1125
+ for k in ks:
1126
+ routine(self, k, etf_dict[tag][k])
1127
+
1128
+ sys.stderr.write('processing ...')
1129
+ sys.stderr.flush()
1130
+
1131
+ self.unthread_entries()
1132
+
1133
+ for st in self.staffs[1:]:
1134
+ if not st:
1135
+ continue
1136
+ mno = 1
1137
+ for m in st.measures[1:]:
1138
+ if not m:
1139
+ continue
1140
+
1141
+ m.calculate()
1142
+ try:
1143
+ m.global_measure = self.measures[mno]
1144
+ except IndexError:
1145
+ sys.stderr.write("Non-existent global measure %d" % mno)
1146
+ continue
1147
+
1148
+ frame_obj_list = [None]
1149
+ for frno in m.frames:
1150
+ try:
1151
+ fr = self.frames[frno]
1152
+ frame_obj_list.append(fr)
1153
+ except IndexError:
1154
+ sys.stderr.write("\nNon-existent frame %d" % frno)
1155
+
1156
+ m.frames = frame_obj_list
1157
+ for fr in frame_obj_list[1:]:
1158
+ if not fr:
1159
+ continue
1160
+
1161
+ fr.set_measure(m)
1162
+
1163
+ fr.chords = self.get_thread(fr.start, fr.end)
1164
+ for c in fr.chords:
1165
+ c.frame = fr
1166
+ mno = mno + 1
1167
+
1168
+ for c in self.chords[1:]:
1169
+ if c:
1170
+ c.calculate()
1171
+
1172
+ for f in self.frames[1:]:
1173
+ if f:
1174
+ f.calculate()
1175
+
1176
+ for t in self.tuplets[1:]:
1177
+ t.calculate(self.chords)
1178
+
1179
+ for s in self.slurs[1:]:
1180
+ if s:
1181
+ s.calculate(self.chords)
1182
+
1183
+ for s in self.articulations[1:]:
1184
+ s.calculate(self.chords, self.articulation_defs)
1185
+
1186
+ def get_thread(self, startno, endno):
1187
+
1188
+ thread = []
1189
+
1190
+ c = None
1191
+ try:
1192
+ c = self.chords[startno]
1193
+ except IndexError:
1194
+ sys.stderr.write(
1195
+ "Huh? Frame has invalid bounds (%d,%d)\n" % (startno, endno))
1196
+ return []
1197
+
1198
+ while c and c.number != endno:
1199
+ d = c # hack to avoid problem with scripts/build/grand-replace.py
1200
+ thread.append(d)
1201
+ c = c.__next__
1202
+
1203
+ if c:
1204
+ d = c # hack to avoid problem with scripts/build/grand-replace.py
1205
+ thread.append(d)
1206
+
1207
+ return thread
1208
+
1209
+ def dump(self):
1210
+ str = ''
1211
+ staffs = []
1212
+ for s in self.staffs[1:]:
1213
+ if s:
1214
+ str = str + '\n\n' + s.dump()
1215
+ staffs.append('\\' + s.staffid())
1216
+
1217
+ # should use \addlyrics ?
1218
+
1219
+ for v in self.verses[1:]:
1220
+ str = str + v.dump()
1221
+
1222
+ if len(self.verses) > 1:
1223
+ sys.stderr.write(
1224
+ "\nLyrics found; edit to use \\addlyrics to couple to a staff\n")
1225
+
1226
+ if staffs:
1227
+ str += '\\version "2.3.25"\n'
1228
+ str = str + '<<\n %s\n>> } ' % ' '.join(staffs)
1229
+
1230
+ return str
1231
+
1232
+ def __str__(self):
1233
+ return 'ETF FILE %s %s' % (self.measures, self.entries)
1234
+
1235
+ def unthread_entries(self):
1236
+ for e in self.chords[1:]:
1237
+ if not e:
1238
+ continue
1239
+
1240
+ e.prev = self.chords[e.finale[0]]
1241
+ e.next = self.chords[e.finale[1]]
1242
+
1243
+
1244
+ def identify():
1245
+ sys.stderr.write("%s from LilyPond %s\n" % (ly.program_name, version))
1246
+
1247
+
1248
+ def warranty():
1249
+ identify()
1250
+ sys.stdout.write('''
1251
+ %s
1252
+
1253
+ %s
1254
+
1255
+ %s
1256
+ %s
1257
+ ''' % (_('Copyright (c) %s by') % '2001--2023',
1258
+ '\n '.join(authors),
1259
+ _('Distributed under terms of the GNU General Public License.'),
1260
+ _('It comes with NO WARRANTY.')))
1261
+
1262
+
1263
+ def get_option_parser():
1264
+ p = ly.get_option_parser(usage=_("%s [OPTION]... ETF-FILE") % 'etf2ly',
1265
+ description=_("""Enigma Transport Format is a format used by Coda Music Technology's
1266
+ Finale product. etf2ly converts a subset of ETF to a ready-to-use LilyPond file.
1267
+ """),
1268
+ add_help_option=False)
1269
+ p.add_option("-h", "--help",
1270
+ action="help",
1271
+ help=_("show this help and exit"))
1272
+ p.version = "etf2ly (LilyPond) 2.24.2"
1273
+ p.add_option("--version",
1274
+ action="version",
1275
+ help=_("show version number and exit"))
1276
+ p.add_option('-o', '--output', help=_("write output to FILE"),
1277
+ metavar=_("FILE"),
1278
+ action='store')
1279
+ p.add_option('-w', '--warranty', help=_("show warranty and copyright"),
1280
+ action='store_true',
1281
+ ),
1282
+
1283
+ p.add_option_group('',
1284
+ description=(
1285
+ _('Report bugs via %s')
1286
+ % '[email protected]') + '\n')
1287
+ return p
1288
+
1289
+
1290
+ def do_options():
1291
+ opt_parser = get_option_parser()
1292
+ (options, args) = opt_parser.parse_args()
1293
+ if options.warranty:
1294
+ warranty()
1295
+ sys.exit(0)
1296
+
1297
+ return (options, args)
1298
+
1299
+
1300
+ (options, files) = do_options()
1301
+ identify()
1302
+
1303
+ out_filename = options.output
1304
+
1305
+ e = None
1306
+ for f in files:
1307
+ if f == '-':
1308
+ f = ''
1309
+
1310
+ sys.stderr.write('Processing `%s\'\n' % f)
1311
+
1312
+ dict = parse_etf_file(f, Etf_file.routine_dict)
1313
+ e = Etf_file(dict)
1314
+ if not out_filename:
1315
+ out_filename = os.path.basename(re.sub('(?i).etf$', '.ly', f))
1316
+
1317
+ if out_filename == f:
1318
+ out_filename = os.path.basename(f + '.ly')
1319
+
1320
+ sys.stderr.write('Writing `%s\'' % out_filename)
1321
+ ly = e.dump()
1322
+
1323
+ fo = open(out_filename, 'w', encoding='utf-8')
1324
+ fo.write('%% lily was here -- automatically converted by etf2ly from %s\n' % f)
1325
+ fo.write(ly)
1326
+ fo.close()
lilypond-2.24.2/bin/gspawn-win64-helper-console.exe ADDED
Binary file (21.5 kB). View file
 
lilypond-2.24.2/bin/libgio-2.0-0.dll ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:16b31008c66821844d6724b81026f8be75d5e25fe52c4489f48ea014a2963eca
3
+ size 1873408
lilypond-2.24.2/bin/libglib-2.0-0.dll ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:176680ef7e5e080f726cf86f7e776a0c13c3fd79f2acd1c11a98f78f6c4264cc
3
+ size 1611264
lilypond-2.24.2/bin/libgmodule-2.0-0.dll ADDED
Binary file (24.1 kB). View file
 
lilypond-2.24.2/bin/libgobject-2.0-0.dll ADDED
Binary file (383 kB). View file
 
lilypond-2.24.2/bin/libintl-8.dll ADDED
Binary file (101 kB). View file
 
lilypond-2.24.2/bin/lilymidi.py ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+
3
+ # Copyright (C) 2006--2022 Brailcom, o.p.s.
4
+ #
5
+ # Author: Milan Zamazal <[email protected]>
6
+ #
7
+ # This file is part of LilyPond, the GNU music typesetter.
8
+ #
9
+ # LilyPond is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # LilyPond is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ import optparse
23
+ import os
24
+ import sys
25
+
26
+ """
27
+
28
+ # relocate-preamble.py.in
29
+ #
30
+ # This file is part of LilyPond, the GNU music typesetter.
31
+ #
32
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
33
+ #
34
+ # LilyPond is free software: you can redistribute it and/or modify
35
+ # it under the terms of the GNU General Public License as published by
36
+ # the Free Software Foundation, either version 3 of the License, or
37
+ # (at your option) any later version.
38
+ #
39
+ # LilyPond is distributed in the hope that it will be useful,
40
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
41
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42
+ # GNU General Public License for more details.
43
+ #
44
+ # You should have received a copy of the GNU General Public License
45
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
46
+ #
47
+
48
+ This is generic code, used for all python scripts.
49
+
50
+ The quotes are to ensure that the source .py file can still be
51
+ run as a python script, but does not include any sys.path handling.
52
+ Otherwise, the lilypond-book calls inside the build
53
+ might modify installed .pyc files.
54
+
55
+ """
56
+
57
+ # This is needed for installations with a non-default layout, ie where share/
58
+ # is not next to bin/.
59
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
60
+
61
+ # Dynamic relocation, for installations with a default layout including GUB,
62
+ # but also for execution from the build directory.
63
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
64
+ topdir = os.path.dirname (bindir)
65
+ if bindir.endswith (r'/scripts/out'):
66
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
67
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
68
+ for v in [ 'current', '2.24.2' ]:
69
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
70
+
71
+ """
72
+ """
73
+
74
+
75
+ def process_options(args):
76
+ parser = optparse.OptionParser(version="2.24.2")
77
+ parser.add_option('', '--filter-tracks', metavar='REGEXP', action='store', type='string', dest='regexp',
78
+ help="display only tracks numbers, of those track names matching REGEXP")
79
+ parser.add_option('', '--prefix-tracks', metavar='PREFIX', action='store', type='string', dest='prefix',
80
+ help="prefix filtered track numbers with PREFIX")
81
+ parser.add_option('', '--dump', action='store_true', dest='dump',
82
+ help="just dump parsed contents of the MIDI file")
83
+ parser.add_option('', '--pretty', action='store_true', dest='pretty',
84
+ help="dump parsed contents of the MIDI file in human-readable form (implies --dump)")
85
+ parser.usage = parser.usage + " FILE"
86
+ options, args = parser.parse_args(args)
87
+ if len(args) != 1:
88
+ parser.print_help()
89
+ sys.exit(2)
90
+ return options, args
91
+
92
+
93
+ def read_midi(file):
94
+ import midi
95
+ return midi.parse(open(file, 'rb').read())
96
+
97
+
98
+ def track_info(data):
99
+ tracks = data[1]
100
+
101
+ def track_name(track):
102
+ name = ''
103
+ for time, event in track:
104
+ if time > 0:
105
+ break
106
+ if event[0] == 255 and event[1] == 3:
107
+ name = event[2]
108
+ break
109
+ return name
110
+ track_info = []
111
+ for i in range(len(tracks)):
112
+ track_info.append((i, track_name(tracks[i])))
113
+ return track_info
114
+
115
+
116
+ class formatter:
117
+ def __init__(self, txt=""):
118
+ self.text = txt
119
+
120
+ def format_vals(self, val1, val2=""):
121
+ return str(val1) + str(val2)
122
+
123
+ def format(self, val1, val2=""):
124
+ return self.text + self.format_vals(val1, val2)
125
+
126
+
127
+ class none_formatter (formatter):
128
+ def format_vals(self, val1, val2=""):
129
+ return ''
130
+
131
+
132
+ class meta_formatter (formatter):
133
+ def format_vals(self, val1, val2):
134
+ return str(val2)
135
+
136
+
137
+ class tempo_formatter (formatter):
138
+ def format_vals(self, val1, val2):
139
+ return str(ord(val2[0])*65536 + ord(val2[1])*256 + ord(val2[2])) \
140
+ + " msec/quarter"
141
+
142
+
143
+ class time_signature_formatter (formatter):
144
+ def format_vals(self, val1, val2=""):
145
+ from fractions import Fraction
146
+ # if there are more notated 32nd notes per midi quarter than 8,
147
+ # we display a fraction smaller than 1 as scale factor.
148
+ r = Fraction(8, ord(val2[3]))
149
+ if r == 1:
150
+ ratio = ""
151
+ else:
152
+ ratio = " *" + str(r)
153
+ return str(ord(val2[0])) + "/" + str(1 << ord(val2[1])) + ratio \
154
+ + ", metronome " + str(Fraction(ord(val2[2]), 96))
155
+
156
+
157
+ class key_signature_formatter (formatter):
158
+ def format_vals(self, val1, val2):
159
+ key_names = ['F', 'C', 'G', 'D', 'A', 'E', 'B']
160
+ key = (((ord(val2[0])+128) % 256)-128) + ord(val2[1])*3 + 1
161
+ return (key_names[key % 7] + (key//7) * "is" + (-(key//7)) * "es"
162
+ + " " + ['major', 'minor'][ord(val2[1])])
163
+
164
+
165
+ class channel_formatter (formatter):
166
+ def __init__(self, txt, ch):
167
+ formatter.__init__(self, txt)
168
+ self.channel = ch
169
+
170
+ def format(self, val1, val2=""):
171
+ return self.text + "Channel " + str(self.channel) + ", " + \
172
+ self.format_vals(val1, val2)
173
+
174
+
175
+ class control_mode_formatter (formatter):
176
+ def __init__(self, txt, ch):
177
+ formatter.__init__(self, txt)
178
+ self.mode = ch
179
+
180
+ def format(self, val1, val2=""):
181
+ return self.text + str(self.mode) + ", " + \
182
+ self.format_vals(val1, val2)
183
+
184
+
185
+ class note_formatter (channel_formatter):
186
+ def pitch(self, val):
187
+ pitch_names = ['C', 'Cis', 'D', 'Dis', 'E',
188
+ 'F', 'Fis', 'G', 'Gis', 'A', 'Ais', 'B']
189
+ p = val % 12
190
+ oct = val // 12 - 1
191
+ return pitch_names[p] + str(oct) + "(" + str(val) + ")"
192
+
193
+ def velocity(self, val):
194
+ return str(val)
195
+
196
+ def format_vals(self, val1, val2):
197
+ if val2 > 0:
198
+ return self.pitch(val1) + '@' + self.velocity(val2)
199
+ return self.pitch(val1)
200
+
201
+
202
+ meta_dict = {0x00: meta_formatter("Seq.Nr.: "),
203
+ 0x01: meta_formatter("Text: "),
204
+ 0x02: meta_formatter("Copyright: "),
205
+ 0x03: meta_formatter("Track name: "),
206
+ 0x04: meta_formatter("Instrument: "),
207
+ 0x05: meta_formatter("Lyric: "),
208
+ 0x06: meta_formatter("Marker: "),
209
+ 0x07: meta_formatter("Cue point: "),
210
+ 0x2F: none_formatter("End of Track"),
211
+ 0x51: tempo_formatter("Tempo: "),
212
+ 0x54: meta_formatter("SMPTE Offs.:"),
213
+ 0x58: time_signature_formatter("Time signature: "),
214
+ 0x59: key_signature_formatter("Key signature: ")
215
+ }
216
+
217
+
218
+ def dump_event(ev, time, padding):
219
+ ch = ev[0] & 0x0F
220
+ func = ev[0] & 0xF0
221
+ f = None
222
+ if ev[0] == 0xFF:
223
+ f = meta_dict.get(ev[1], formatter())
224
+ if func == 0x80:
225
+ f = note_formatter("Note off: ", ch)
226
+ elif func == 0x90:
227
+ if ev[2] == 0:
228
+ desc = "Note off: "
229
+ else:
230
+ desc = "Note on: "
231
+ f = note_formatter(desc, ch)
232
+ elif func == 0xA0:
233
+ f = note_formatter("Polyphonic aftertouch: ",
234
+ ch, "Aftertouch pressure: ")
235
+ elif func == 0xB0:
236
+ f = control_mode_formatter("Control mode change: ", ch)
237
+ elif func == 0xC0:
238
+ f = channel_formatter("Program Change: ", ch)
239
+ elif func == 0xD0:
240
+ f = channel_formatter("Channel aftertouch: ", ch)
241
+ elif ev[0] in [0xF0, 0xF7]:
242
+ f = meta_formatter("System-exclusive event: ")
243
+
244
+ if f:
245
+ if len(ev) > 2:
246
+ print(padding + f.format(ev[1], ev[2]))
247
+ elif len(ev) > 1:
248
+ print(padding + f.format(ev[1]))
249
+ else:
250
+ print(padding + f.format())
251
+ else:
252
+ print(padding + "Unrecognized MIDI event: " + str(ev))
253
+
254
+
255
+ def dump_midi(data, midi_file, options):
256
+ if not options.pretty:
257
+ print(data)
258
+ return
259
+ # First, dump general info, #tracks, etc.
260
+ print("Filename: " + midi_file)
261
+ i = data[0]
262
+ m_formats = {0: 'single multi-channel track',
263
+ 1: "one or more simultaneous tracks",
264
+ 2: "one or more sequentially independent single-track patterns"}
265
+ print("MIDI format: " + str(i[0]) + " (" + m_formats.get(i[0], "") + ")")
266
+ print("Divisions: " + str(i[1]) + " per whole note")
267
+ print("#Tracks: " + str(len(data[1])))
268
+ n = 0
269
+ for tr in data[1]:
270
+ time = 0
271
+ n += 1
272
+ print()
273
+ print("Track " + str(n) + ":")
274
+ print(" Time 0:")
275
+ for ev in tr:
276
+ if ev[0] > time:
277
+ time = ev[0]
278
+ print(" Time " + str(time) + ": ")
279
+ dump_event(ev[1], time, " ")
280
+
281
+
282
+ def go():
283
+ options, args = process_options(sys.argv[1:])
284
+ midi_file = args[0]
285
+ midi_data = read_midi(midi_file)
286
+ info = track_info(midi_data)
287
+ if (options.dump or options.pretty):
288
+ dump_midi(midi_data, midi_file, options)
289
+ elif options.regexp:
290
+ import re
291
+ regexp = re.compile(options.regexp)
292
+ numbers = [str(n+1) for n, name in info if regexp.search(name)]
293
+ if numbers:
294
+ if options.prefix:
295
+ sys.stdout.write('%s ' % (options.prefix,))
296
+ sys.stdout.write(','.join(numbers))
297
+ sys.stdout.write('\n')
298
+ else:
299
+ for n, name in info:
300
+ sys.stdout.write('%d %s\n' % (n+1, name,))
301
+
302
+
303
+ if __name__ == '__main__':
304
+ go()
lilypond-2.24.2/bin/lilypond-book.py ADDED
@@ -0,0 +1,790 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+ # -*- coding: utf-8 -*-
3
+
4
+ # This file is part of LilyPond, the GNU music typesetter.
5
+ #
6
+ # Copyright (C) 1998--2022 Han-Wen Nienhuys <[email protected]>
7
+ # Jan Nieuwenhuizen <[email protected]>
8
+ #
9
+ # LilyPond is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # LilyPond is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ r'''
23
+ Example usage:
24
+
25
+ test:
26
+ lilypond-book --filter="tr '[a-z]' '[A-Z]'" BOOK
27
+
28
+ convert-ly on book:
29
+ lilypond-book --filter="convert-ly --no-version --from=1.6.11 -" BOOK
30
+
31
+ classic lilypond-book:
32
+ lilypond-book --process="lilypond" BOOK.tely
33
+
34
+ TODO:
35
+
36
+ * ly-options: intertext?
37
+ * --line-width?
38
+ * eps in latex / eps by lilypond -b ps?
39
+ * check latex parameters, twocolumn, multicolumn?
40
+ * use --png --ps --pdf for making images?
41
+
42
+ * Converting from lilypond-book source, substitute:
43
+ @mbinclude foo.itely -> @include foo.itely
44
+ \mbinput -> \input
45
+
46
+ '''
47
+
48
+
49
+ # TODO: Better solve the global_options copying to the snippets...
50
+
51
+ import gettext
52
+ import glob
53
+ import hashlib
54
+ from optparse import OptionGroup, SUPPRESS_HELP
55
+ import os
56
+ import re
57
+ import shlex
58
+ import stat
59
+ import subprocess
60
+ import sys
61
+ import tempfile
62
+ import typing
63
+
64
+ # See lock_path and unlock_path; this module is not available at all on Windows.
65
+ if os.name == 'posix':
66
+ import fcntl
67
+
68
+ """
69
+
70
+ # relocate-preamble.py.in
71
+ #
72
+ # This file is part of LilyPond, the GNU music typesetter.
73
+ #
74
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
75
+ #
76
+ # LilyPond is free software: you can redistribute it and/or modify
77
+ # it under the terms of the GNU General Public License as published by
78
+ # the Free Software Foundation, either version 3 of the License, or
79
+ # (at your option) any later version.
80
+ #
81
+ # LilyPond is distributed in the hope that it will be useful,
82
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
83
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84
+ # GNU General Public License for more details.
85
+ #
86
+ # You should have received a copy of the GNU General Public License
87
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
88
+ #
89
+
90
+ This is generic code, used for all python scripts.
91
+
92
+ The quotes are to ensure that the source .py file can still be
93
+ run as a python script, but does not include any sys.path handling.
94
+ Otherwise, the lilypond-book calls inside the build
95
+ might modify installed .pyc files.
96
+
97
+ """
98
+
99
+ # This is needed for installations with a non-default layout, ie where share/
100
+ # is not next to bin/.
101
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
102
+
103
+ # Dynamic relocation, for installations with a default layout including GUB,
104
+ # but also for execution from the build directory.
105
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
106
+ topdir = os.path.dirname (bindir)
107
+ if bindir.endswith (r'/scripts/out'):
108
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
109
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
110
+ for v in [ 'current', '2.24.2' ]:
111
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
112
+
113
+ """
114
+ """
115
+
116
+ import book_base
117
+ import book_docbook
118
+ import book_html
119
+ import book_latex
120
+ import book_texinfo
121
+ import book_snippets
122
+
123
+ # Load translation and install _() into Python's builtins namespace.
124
+ gettext.install('lilypond', '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale')
125
+
126
+ import lilylib as ly
127
+
128
+ backend = 'ps'
129
+
130
+ help_summary = (
131
+ _("Process LilyPond snippets in hybrid HTML, LaTeX, texinfo or DocBook document.")
132
+ + '\n\n'
133
+ + _("Examples:")
134
+ + '''
135
+ $ lilypond-book --filter="tr '[a-z]' '[A-Z]'" %(BOOK)s
136
+ $ lilypond-book -F "convert-ly --no-version --from=2.0.0 -" %(BOOK)s
137
+ $ lilypond-book --process='lilypond -I include' %(BOOK)s
138
+ ''' % {'BOOK': _("BOOK")})
139
+
140
+ authors = ('Jan Nieuwenhuizen <[email protected]>',
141
+ 'Han-Wen Nienhuys <[email protected]>')
142
+
143
+ ################################################################
144
+
145
+
146
+ def exit(i):
147
+ if ly.is_verbose():
148
+ raise Exception(_('Exiting (%d)...') % i)
149
+ else:
150
+ sys.exit(i)
151
+
152
+
153
+ progress = ly.progress
154
+ warning = ly.warning
155
+ error = ly.error
156
+
157
+ program_version = '2.24.2'
158
+ if program_version.startswith("@"):
159
+ # '@' in lilypond-book output confuses texinfo
160
+ program_version = "dev"
161
+
162
+
163
+ def identify():
164
+ progress('%s (GNU LilyPond) %s' % (ly.program_name, program_version))
165
+
166
+
167
+ def warranty():
168
+ identify()
169
+ sys.stdout.write('''
170
+ %s
171
+
172
+ %s
173
+
174
+ %s
175
+ %s
176
+ ''' % (_('Copyright (c) %s by') % '2001--2023',
177
+ '\n '.join(authors),
178
+ _("Distributed under terms of the GNU General Public License."),
179
+ _("It comes with NO WARRANTY.")))
180
+
181
+
182
+ def get_option_parser():
183
+ p = ly.get_option_parser(usage=_("%s [OPTION]... FILE") % 'lilypond-book',
184
+ description=help_summary,
185
+ conflict_handler="resolve",
186
+ add_help_option=False)
187
+
188
+ p.add_option('-F', '--filter',
189
+ help=_("pipe snippets through FILTER "
190
+ "[default: `convert-ly -n -']"),
191
+ metavar=_("FILTER"),
192
+ action="store",
193
+ dest="filter_cmd",
194
+ default=None)
195
+
196
+ p.add_option('-f', '--format',
197
+ help=_("use output format FORMAT (texi [default], "
198
+ "texi-html, latex, html, docbook)"),
199
+ metavar=_("FORMAT"),
200
+ action='store')
201
+
202
+ p.add_option("-h", "--help",
203
+ action="help",
204
+ help=_("show this help and exit"))
205
+
206
+ # Turn on syntax highlighting using vendored Pygments
207
+ # when building the main documentation. Purposefully
208
+ # undocumented, it is not for end users.
209
+ p.add_option("--highlight",
210
+ action="store_true",
211
+ help=SUPPRESS_HELP)
212
+
213
+ p.add_option("-I", '--include',
214
+ help=_("add DIR to include path"),
215
+ metavar=_("DIR"),
216
+ action='append',
217
+ dest='include_path',
218
+ default=[])
219
+
220
+ p.add_option('--info-images-dir',
221
+ help=_("format Texinfo output so that Info will "
222
+ "look for images of music in DIR"),
223
+ metavar=_("DIR"),
224
+ action='store',
225
+ dest='info_images_dir',
226
+ default='')
227
+
228
+ p.add_option('--left-padding',
229
+ help=_("pad left side of music to align music in spite "
230
+ "of uneven bar numbers (in mm) [default: %default]"),
231
+ metavar=_("PAD"),
232
+ dest="padding_mm",
233
+ type="float",
234
+ default=3.0)
235
+
236
+ p.add_option('--lily-loglevel',
237
+ help=_("print lilypond log messages according to LOGLEVEL "
238
+ "[default: %default]"),
239
+ metavar=_("LOGLEVEL"),
240
+ action='store',
241
+ dest='lily_loglevel',
242
+ default=os.environ.get("LILYPOND_LOGLEVEL", None))
243
+
244
+ p.add_option('--lily-output-dir',
245
+ help=_("write lily-XXX files to DIR, "
246
+ "link into --output dir"),
247
+ metavar=_("DIR"),
248
+ action='store',
249
+ dest='lily_output_dir',
250
+ default=None)
251
+
252
+ p.add_option("-l", "--loglevel",
253
+ help=_("print log messages according to LOGLEVEL "
254
+ "(NONE, ERROR, WARNING, PROGRESS [default], DEBUG)"),
255
+ metavar=_("LOGLEVEL"),
256
+ action='callback',
257
+ callback=ly.handle_loglevel_option,
258
+ type='string')
259
+
260
+ p.add_option("-o", '--output',
261
+ help=_("write output to DIR"),
262
+ metavar=_("DIR"),
263
+ action='store',
264
+ dest='output_dir',
265
+ default='')
266
+
267
+ p.add_option('-P', '--process',
268
+ help=_("process ly_files using COMMAND FILE..."),
269
+ metavar=_("COMMAND"),
270
+ action='store',
271
+ dest='process_cmd',
272
+ default='')
273
+
274
+ p.add_option('--redirect-lilypond-output',
275
+ help=_("redirect the lilypond output"),
276
+ action='store_true',
277
+ dest='redirect_output',
278
+ default=False)
279
+
280
+ p.add_option('-s', '--safe',
281
+ help=_("removed; using this option results in an error"),
282
+ action="store_true",
283
+ dest="safe_mode",
284
+ default=False)
285
+
286
+ p.add_option('--skip-lily-check',
287
+ help=_("do not fail if no lilypond output is found"),
288
+ metavar=_("DIR"),
289
+ action='store_true',
290
+ dest='skip_lilypond_run',
291
+ default=False)
292
+
293
+ p.add_option('--skip-png-check',
294
+ help=_("do not fail if no PNG images "
295
+ "are found for EPS files"),
296
+ metavar=_("DIR"),
297
+ action='store_true',
298
+ dest='skip_png_check',
299
+ default=False)
300
+
301
+ p.add_option('--use-source-file-names',
302
+ help=_("write snippet output files with the same "
303
+ "base name as their source file"),
304
+ action='store_true',
305
+ dest='use_source_file_names',
306
+ default=False)
307
+
308
+ p.add_option('-V', '--verbose',
309
+ help=_("be verbose"),
310
+ action="callback",
311
+ callback=ly.handle_loglevel_option,
312
+ callback_args=("DEBUG",))
313
+
314
+ p.version = "2.24.2"
315
+ p.add_option("--version",
316
+ help=_("show version number and exit"),
317
+ action="version")
318
+
319
+ p.add_option('-w', '--warranty',
320
+ help=_("show warranty and copyright"),
321
+ action='store_true')
322
+
323
+ group = OptionGroup(p, "Options only for the latex and texinfo backends")
324
+ group.add_option('--latex-program',
325
+ help=_("run executable PROG instead of latex or, "
326
+ "in case --pdf option is set, "
327
+ "instead of pdflatex"),
328
+ metavar=_("PROG"),
329
+ action='store',
330
+ dest='latex_program',
331
+ default='latex')
332
+ group.add_option('--texinfo-program',
333
+ help=_("run executable PROG instead of texi2pdf"),
334
+ metavar=_("PROG"),
335
+ action='store',
336
+ dest='texinfo_program',
337
+ default='texi2pdf')
338
+ group.add_option('--pdf',
339
+ help=_("create PDF files for use with pdftex"),
340
+ action="store_true",
341
+ dest="create_pdf",
342
+ default=False)
343
+ p.add_option_group(group)
344
+
345
+ p.add_option_group('',
346
+ description=(
347
+ _("Report bugs via %s")
348
+ % '[email protected]') + '\n')
349
+
350
+ for formatter in book_base.all_formats:
351
+ formatter.add_options(p)
352
+
353
+ return p
354
+
355
+
356
+ lilypond_binary = os.path.join('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/bin', 'lilypond')
357
+
358
+ # If we are called with full path, try to use lilypond binary
359
+ # installed in the same path; this is needed in GUB binaries, where
360
+ # @bindir is always different from the installed binary path.
361
+ if 'bindir' in globals() and bindir:
362
+ lilypond_binary = os.path.join(bindir, 'lilypond')
363
+
364
+ # Only use installed binary when we are installed too.
365
+ if '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/bin' == ('@' + 'bindir@') or not os.path.exists(lilypond_binary):
366
+ lilypond_binary = 'lilypond'
367
+
368
+ # Need to shell-quote, issue 3468
369
+ # FIXME: we should really pass argument lists
370
+ # everywhere instead of playing with shell syntax.
371
+ lilypond_binary = shlex.quote(lilypond_binary)
372
+
373
+ global_options = None
374
+
375
+
376
+ def command_name(cmd):
377
+ # Strip all stuf after command,
378
+ # deal with "((latex ) >& 1 ) .." too
379
+ cmd = re.match(r'([\(\)]*)([^\\ ]*)', cmd).group(2)
380
+ return os.path.basename(cmd)
381
+
382
+
383
+ def system_in_directory(cmd_str, directory, log_file):
384
+ """Execute a command in a different directory."""
385
+
386
+ if ly.is_verbose():
387
+ ly.progress(_("Invoking `%s\'") % cmd_str)
388
+ elif global_options.redirect_output:
389
+ ly.progress(_("Processing %s.ly") % log_file)
390
+ else:
391
+ name = command_name(cmd_str)
392
+ ly.progress(_("Running %s...") % name)
393
+
394
+ output_location = None
395
+ if global_options.redirect_output:
396
+ output_location = open(log_file + '.log', 'w', encoding='utf-8')
397
+
398
+ try:
399
+ subprocess.run(cmd_str, stdout=output_location,
400
+ stderr=output_location, cwd=directory,
401
+ shell=True, check=True)
402
+ except subprocess.CalledProcessError as e:
403
+ sys.stderr.write("%s\n" % e)
404
+ sys.exit(1)
405
+
406
+
407
+ def process_snippets(cmd, outdated_dict,
408
+ formatter, lily_output_dir):
409
+ """Run cmd on all of the .ly files from snippets."""
410
+ basenames = sorted(outdated_dict.keys())
411
+
412
+ # No need for a secure hash function, just need a digest.
413
+ checksum = hashlib.md5()
414
+ for name in basenames:
415
+ checksum.update(name.encode('ascii'))
416
+ checksum = checksum.hexdigest()
417
+
418
+ lily_output_dir = global_options.lily_output_dir
419
+
420
+ # Write list of snippet names.
421
+ snippet_names_file = 'snippet-names-%s.ly' % checksum
422
+ snippet_names_path = os.path.join(lily_output_dir, snippet_names_file)
423
+ with open(snippet_names_path, 'w', encoding='utf-8') as snippet_names:
424
+ snippet_names.write('\n'.join([name + '.ly' for name in basenames]))
425
+
426
+ # Run command.
427
+ cmd = formatter.adjust_snippet_command(cmd)
428
+ # Remove .ly ending.
429
+ logfile = os.path.splitext(snippet_names_path)[0]
430
+ snippet_names_arg = mkarg(snippet_names_path.replace(os.path.sep, '/'))
431
+ system_in_directory(' '.join([cmd, snippet_names_arg]),
432
+ lily_output_dir,
433
+ logfile)
434
+ os.unlink(snippet_names_path)
435
+
436
+
437
+ def lock_path(name):
438
+ if os.name != 'posix':
439
+ return None
440
+
441
+ fp = open(name, 'w', encoding='utf-8')
442
+ fcntl.lockf(fp, fcntl.LOCK_EX)
443
+ return fp
444
+
445
+
446
+ def unlock_path(lock):
447
+ if os.name != 'posix':
448
+ return None
449
+ fcntl.lockf(lock, fcntl.LOCK_UN)
450
+ lock.close()
451
+
452
+
453
+ def do_process_cmd(chunks, options):
454
+ """Wrap do_process_cmd_locked in a filesystem lock"""
455
+ snippets = [c for c in chunks if isinstance(
456
+ c, book_snippets.LilypondSnippet)]
457
+
458
+ # calculate checksums eagerly
459
+ for s in snippets:
460
+ s.get_checksum()
461
+
462
+ os.makedirs(options.lily_output_dir, exist_ok=True)
463
+ lock_file = os.path.join(options.lily_output_dir, "lock")
464
+ lock = None
465
+ try:
466
+ lock = lock_path(lock_file)
467
+ do_process_cmd_locked(snippets, options)
468
+ finally:
469
+ if lock:
470
+ unlock_path(lock)
471
+
472
+
473
+ def do_process_cmd_locked(snippets, options):
474
+ """Look at all snippets, write the outdated ones, and compile them."""
475
+ outdated = [c for c in snippets if c.is_outdated(options.lily_output_dir)]
476
+
477
+ if outdated:
478
+ # First unique the list based on the basename, by using them as keys
479
+ # in a dict.
480
+ outdated_dict = dict()
481
+ for snippet in outdated:
482
+ outdated_dict[snippet.basename()] = snippet
483
+
484
+ # Next call write_ly() for each snippet once.
485
+ progress(_("Writing snippets..."))
486
+ for snippet in outdated_dict.values():
487
+ snippet.write_ly()
488
+
489
+ progress(_("Processing..."))
490
+ process_snippets(options.process_cmd, outdated_dict,
491
+ options.formatter, options.lily_output_dir)
492
+
493
+ else:
494
+ progress(_("All snippets are up to date..."))
495
+
496
+ progress(_("Linking files..."))
497
+ if options.lily_output_dir != options.output_dir:
498
+ for snippet in snippets:
499
+ snippet.link_all_output_files(options.lily_output_dir,
500
+ options.output_dir)
501
+
502
+
503
+ ###
504
+ # Format guessing data
505
+
506
+ def guess_format(input_filename):
507
+ format = None
508
+ e = os.path.splitext(input_filename)[1]
509
+ for formatter in book_base.all_formats:
510
+ if formatter.can_handle_extension(e):
511
+ return formatter
512
+ error(_("cannot determine format for: %s" % input_filename))
513
+ exit(1)
514
+
515
+ def write_if_updated(file_name, lines):
516
+ try:
517
+ with open(file_name, encoding='utf-8') as file:
518
+ old_str = file.read()
519
+ except FileNotFoundError:
520
+ pass
521
+ else:
522
+ new_str = ''.join(lines)
523
+ if old_str == new_str:
524
+ progress(_("%s is up to date.") % file_name)
525
+
526
+ # this prevents make from always rerunning lilypond-book:
527
+ # output file must be touched in order to be up to date
528
+ os.utime(file_name, None)
529
+ return
530
+
531
+ output_dir = os.path.dirname(file_name)
532
+ os.makedirs(output_dir, exist_ok=True)
533
+
534
+ progress(_("Writing `%s'...") % file_name)
535
+ open(file_name, 'w', encoding='utf-8').writelines(lines)
536
+
537
+
538
+ def note_input_file(name, inputs=[]):
539
+ # hack: inputs is mutable!
540
+ inputs.append(name)
541
+ return inputs
542
+
543
+
544
+ def samefile(f1, f2):
545
+ try:
546
+ return os.path.samefile(f1, f2)
547
+ except AttributeError: # Windoze
548
+ f1 = re.sub("//*", "/", f1)
549
+ f2 = re.sub("//*", "/", f2)
550
+ return f1 == f2
551
+
552
+
553
+ def do_file(input_filename, included=False):
554
+ # Ugh.
555
+ input_absname = input_filename
556
+ if not input_filename or input_filename == '-':
557
+ in_handle = sys.stdin
558
+ else:
559
+ if os.path.exists(input_filename):
560
+ input_fullname = input_filename
561
+ else:
562
+ input_fullname = global_options.formatter.input_fullname(
563
+ input_filename)
564
+ # Normalize path to absolute path, since we will change cwd to the output dir!
565
+ # Otherwise, "lilypond-book -o out test.tex" will complain that it is
566
+ # overwriting the input file (which it is actually not), since the
567
+ # input filename is relative to the CWD...
568
+ input_absname = os.path.abspath(input_fullname)
569
+
570
+ note_input_file(input_fullname)
571
+ in_handle = open(input_fullname, 'r', encoding='utf-8')
572
+
573
+ if input_filename == '-':
574
+ global_options.input_dir = os.getcwd()
575
+ input_base = 'stdin'
576
+ elif included:
577
+ input_base = os.path.splitext(input_filename)[0]
578
+ else:
579
+ global_options.input_dir = os.path.split(input_absname)[0]
580
+ input_base = os.path.basename(
581
+ os.path.splitext(input_filename)[0])
582
+
583
+ output_filename = os.path.join(global_options.output_dir,
584
+ input_base + global_options.formatter.default_extension)
585
+ if (os.path.exists(input_filename)
586
+ and os.path.exists(output_filename)
587
+ and samefile(output_filename, input_absname)):
588
+ error(
589
+ _("Output would overwrite input file; use --output."))
590
+ exit(2)
591
+
592
+ try:
593
+ progress(_("Reading `%s'") % input_absname)
594
+ source = in_handle.read()
595
+
596
+ if not included:
597
+ global_options.formatter.init_default_snippet_options(source)
598
+
599
+ progress(_("Dissecting..."))
600
+ chunks = book_base.find_toplevel_snippets(
601
+ source, global_options.formatter, global_options)
602
+ for c in chunks:
603
+ c.set_output_fullpath(output_filename)
604
+
605
+ # Let the formatter modify the chunks before further processing
606
+ chunks = global_options.formatter.process_chunks(chunks)
607
+
608
+ def process_include(snippet):
609
+ name = snippet.substring('filename')
610
+ progress(_("Processing include `%s'") % name)
611
+ return do_file(name, included=True)
612
+
613
+ include_chunks = []
614
+ for x in chunks:
615
+ if isinstance(x, book_snippets.IncludeSnippet):
616
+ include_chunks += process_include(x)
617
+
618
+ return chunks + include_chunks
619
+
620
+ except book_snippets.CompileError:
621
+ progress(_("Removing `%s'") % output_filename)
622
+ raise book_snippets.CompileError
623
+
624
+
625
+ def do_options():
626
+ global global_options
627
+
628
+ opt_parser = get_option_parser()
629
+ (global_options, args) = opt_parser.parse_args()
630
+
631
+ if global_options.safe_mode:
632
+ error("""Due to security vulnerabilities deemed unfixable
633
+ by the developers, LilyPond's safe mode was removed in
634
+ version 2.23.12 in order not to provide a false sense of
635
+ security. If you need to compile an untrusted .ly file, please
636
+ use an external tool to run LilyPond in a sandbox.""")
637
+ raise SystemExit
638
+
639
+ global_options.information = {
640
+ 'program_version': program_version, 'program_name': ly.program_name}
641
+
642
+ if global_options.lily_output_dir:
643
+ global_options.lily_output_dir = os.path.expanduser(
644
+ global_options.lily_output_dir)
645
+ if global_options.output_dir:
646
+ global_options.output_dir = os.path.expanduser(
647
+ global_options.output_dir)
648
+
649
+ # Compute absolute paths of include directories.
650
+ for i, path in enumerate(global_options.include_path):
651
+ global_options.include_path[i] = os.path.abspath(path)
652
+
653
+ # Append the current directory.
654
+ global_options.include_path.append(os.getcwd())
655
+
656
+ if global_options.warranty:
657
+ warranty()
658
+ exit(0)
659
+ if not args or len(args) > 1:
660
+ opt_parser.print_help()
661
+ exit(2)
662
+
663
+ return args
664
+
665
+
666
+ def mkarg(x):
667
+ r"""
668
+ A modified version of the commands.mkarg(x)
669
+
670
+ Uses double quotes (since Windows can't handle the single quotes)
671
+ and escapes the characters \, $, ", and ` for unix shells.
672
+ """
673
+ if os.name == 'nt':
674
+ return ' "%s"' % x
675
+ s = ' "'
676
+ for c in x:
677
+ if c in '\\$"`':
678
+ s = s + '\\'
679
+ s = s + c
680
+ s = s + '"'
681
+ return s
682
+
683
+
684
+ def write_output_documents(chunks: typing.List[book_snippets.Chunk], is_filter: bool):
685
+ text_by_path = {}
686
+ for ch in chunks:
687
+ path = ch.output_fullpath()
688
+ if path not in text_by_path:
689
+ text_by_path[path] = []
690
+
691
+ if is_filter:
692
+ s = ch.filter_text()
693
+ else:
694
+ s = ch.replacement_text()
695
+
696
+ text_by_path[path].append(s)
697
+
698
+ for path in text_by_path:
699
+ write_if_updated(path, text_by_path[path])
700
+
701
+
702
+ def main():
703
+ if "LILYPOND_BOOK_LOGLEVEL" in os.environ:
704
+ ly.set_loglevel(os.environ["LILYPOND_BOOK_LOGLEVEL"])
705
+ files = do_options()
706
+
707
+ basename = os.path.splitext(files[0])[0]
708
+ basename = os.path.split(basename)[1]
709
+
710
+ if global_options.format:
711
+ # Retrieve the formatter for the given format
712
+ for formatter in book_base.all_formats:
713
+ if formatter.can_handle_format(global_options.format):
714
+ global_options.formatter = formatter
715
+ else:
716
+ global_options.formatter = guess_format(files[0])
717
+ global_options.format = global_options.formatter.format
718
+
719
+ # make the global options available to the formatters:
720
+ global_options.formatter.global_options = global_options
721
+ formats = global_options.formatter.image_formats
722
+
723
+ if global_options.process_cmd == '':
724
+ global_options.process_cmd = (
725
+ lilypond_binary + ' --formats=%s ' % formats)
726
+
727
+ global_options.process_cmd += (
728
+ ' '.join([' -I %s' % mkarg(p) for p in global_options.include_path])
729
+ + ' -daux-files ')
730
+
731
+ global_options.formatter.process_options(global_options)
732
+
733
+ if global_options.lily_loglevel:
734
+ ly.debug_output(_("Setting LilyPond's loglevel to %s") %
735
+ global_options.lily_loglevel, True)
736
+ global_options.process_cmd += " --loglevel=%s" % global_options.lily_loglevel
737
+ elif ly.is_verbose():
738
+ if os.environ.get("LILYPOND_LOGLEVEL", None):
739
+ ly.debug_output(_("Setting LilyPond's loglevel to %s (from environment variable LILYPOND_LOGLEVEL)") %
740
+ os.environ.get("LILYPOND_LOGLEVEL", None), True)
741
+ global_options.process_cmd += " --loglevel=%s" % os.environ.get(
742
+ "LILYPOND_LOGLEVEL", None)
743
+ else:
744
+ ly.debug_output(
745
+ _("Setting LilyPond's output to --verbose, implied by lilypond-book's setting"), True)
746
+ global_options.process_cmd += " --verbose"
747
+
748
+ global_options.process_cmd += " -dread-file-list -dno-strip-output-dir"
749
+
750
+ # Store the original argument to construct the dependency file below.
751
+ relative_output_dir = global_options.output_dir
752
+
753
+ if global_options.output_dir:
754
+ global_options.output_dir = os.path.abspath(global_options.output_dir)
755
+ # Create the directory, but do not complain if it already exists.
756
+ os.makedirs(global_options.output_dir, exist_ok=True)
757
+ else:
758
+ global_options.output_dir = os.getcwd()
759
+
760
+ if global_options.lily_output_dir:
761
+ global_options.lily_output_dir = os.path.abspath(
762
+ global_options.lily_output_dir)
763
+ else:
764
+ global_options.lily_output_dir = global_options.output_dir
765
+
766
+ identify()
767
+ try:
768
+ chunks = do_file(files[0])
769
+ if global_options.filter_cmd:
770
+ write_output_documents(chunks, is_filter=True)
771
+ elif global_options.process_cmd:
772
+ do_process_cmd(chunks, global_options)
773
+ progress(_("Compiling `%s'...") % files[0])
774
+ write_output_documents(chunks, is_filter=False)
775
+ except book_snippets.CompileError:
776
+ exit(1)
777
+
778
+ inputs = note_input_file('')
779
+ inputs.pop()
780
+
781
+ base_file_name = os.path.splitext(os.path.basename(files[0]))[0]
782
+ dep_file = os.path.join(global_options.output_dir, base_file_name + '.dep')
783
+ final_output_file = os.path.join(relative_output_dir,
784
+ base_file_name + global_options.formatter.default_extension)
785
+ open(dep_file, 'w', encoding='utf-8').write('%s: %s\n'
786
+ % (final_output_file, ' '.join(inputs)))
787
+
788
+
789
+ if __name__ == '__main__':
790
+ main()
lilypond-2.24.2/bin/lilypond-invoke-editor.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+ #
3
+ # This file is part of LilyPond, the GNU music typesetter.
4
+ #
5
+ # Copyright (C) 2022 Jonas Hahnfeld <[email protected]>
6
+ #
7
+ # LilyPond is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # LilyPond is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ import gettext
21
+ import os
22
+ import re
23
+ import shlex
24
+ import subprocess
25
+ import sys
26
+ import urllib.parse
27
+
28
+ # Load translation and install _() into Python's builtins namespace.
29
+ gettext.install("lilypond", "/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale")
30
+
31
+
32
+ def show_version(file):
33
+ file.write("lilypond-invoke-editor (GNU LilyPond 2.24.2)\n")
34
+
35
+
36
+ def show_help(file):
37
+ file.write(
38
+ _(
39
+ """Usage: lilypond-invoke-editor textedit://FILE:LINE:CHAR:COLUMN
40
+
41
+ Visit a file and position the cursor.
42
+
43
+ Options:
44
+ -h, --help show this help
45
+ -v, --version show version
46
+ """
47
+ )
48
+ )
49
+
50
+
51
+ # We don't need heavy option parsing here, just expect exactly one argument.
52
+ if len(sys.argv) != 2:
53
+ show_version(sys.stderr)
54
+ show_help(sys.stderr)
55
+ sys.exit(2)
56
+
57
+ argument = sys.argv[1]
58
+
59
+ # Handle the two options this script knows about.
60
+ if argument in ("-h", "--help"):
61
+ show_version(sys.stdout)
62
+ show_help(sys.stdout)
63
+ sys.exit(0)
64
+ if argument in ("-v", "--version"):
65
+ show_version(sys.stdout)
66
+ sys.exit(0)
67
+
68
+ # Now start parsing the textedit argument, first by matching its components.
69
+ m = re.fullmatch(r"textedit://(.*):([0-9]+):([0-9]+):([0-9]*)", argument)
70
+ if m is None:
71
+ show_help(sys.stderr)
72
+ sys.exit(2)
73
+
74
+ file, line, char, column = m.groups()
75
+ file = urllib.parse.unquote(file)
76
+
77
+
78
+ def replace_template(template):
79
+ return template % {
80
+ "file": file,
81
+ "line": line,
82
+ "char": char,
83
+ "column": column,
84
+ }
85
+
86
+
87
+ # Determine the editor, going from more to less specific environment variables.
88
+ editor = "emacs"
89
+ for env in ("LYEDITOR", "XEDITOR", "EDITOR"):
90
+ if env in os.environ:
91
+ editor = os.environ[env]
92
+ break
93
+
94
+ # Check if we have a template for this editor to position the cursor.
95
+ EDITOR_TEMPLATES = {
96
+ "atom": [("atom", "%(file)s:%(line)s:%(column)s")],
97
+ "emacs": [
98
+ ("emacsclient", "--no-wait", "+%(line)s:%(column)s", "%(file)s"),
99
+ ("emacs", "+%(line)s:%(column)s", "%(file)s"),
100
+ ],
101
+ "geany": [("geany", "--line", "%(line)s", "--column", "%(column)s", "%(file)s")],
102
+ "gedit": [("gedit", "--wait", "%(file)s", "+%(line)s:%(column)s")],
103
+ "gvim": [("gvim", "--remote", "+:%(line)s:norm%(column)s", "%(file)s")],
104
+ "jedit": [("jedit", "-reuseview", "%(file)s", "+line:%(line)s")],
105
+ "kate": [
106
+ ("kate", "--block", "--line", "%(line)s", "--column", "%(column)s", "%(file)s")
107
+ ],
108
+ # "nc" nowadays also stands for netcat...
109
+ "nedit": [("nc", "-noask", "+%(line)s", "%(file)s")],
110
+ "syn": [("syn", "-line", "%(line)s", "-col", "%(char)s", "%(file)s")],
111
+ "uedit32": [("uedit32", "%(file)s", "-l%(line)s", "-c%(char)s")],
112
+ }
113
+
114
+ editor_commands = []
115
+ if "%(file)s" in editor:
116
+ editor_commands = [shlex.split(editor)]
117
+ elif editor in EDITOR_TEMPLATES:
118
+ editor_commands = EDITOR_TEMPLATES[editor]
119
+ else:
120
+ editor_commands = [(editor, "%(file)s")]
121
+
122
+ editor_commands = [list(map(replace_template, cmd)) for cmd in editor_commands]
123
+
124
+ # Try commands one after another, until one succeeds.
125
+ for cmd in editor_commands:
126
+ try:
127
+ proc = subprocess.run(cmd)
128
+ if proc.returncode == 0:
129
+ sys.exit(0)
130
+ except FileNotFoundError as e:
131
+ pass
132
+
133
+ sys.stderr.write(_("failed to invoke editor:"))
134
+ sys.stderr.write(" " + str(editor_commands) + "\n")
135
+ sys.exit(1)
lilypond-2.24.2/bin/lilypond.exe ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d9c9ba6fc2c1d7c082f1e36d75053f29df32e5e513d853b30887dee2f1b2ed40
3
+ size 13852160
lilypond-2.24.2/bin/lilysong.py ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+
3
+ # Copyright (c) 2006--2022 Brailcom, o.p.s.
4
+ #
5
+ # Author: Milan Zamazal <[email protected]>
6
+ #
7
+ # This file is part of LilyPond, the GNU music typesetter.
8
+ #
9
+ # LilyPond is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # LilyPond is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+
23
+ import codecs
24
+ import optparse
25
+ import os
26
+ import subprocess
27
+ import sys
28
+ import tempfile
29
+
30
+ """
31
+
32
+ # relocate-preamble.py.in
33
+ #
34
+ # This file is part of LilyPond, the GNU music typesetter.
35
+ #
36
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
37
+ #
38
+ # LilyPond is free software: you can redistribute it and/or modify
39
+ # it under the terms of the GNU General Public License as published by
40
+ # the Free Software Foundation, either version 3 of the License, or
41
+ # (at your option) any later version.
42
+ #
43
+ # LilyPond is distributed in the hope that it will be useful,
44
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
45
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46
+ # GNU General Public License for more details.
47
+ #
48
+ # You should have received a copy of the GNU General Public License
49
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
50
+ #
51
+
52
+ This is generic code, used for all python scripts.
53
+
54
+ The quotes are to ensure that the source .py file can still be
55
+ run as a python script, but does not include any sys.path handling.
56
+ Otherwise, the lilypond-book calls inside the build
57
+ might modify installed .pyc files.
58
+
59
+ """
60
+
61
+ # This is needed for installations with a non-default layout, ie where share/
62
+ # is not next to bin/.
63
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
64
+
65
+ # Dynamic relocation, for installations with a default layout including GUB,
66
+ # but also for execution from the build directory.
67
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
68
+ topdir = os.path.dirname (bindir)
69
+ if bindir.endswith (r'/scripts/out'):
70
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
71
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
72
+ for v in [ 'current', '2.24.2' ]:
73
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
74
+
75
+ """
76
+ """
77
+
78
+
79
+ FESTIVAL_COMMAND = ['festival', '--pipe']
80
+ VOICE_CODINGS = {'voice_czech_ph': 'iso-8859-2'}
81
+
82
+ _USAGE = """lilysong [-p PLAY-PROGRAM] FILE.xml [LANGUAGE-CODE-OR-VOICE [SPEEDUP]]
83
+ lilysong FILE.ly [LANGUAGE-CODE-OR-VOICE]
84
+ lilysong --list-voices
85
+ lilysong --list-languages
86
+ """
87
+
88
+
89
+ def usage():
90
+ print('Usage:', _USAGE)
91
+ sys.exit(2)
92
+
93
+
94
+ def process_options(args):
95
+ parser = optparse.OptionParser(usage=_USAGE, version="2.24.2")
96
+ parser.add_option('', '--list-voices', action='store_true', dest='list_voices',
97
+ help="list available Festival voices")
98
+ parser.add_option('', '--list-languages', action='store_true', dest='list_languages',
99
+ help="list available Festival languages")
100
+ parser.add_option('-p', '--play-program', metavar='PROGRAM',
101
+ action='store', type='string', dest='play_program',
102
+ help="use PROGRAM to play song immediately")
103
+ options, args = parser.parse_args(args)
104
+ return options, args
105
+
106
+
107
+ def call_festival(scheme_code):
108
+ p = subprocess.Popen(FESTIVAL_COMMAND, stdin=subprocess.PIPE,
109
+ stdout=subprocess.PIPE, close_fds=True)
110
+ p.stdin.write(scheme_code)
111
+ p.stdin.close()
112
+ answer = ''
113
+ while True:
114
+ process_output = p.stdout.read()
115
+ if not process_output:
116
+ break
117
+ answer = answer + process_output
118
+ return answer
119
+
120
+
121
+ def select_voice(language_or_voice):
122
+ if language_or_voice[:6] == 'voice_':
123
+ voice = language_or_voice
124
+ else:
125
+ voice = call_festival('''
126
+ (let ((candidates '()))
127
+ (mapcar (lambda (v)
128
+ (if (eq (cadr (assoc 'language (cadr (voice.description v)))) '%s)
129
+ (set! candidates (cons v candidates))))
130
+ (append (voice.list) (mapcar car Voice_descriptions)))
131
+ (if candidates
132
+ (format t "voice_%%s" (car candidates))
133
+ (format t "nil")))
134
+ ''' % (language_or_voice,))
135
+ if voice == 'nil':
136
+ voice = None
137
+ return voice
138
+
139
+
140
+ def list_voices():
141
+ print(call_festival('''
142
+ (let ((voices (voice.list))
143
+ (print-voice (lambda (v) (format t "voice_%s\n" v))))
144
+ (mapcar print-voice voices)
145
+ (mapcar (lambda (v) (if (not (member v voices)) (print-voice v)))
146
+ (mapcar car Voice_descriptions)))
147
+ '''))
148
+
149
+
150
+ def list_languages():
151
+ print(call_festival('''
152
+ (let ((languages '()))
153
+ (let ((voices (voice.list))
154
+ (print-language (lambda (v)
155
+ (let ((language (cadr (assoc 'language (cadr (voice.description v))))))
156
+ (if (and language (not (member language languages)))
157
+ (begin
158
+ (set! languages (cons language languages))
159
+ (print language)))))))
160
+ (mapcar print-language voices)
161
+ (mapcar (lambda (v) (if (not (member v voices)) (print-language v)))
162
+ (mapcar car Voice_descriptions))))
163
+ '''))
164
+
165
+
166
+ def process_xml_file(file_name, voice, speedup, play_program):
167
+ if speedup == 1:
168
+ speedup = None
169
+ coding = (VOICE_CODINGS.get(voice) or 'iso-8859-1')
170
+ _, xml_temp_file = tempfile.mkstemp('.xml')
171
+ try:
172
+ # recode the XML file
173
+ recodep = (coding != 'utf-8')
174
+ if recodep:
175
+ decode = codecs.getdecoder('utf-8')
176
+ encode = codecs.getencoder(coding)
177
+ input = open(file_name, encoding='utf-8')
178
+ output = open(xml_temp_file, 'w', encoding='utf-8')
179
+ while True:
180
+ data = input.read()
181
+ if not data:
182
+ break
183
+ if recodep:
184
+ data = encode(decode(data)[0])[0]
185
+ output.write(data)
186
+ output.close()
187
+ # synthesize
188
+ wav_file = file_name[:-3] + 'wav'
189
+ if speedup:
190
+ _, wav_temp_file = tempfile.mkstemp('.wav')
191
+ else:
192
+ wav_temp_file = wav_file
193
+ try:
194
+ print("text2wave -eval '(%s)' -mode singing '%s' -o '%s'" %
195
+ (voice, xml_temp_file, wav_temp_file,))
196
+ result = os.system("text2wave -eval '(%s)' -mode singing '%s' -o '%s'" %
197
+ (voice, xml_temp_file, wav_temp_file,))
198
+ if result:
199
+ sys.stdout.write("Festival processing failed.\n")
200
+ return
201
+ if speedup:
202
+ result = os.system("sox '%s' '%s' speed '%f'" %
203
+ (wav_temp_file, wav_file, speedup,))
204
+ if result:
205
+ sys.stdout.write("Festival processing failed.\n")
206
+ return
207
+ finally:
208
+ if speedup:
209
+ try:
210
+ os.delete(wav_temp_file)
211
+ except OSError:
212
+ pass
213
+ sys.stdout.write("%s created.\n" % (wav_file,))
214
+ # play
215
+ if play_program:
216
+ os.system("%s '%s' >/dev/null" % (play_program, wav_file,))
217
+ finally:
218
+ try:
219
+ os.delete(xml_temp_file)
220
+ except OSError:
221
+ pass
222
+
223
+
224
+ def process_ly_file(file_name, voice):
225
+ result = os.system("lilypond '%s'" % (file_name,))
226
+ if result:
227
+ return
228
+ xml_file = None
229
+ for f in os.listdir(os.path.dirname(file_name) or '.'):
230
+ if (f[-4:] == '.xml' and
231
+ (not xml_file or os.stat.st_mtime(f) > os.stat.st_mtime(xml_file))):
232
+ xml_file = f
233
+ if xml_file:
234
+ process_xml_file(xml_file, voice, None, None)
235
+ else:
236
+ sys.stderr.write("No XML file found\n")
237
+
238
+
239
+ def go():
240
+ options, args = process_options(sys.argv[1:])
241
+ if options.list_voices:
242
+ list_voices()
243
+ elif options.list_languages:
244
+ list_languages()
245
+ else:
246
+ arglen = len(args)
247
+ if arglen < 1:
248
+ usage()
249
+ file_name = args[0]
250
+ if arglen > 1:
251
+ language_or_voice = args[1]
252
+ voice = select_voice(language_or_voice)
253
+ else:
254
+ voice = None
255
+ if file_name[-3:] == '.ly':
256
+ if arglen > 2:
257
+ usage()
258
+ process_ly_file(file_name, voice)
259
+ else:
260
+ if arglen > 3:
261
+ usage()
262
+ elif arglen == 3:
263
+ try:
264
+ speedup = float(args[2])
265
+ except ValueError:
266
+ usage()
267
+ else:
268
+ speedup = None
269
+ process_xml_file(file_name, voice, speedup, options.play_program)
270
+
271
+
272
+ if __name__ == '__main__':
273
+ go()
lilypond-2.24.2/bin/midi2ly.py ADDED
@@ -0,0 +1,1329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/home/lily/lilypond-2.24.2/release/binaries/dependencies/install/Python-3.10.8/bin/python3.10
2
+ #
3
+ # midi2ly.py -- LilyPond midi import script
4
+
5
+ # This file is part of LilyPond, the GNU music typesetter.
6
+ #
7
+ # Copyright (C) 1998--2022 Han-Wen Nienhuys <[email protected]>
8
+ # Jan Nieuwenhuizen <[email protected]>
9
+ #
10
+ # LilyPond is free software: you can redistribute it and/or modify
11
+ # it under the terms of the GNU General Public License as published by
12
+ # the Free Software Foundation, either version 3 of the License, or
13
+ # (at your option) any later version.
14
+ #
15
+ # LilyPond is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ # GNU General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU General Public License
21
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
22
+
23
+
24
+ '''
25
+ TODO:
26
+ '''
27
+
28
+ import gettext
29
+ import math
30
+ import os
31
+ import sys
32
+
33
+ """
34
+
35
+ # relocate-preamble.py.in
36
+ #
37
+ # This file is part of LilyPond, the GNU music typesetter.
38
+ #
39
+ # Copyright (C) 2007--2022 Han-Wen Nienhuys <[email protected]>
40
+ #
41
+ # LilyPond is free software: you can redistribute it and/or modify
42
+ # it under the terms of the GNU General Public License as published by
43
+ # the Free Software Foundation, either version 3 of the License, or
44
+ # (at your option) any later version.
45
+ #
46
+ # LilyPond is distributed in the hope that it will be useful,
47
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
48
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49
+ # GNU General Public License for more details.
50
+ #
51
+ # You should have received a copy of the GNU General Public License
52
+ # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
53
+ #
54
+
55
+ This is generic code, used for all python scripts.
56
+
57
+ The quotes are to ensure that the source .py file can still be
58
+ run as a python script, but does not include any sys.path handling.
59
+ Otherwise, the lilypond-book calls inside the build
60
+ might modify installed .pyc files.
61
+
62
+ """
63
+
64
+ # This is needed for installations with a non-default layout, ie where share/
65
+ # is not next to bin/.
66
+ sys.path.insert (0, os.path.join ('/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/lilypond/2.24.2', 'python'))
67
+
68
+ # Dynamic relocation, for installations with a default layout including GUB,
69
+ # but also for execution from the build directory.
70
+ bindir = os.path.abspath (os.path.dirname (sys.argv[0]))
71
+ topdir = os.path.dirname (bindir)
72
+ if bindir.endswith (r'/scripts/out'):
73
+ topdir = os.path.join (os.path.dirname (topdir), 'out')
74
+ datadir = os.path.abspath (os.path.join (topdir, 'share', 'lilypond'))
75
+ for v in [ 'current', '2.24.2' ]:
76
+ sys.path.insert (0, os.path.join (datadir, v, 'python'))
77
+
78
+ """
79
+ """
80
+
81
+ # Load translation and install _() into Python's builtins namespace.
82
+ gettext.install('lilypond', '/home/lily/lilypond-2.24.2/release/binaries/mingw/lilypond/install/share/locale')
83
+
84
+ import lilylib as ly
85
+
86
+ ################################################################
87
+ # CONSTANTS
88
+
89
+
90
+ LINE_BELL = 60
91
+ scale_steps = [0, 2, 4, 5, 7, 9, 11]
92
+ global_options = None
93
+
94
+ clocks_per_1 = 1536
95
+ clocks_per_4 = 0
96
+
97
+ time = None
98
+ reference_note = 0 # a mess
99
+ start_quant_clocks = 0
100
+
101
+ duration_quant_clocks = 0
102
+ allowed_tuplet_clocks = []
103
+ bar_max = 0
104
+
105
+ ################################################################
106
+
107
+
108
+ program_version = '2.24.2'
109
+
110
+ authors = ('Jan Nieuwenhuizen <[email protected]>',
111
+ 'Han-Wen Nienhuys <[email protected]>')
112
+
113
+
114
+
115
+ def identify():
116
+ sys.stdout.write('%s (GNU LilyPond) %s\n' %
117
+ (ly.program_name, program_version))
118
+
119
+
120
+ def warranty():
121
+ identify()
122
+ sys.stdout.write('''
123
+ %s
124
+
125
+ %s
126
+
127
+ %s
128
+ %s
129
+ ''' % (_('Copyright (c) %s by') % '1998--2023',
130
+ '\n '.join(authors),
131
+ _('Distributed under terms of the GNU General Public License.'),
132
+ _('It comes with NO WARRANTY.')))
133
+
134
+
135
+ def strip_extension(f, ext):
136
+ (p, e) = os.path.splitext(f)
137
+ if e == ext:
138
+ e = ''
139
+ return p + e
140
+
141
+
142
+ class Duration:
143
+ allowed_durs = (1, 2, 4, 8, 16, 32, 64, 128)
144
+
145
+ def __init__(self, clocks):
146
+ self.clocks = clocks
147
+ (self.dur, self.num, self.den) = self.dur_num_den(clocks)
148
+
149
+ def dur_num_den(self, clocks):
150
+ for i in range(len(allowed_tuplet_clocks)):
151
+ if clocks == allowed_tuplet_clocks[i]:
152
+ return global_options.allowed_tuplets[i]
153
+
154
+ dur = 0
155
+ num = 1
156
+ den = 1
157
+ g = math.gcd(int(clocks), clocks_per_1)
158
+ if g:
159
+ (dur, num) = (clocks_per_1 / g, clocks / g)
160
+ if not dur in self.allowed_durs:
161
+ dur = 4
162
+ num = clocks
163
+ den = clocks_per_4
164
+ return (dur, num, den)
165
+
166
+ def __repr__(self):
167
+ if self.den == 1:
168
+ if self.num == 1:
169
+ s = '%d' % self.dur
170
+ elif self.num == 3 and self.dur != 1:
171
+ s = '%d.' % (self.dur / 2)
172
+ else:
173
+ s = '%d*%d' % (self.dur, self.num)
174
+ else:
175
+ s = '%d*%d/%d' % (self.dur, self.num, self.den)
176
+ return s
177
+
178
+ def dump(self):
179
+ global reference_note
180
+ reference_note.duration = self
181
+ return repr(self)
182
+
183
+ def compare(self, other):
184
+ return self.clocks - other.clocks
185
+
186
+
187
+ def sign(x):
188
+ if x >= 0:
189
+ return 1
190
+ else:
191
+ return -1
192
+
193
+
194
+ class Note:
195
+ names = (0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6)
196
+ alterations = (0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0)
197
+ alteration_names = ('eses', 'es', '', 'is', 'isis')
198
+
199
+ def __init__(self, clocks, pitch, velocity):
200
+ self.pitch = pitch
201
+ self.velocity = velocity
202
+ # hmm
203
+ self.clocks = clocks
204
+ self.duration = Duration(clocks)
205
+ (self.octave, self.notename, self.alteration) = self.o_n_a()
206
+
207
+ def o_n_a(self):
208
+ # major scale: do-do
209
+ # minor scale: la-la (= + 5) '''
210
+
211
+ n = self.names[(self.pitch) % 12]
212
+ a = self.alterations[(self.pitch) % 12]
213
+
214
+ key = global_options.key
215
+ if not key:
216
+ key = Key(0, 0, 0)
217
+
218
+ if a and key.flats:
219
+ a = - self.alterations[(self.pitch) % 12]
220
+ n = (n - a) % 7
221
+
222
+ # By tradition, all scales now consist of a sequence
223
+ # of 7 notes each with a distinct name, from amongst
224
+ # a b c d e f g. But, minor scales have a wide
225
+ # second interval at the top - the 'leading note' is
226
+ # sharped. (Why? it just works that way! Anything
227
+ # else doesn't sound as good and isn't as flexible at
228
+ # saying things. In medieval times, scales only had 6
229
+ # notes to avoid this problem - the hexachords.)
230
+
231
+ # So, the d minor scale is d e f g a b-flat c-sharp d
232
+ # - using d-flat for the leading note would skip the
233
+ # name c and duplicate the name d. Why isn't c-sharp
234
+ # put in the key signature? Tradition. (It's also
235
+ # supposedly based on the Pythagorean theory of the
236
+ # cycle of fifths, but that really only applies to
237
+ # major scales...) Anyway, g minor is g a b-flat c d
238
+ # e-flat f-sharp g, and all the other flat minor keys
239
+ # end up with a natural leading note. And there you
240
+ # have it.
241
+
242
+ # John Sankey <[email protected]>
243
+ #
244
+ # Let's also do a-minor: a b c d e f gis a
245
+ #
246
+ # --jcn
247
+
248
+ o = self.pitch / 12 - 4
249
+
250
+ if key.minor:
251
+ # as -> gis
252
+ if (key.sharps == 0 and key.flats == 0
253
+ and n == 5 and a == -1):
254
+ n = 4
255
+ a = 1
256
+ # des -> cis
257
+ elif key.flats == 1 and n == 1 and a == -1:
258
+ n = 0
259
+ a = 1
260
+ # ges -> fis
261
+ elif key.flats == 2 and n == 4 and a == -1:
262
+ n = 3
263
+ a = 1
264
+ # g -> fisis
265
+ elif key.sharps == 5 and n == 4 and a == 0:
266
+ n = 3
267
+ a = 2
268
+ # d -> cisis
269
+ elif key.sharps == 6 and n == 1 and a == 0:
270
+ n = 0
271
+ a = 2
272
+ # a -> gisis
273
+ elif key.sharps == 7 and n == 5 and a == 0:
274
+ n = 4
275
+ a = 2
276
+
277
+ # b -> ces
278
+ if key.flats >= 6 and n == 6 and a == 0:
279
+ n = 0
280
+ a = -1
281
+ o = o + 1
282
+ # e -> fes
283
+ if key.flats >= 7 and n == 2 and a == 0:
284
+ n = 3
285
+ a = -1
286
+
287
+ # f -> eis
288
+ if key.sharps >= 3 and n == 3 and a == 0:
289
+ n = 2
290
+ a = 1
291
+ # c -> bis
292
+ if key.sharps >= 4 and n == 0 and a == 0:
293
+ n = 6
294
+ a = 1
295
+ o = o - 1
296
+
297
+ return (o, n, a)
298
+
299
+ def __repr__(self):
300
+ s = chr((self.notename + 2) % 7 + ord('a'))
301
+ return 'Note(%s %s)' % (s, repr(self.duration))
302
+
303
+ def dump(self, dump_dur=True):
304
+ global reference_note
305
+ s = chr((self.notename + 2) % 7 + ord('a'))
306
+ s = s + self.alteration_names[self.alteration + 2]
307
+ if global_options.absolute_pitches:
308
+ commas = self.octave
309
+ else:
310
+ delta = self.pitch - reference_note.pitch
311
+ commas = sign(delta) * (abs(delta) // 12)
312
+ if (((sign(delta)
313
+ * (self.notename - reference_note.notename) + 7)
314
+ % 7 >= 4)
315
+ or ((self.notename == reference_note.notename)
316
+ and (abs(delta) > 4) and (abs(delta) < 12))):
317
+ commas = commas + sign(delta)
318
+
319
+ if commas > 0:
320
+ s = s + "'" * commas
321
+ elif commas < 0:
322
+ s = s + "," * -commas
323
+
324
+ if (dump_dur
325
+ and (self.duration.compare(reference_note.duration)
326
+ or global_options.explicit_durations)):
327
+ s = s + self.duration.dump()
328
+
329
+ # Chords need to handle their reference duration themselves
330
+
331
+ reference_note = self
332
+
333
+ # TODO: move space
334
+ return s + ' '
335
+
336
+
337
+ class Time:
338
+ def __init__(self, num, den):
339
+ self.clocks = 0
340
+ self.num = num
341
+ self.den = den
342
+
343
+ def bar_clocks(self):
344
+ return clocks_per_1 * self.num / self.den
345
+
346
+ def __repr__(self):
347
+ return 'Time(%d/%d)' % (self.num, self.den)
348
+
349
+ def dump(self):
350
+ global time
351
+ time = self
352
+ return '\n ' + '\\time %d/%d ' % (self.num, self.den) + '\n '
353
+
354
+
355
+ class Tempo:
356
+ def __init__(self, seconds_per_1):
357
+ self.clocks = 0
358
+ self.seconds_per_1 = seconds_per_1
359
+
360
+ def __repr__(self):
361
+ return 'Tempo(%d)' % self.bpm()
362
+
363
+ def bpm(self):
364
+ return 4 * 60 / self.seconds_per_1
365
+
366
+ def dump(self):
367
+ return '\n ' + '\\tempo 4 = %d ' % (self.bpm()) + '\n '
368
+
369
+
370
+ class Clef:
371
+ clefs = ('"bass_8"', 'bass', 'violin', '"violin^8"')
372
+
373
+ def __init__(self, type):
374
+ self.type = type
375
+
376
+ def __repr__(self):
377
+ return 'Clef(%s)' % self.clefs[self.type]
378
+
379
+ def dump(self):
380
+ return '\n \\clef %s\n ' % self.clefs[self.type]
381
+
382
+
383
+ class Key:
384
+ key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis')
385
+ key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges')
386
+
387
+ def __init__(self, sharps, flats, minor):
388
+ self.clocks = 0
389
+ self.flats = flats
390
+ self.sharps = sharps
391
+ self.minor = minor
392
+
393
+ def dump(self):
394
+ global_options.key = self
395
+
396
+ s = ''
397
+ if self.sharps and self.flats:
398
+ pass
399
+ else:
400
+ if self.flats:
401
+ k = (ord('cfbeadg'[self.flats % 7]) -
402
+ ord('a') - 2 - 2 * self.minor + 7) % 7
403
+ else:
404
+ k = (ord('cgdaebf'[self.sharps % 7]) -
405
+ ord('a') - 2 - 2 * self.minor + 7) % 7
406
+
407
+ if not self.minor:
408
+ name = chr((k + 2) % 7 + ord('a'))
409
+ else:
410
+ name = chr((k + 2) % 7 + ord('a'))
411
+
412
+ # fis cis gis dis ais eis bis
413
+ sharps = (2, 4, 6, 1, 3, 5, 7)
414
+ # bes es as des ges ces fes
415
+ flats = (6, 4, 2, 7, 5, 3, 1)
416
+ a = 0
417
+ if self.flats:
418
+ if flats[k] <= self.flats:
419
+ a = -1
420
+ else:
421
+ if sharps[k] <= self.sharps:
422
+ a = 1
423
+
424
+ if a:
425
+ name = name + Note.alteration_names[a + 2]
426
+
427
+ s = '\\key ' + name
428
+ if self.minor:
429
+ s = s + ' \\minor'
430
+ else:
431
+ s = s + ' \\major'
432
+
433
+ return '\n\n ' + s + '\n '
434
+
435
+
436
+ class Text:
437
+ text_types = (
438
+ 'SEQUENCE_NUMBER',
439
+ 'TEXT_EVENT',
440
+ 'COPYRIGHT_NOTICE',
441
+ 'SEQUENCE_TRACK_NAME',
442
+ 'INSTRUMENT_NAME',
443
+ 'LYRIC',
444
+ 'MARKER',
445
+ 'CUE_POINT',
446
+ 'PROGRAM_NAME',
447
+ 'DEVICE_NAME', )
448
+
449
+ @staticmethod
450
+ def _text_only(chr):
451
+ if ((' ' <= chr <= '~') or chr in ['\n', '\r']):
452
+ return chr
453
+ else:
454
+ return '~'
455
+
456
+ def __init__(self, type, text):
457
+ self.clocks = 0
458
+ self.type = type
459
+ self.text = ''.join(map(self._text_only, text))
460
+
461
+ def dump(self):
462
+ # urg, we should be sure that we're in a lyrics staff
463
+ s = ''
464
+ if self.type == midi.LYRIC:
465
+ s = '"%s"' % self.text
466
+ d = Duration(self.clocks)
467
+ if (global_options.explicit_durations
468
+ or d.compare(reference_note.duration)):
469
+ s = s + Duration(self.clocks).dump()
470
+ s = s + ' '
471
+ elif (self.text.strip()
472
+ and self.type == midi.SEQUENCE_TRACK_NAME
473
+ and not self.text == 'control track'
474
+ and not self.track.lyrics_p_):
475
+ text = self.text.replace('(MIDI)', '').strip()
476
+ if text:
477
+ s = '\n \\set Staff.instrumentName = "%(text)s"\n ' % locals(
478
+ )
479
+ elif self.text.strip():
480
+ s = '\n % [' + self.text_types[self.type] + '] ' + \
481
+ self.text + '\n '
482
+ return s
483
+
484
+ def __repr__(self):
485
+ return 'Text(%d=%s)' % (self.type, self.text)
486
+
487
+ class EndOfTrack:
488
+ def __init__(self):
489
+ self.clocks = 0
490
+
491
+ def __repr__(self):
492
+ return 'EndOfTrack()'
493
+
494
+ def dump(self):
495
+ return ''
496
+
497
+ def get_voice(channel, music):
498
+ ly.debug_output('channel: ' + str(channel) + '\n')
499
+ return unthread_notes(music)
500
+
501
+
502
+ class Channel:
503
+ def __init__(self, number):
504
+ self.number = number
505
+ self.events = []
506
+ self.music = None
507
+
508
+ def add(self, event):
509
+ self.events.append(event)
510
+
511
+ def get_voice(self):
512
+ if not self.music:
513
+ self.music = self.parse()
514
+ return get_voice(self.number, self.music)
515
+
516
+ def parse(self):
517
+ pitches = {}
518
+ notes = []
519
+ music = []
520
+ last_lyric = 0
521
+ last_time = 0
522
+ end_of_track_time = None
523
+ for e in self.events:
524
+ t = e[0]
525
+
526
+ if start_quant_clocks:
527
+ t = quantise_clocks(t, start_quant_clocks)
528
+
529
+ if (e[1][0] == midi.NOTE_OFF
530
+ or (e[1][0] == midi.NOTE_ON and e[1][2] == 0)):
531
+ ly.debug_output('%d: NOTE OFF: %s' % (t, e[1][1]))
532
+ if not e[1][2]:
533
+ ly.debug_output(' ...treated as OFF')
534
+ end_note(pitches, notes, t, e[1][1])
535
+
536
+ elif e[1][0] == midi.NOTE_ON:
537
+ if e[1][1] not in pitches:
538
+ ly.debug_output('%d: NOTE ON: %s' % (t, e[1][1]))
539
+ pitches[e[1][1]] = (t, e[1][2])
540
+ else:
541
+ ly.debug_output('...ignored')
542
+
543
+ # all include ALL_NOTES_OFF
544
+ elif (e[1][0] >= midi.ALL_SOUND_OFF
545
+ and e[1][0] <= midi.POLY_MODE_ON):
546
+ for i in pitches:
547
+ end_note(pitches, notes, t, i)
548
+
549
+ elif e[1][0] == midi.META_EVENT:
550
+ if e[1][1] == midi.END_OF_TRACK:
551
+ for i in pitches:
552
+ end_note(pitches, notes, t, i)
553
+ end_of_track_time = t
554
+ break
555
+
556
+ elif e[1][1] == midi.SET_TEMPO:
557
+ (u0, u1, u2) = list(map(ord, e[1][2]))
558
+ us_per_4 = u2 + 256 * (u1 + 256 * u0)
559
+ seconds_per_1 = us_per_4 * 4 / 1e6
560
+ music.append((t, Tempo(seconds_per_1)))
561
+ elif e[1][1] == midi.TIME_SIGNATURE:
562
+ (num, dur, clocks4, count32) = list(map(ord, e[1][2]))
563
+ den = 2 ** dur
564
+ music.append((t, Time(num, den)))
565
+ elif e[1][1] == midi.KEY_SIGNATURE:
566
+ (alterations, minor) = list(map(ord, e[1][2]))
567
+ sharps = 0
568
+ flats = 0
569
+ if alterations < 127:
570
+ sharps = alterations
571
+ else:
572
+ flats = 256 - alterations
573
+
574
+ k = Key(sharps, flats, minor)
575
+ if not t and global_options.key:
576
+ # At t == 0, a set --key overrides us
577
+ k = global_options.key
578
+ music.append((t, k))
579
+
580
+ # ugh, must set key while parsing
581
+ # because Note init uses key
582
+ # Better do Note.calc () at dump time?
583
+ global_options.key = k
584
+
585
+ elif (e[1][1] == midi.LYRIC
586
+ or (global_options.text_lyrics
587
+ and e[1][1] == midi.TEXT_EVENT)):
588
+ self.lyrics_p_ = True
589
+ if last_lyric:
590
+ last_lyric.clocks = t - last_time
591
+ music.append((last_time, last_lyric))
592
+ last_time = t
593
+ last_lyric = Text(midi.LYRIC, e[1][2])
594
+
595
+ elif (e[1][1] >= midi.SEQUENCE_NUMBER
596
+ and e[1][1] <= midi.CUE_POINT):
597
+ text = Text(e[1][1], e[1][2])
598
+ text.track = self
599
+ music.append((t, text))
600
+ if text.type == midi.SEQUENCE_TRACK_NAME:
601
+ self.name = text.text
602
+ else:
603
+ if global_options.verbose:
604
+ sys.stderr.write("SKIP: %s\n" % repr(e))
605
+ else:
606
+ if global_options.verbose:
607
+ sys.stderr.write("SKIP: %s\n" % repr(e))
608
+
609
+ if last_lyric:
610
+ # last_lyric.clocks = t - last_time
611
+ # hmm
612
+ last_lyric.clocks = clocks_per_4
613
+ music.append((last_time, last_lyric))
614
+ last_lyric = 0
615
+
616
+ i = 0
617
+ while len(notes):
618
+ if i < len(music) and notes[0][0] >= music[i][0]:
619
+ i = i + 1
620
+ else:
621
+ music.insert(i, notes[0])
622
+ del notes[0]
623
+
624
+ if end_of_track_time is not None:
625
+ music.append((end_of_track_time, EndOfTrack()))
626
+
627
+ return music
628
+
629
+
630
+ class Track (Channel):
631
+ def __init__(self):
632
+ Channel.__init__(self, None)
633
+ self.name = None
634
+ self.channels = {}
635
+ self.lyrics_p_ = False
636
+
637
+ def _add(self, event):
638
+ self.events.append(event)
639
+
640
+ def add(self, event, channel=None):
641
+ if channel is None:
642
+ self._add(event)
643
+ else:
644
+ self.channels[channel] = self.channels.get(
645
+ channel, Channel(channel))
646
+ self.channels[channel].add(event)
647
+
648
+ def get_voices(self):
649
+ return ([self.get_voice()]
650
+ + [self.channels[k].get_voice()
651
+ for k in sorted(self.channels.keys())])
652
+
653
+
654
+ def create_track(events):
655
+ track = Track()
656
+ for e in events:
657
+ data = list(e[1])
658
+ if data[0] > 0x7f and data[0] < 0xf0:
659
+ channel = data[0] & 0x0f
660
+ e = (e[0], tuple([data[0] & 0xf0] + data[1:]))
661
+ track.add(e, channel)
662
+ else:
663
+ track.add(e)
664
+ return track
665
+
666
+
667
+ def quantise_clocks(clocks, quant):
668
+ q = int(clocks / quant) * quant
669
+ if q != clocks:
670
+ for tquant in allowed_tuplet_clocks:
671
+ if int(clocks / tquant) * tquant == clocks:
672
+ return clocks
673
+ if 2 * (clocks - q) > quant:
674
+ q = q + quant
675
+ return q
676
+
677
+
678
+ def end_note(pitches, notes, t, e):
679
+ try:
680
+ (lt, vel) = pitches[e]
681
+ del pitches[e]
682
+
683
+ i = len(notes) - 1
684
+ while i > 0:
685
+ if notes[i][0] > lt:
686
+ i = i - 1
687
+ else:
688
+ break
689
+ d = t - lt
690
+ if duration_quant_clocks:
691
+ d = quantise_clocks(d, duration_quant_clocks)
692
+ if not d:
693
+ d = duration_quant_clocks
694
+
695
+ notes.insert(i + 1,
696
+ (lt, Note(d, e, vel)))
697
+
698
+ except KeyError:
699
+ pass
700
+
701
+
702
+ def unthread_notes(channel):
703
+ threads = []
704
+ while channel:
705
+ thread = []
706
+ end_busy_t = 0
707
+ start_busy_t = 0
708
+ todo = []
709
+ for e in channel:
710
+ t = e[0]
711
+ if (e[1].__class__ == Note
712
+ and ((t == start_busy_t
713
+ and e[1].clocks + t == end_busy_t)
714
+ or t >= end_busy_t)):
715
+ thread.append(e)
716
+ start_busy_t = t
717
+ end_busy_t = t + e[1].clocks
718
+ elif (e[1].__class__ == Time
719
+ or e[1].__class__ == Key
720
+ or e[1].__class__ == Text
721
+ or e[1].__class__ == Tempo
722
+ or e[1].__class__ == EndOfTrack):
723
+ thread.append(e)
724
+ else:
725
+ todo.append(e)
726
+ threads.append(thread)
727
+ channel = todo
728
+
729
+ return threads
730
+
731
+
732
+ def dump_skip(skip, clocks):
733
+ global reference_note
734
+ saved_duration = reference_note.duration
735
+ result = skip + Duration(clocks).dump() + ' '
736
+ # "\skip D" does not change the reference duration like "sD",
737
+ # so we restore it after Duration.dump changes it.
738
+ if skip[0] == '\\':
739
+ reference_note.duration = saved_duration
740
+ return result
741
+
742
+
743
+ def dump(d):
744
+ return d.dump()
745
+
746
+
747
+ def dump_chord(ch):
748
+ s = ''
749
+ notes = []
750
+ for i in ch:
751
+ if i.__class__ == Note:
752
+ notes.append(i)
753
+ else:
754
+ s = s + i.dump()
755
+ if len(notes) == 1:
756
+ s = s + dump(notes[0])
757
+ elif len(notes) > 1:
758
+ global reference_note
759
+ reference_dur = reference_note.duration
760
+ s = s + '<'
761
+ s = s + notes[0].dump(dump_dur=False)
762
+ r = reference_note
763
+ for i in notes[1:]:
764
+ s = s + i.dump(dump_dur=False)
765
+ s = s + '>'
766
+ if (r.duration.compare(reference_dur)
767
+ or global_options.explicit_durations):
768
+ s = s + r.duration.dump()
769
+ s = s + ' '
770
+ reference_note = r
771
+ return s
772
+
773
+
774
+ def dump_bar_line(last_bar_t, t, bar_count):
775
+ s = ''
776
+ bar_t = time.bar_clocks()
777
+ if t - last_bar_t >= bar_t:
778
+ bar_count = bar_count + (t - last_bar_t) / bar_t
779
+
780
+ if t - last_bar_t == bar_t:
781
+ s = '\n | %% %(bar_count)d\n ' % locals()
782
+ last_bar_t = t
783
+ else:
784
+ # urg, this will barf at meter changes
785
+ last_bar_t = last_bar_t + (t - last_bar_t) / bar_t * bar_t
786
+
787
+ return (s, last_bar_t, bar_count)
788
+
789
+
790
+ def dump_voice(thread, skip):
791
+ global reference_note, time
792
+ ref = Note(0, 4*12, 0)
793
+ if not reference_note:
794
+ reference_note = ref
795
+ else:
796
+ ref.duration = reference_note.duration
797
+ reference_note = ref
798
+ last_e = None
799
+ chs = []
800
+ ch = []
801
+
802
+ for e in thread:
803
+ if last_e and last_e[0] == e[0]:
804
+ ch.append(e[1])
805
+ else:
806
+ if ch:
807
+ chs.append((last_e[0], ch))
808
+
809
+ ch = [e[1]]
810
+
811
+ last_e = e
812
+
813
+ if ch:
814
+ chs.append((last_e[0], ch))
815
+ t = 0
816
+ last_t = 0
817
+ last_bar_t = 0
818
+ bar_count = 1
819
+
820
+ lines = ['']
821
+ for ch in chs:
822
+ t = ch[0]
823
+
824
+ i = lines[-1].rfind('\n') + 1
825
+ if len(lines[-1][i:]) > LINE_BELL:
826
+ lines.append('')
827
+
828
+ if t - last_t > 0:
829
+ d = t - last_t
830
+ if bar_max and t > time.bar_clocks() * bar_max:
831
+ d = time.bar_clocks() * bar_max - last_t
832
+ lines[-1] = lines[-1] + dump_skip(skip, d)
833
+ elif t - last_t < 0:
834
+ ly.error('BUG: time skew')
835
+
836
+ (s, last_bar_t, bar_count) = dump_bar_line(last_bar_t,
837
+ t, bar_count)
838
+
839
+ if bar_max and bar_count > bar_max:
840
+ break
841
+
842
+ lines[-1] = lines[-1] + s
843
+ lines[-1] = lines[-1] + dump_chord(ch[1])
844
+
845
+ clocks = 0
846
+ for i in ch[1]:
847
+ if i.clocks > clocks:
848
+ clocks = i.clocks
849
+
850
+ last_t = t + clocks
851
+
852
+ (s, last_bar_t, bar_count) = dump_bar_line(last_bar_t,
853
+ last_t, bar_count)
854
+ lines[-1] = lines[-1] + s
855
+
856
+ return '\n '.join(lines) + '\n'
857
+
858
+
859
+ def number2ascii(i):
860
+ s = ''
861
+ i += 1
862
+ while i > 0:
863
+ m = (i - 1) % 26
864
+ s = '%c' % (m + ord('A')) + s
865
+ i = (i - m) // 26
866
+ return s
867
+
868
+
869
+ def get_track_name(i):
870
+ return 'track' + number2ascii(i)
871
+
872
+
873
+ def get_channel_name(i):
874
+ return 'channel' + number2ascii(i)
875
+
876
+
877
+ def get_voice_name(i, zero_too_p=False):
878
+ if i or zero_too_p:
879
+ return 'voice' + number2ascii(i)
880
+ return ''
881
+
882
+
883
+ def lst_append(lst, x):
884
+ lst.append(x)
885
+ return lst
886
+
887
+
888
+ def get_voice_layout(average_pitch):
889
+ d = {}
890
+ for i in range(len(average_pitch)):
891
+ d[average_pitch[i]] = lst_append(d.get(average_pitch[i], []), i)
892
+ s = list(reversed(sorted(average_pitch)))
893
+ non_empty = len([x for x in s if x])
894
+ names = ['One', 'Two']
895
+ if non_empty > 2:
896
+ names = ['One', 'Three', 'Four', 'Two']
897
+ layout = ['' for x in range(len(average_pitch))]
898
+ for i, n in zip(s, names):
899
+ if i:
900
+ v = d[i]
901
+ if isinstance(v, list):
902
+ d[i] = v[1:]
903
+ v = v[0]
904
+ layout[v] = n
905
+ return layout
906
+
907
+
908
+ def dump_track(track, n):
909
+ s = '\n'
910
+ track_name = get_track_name(n)
911
+
912
+ average_pitch = track_average_pitch(track)
913
+ voices = len([x for x in average_pitch[1:] if x])
914
+ clef = get_best_clef(average_pitch[0])
915
+
916
+ c = 0
917
+ vv = 0
918
+ for channel in track:
919
+ v = 0
920
+ channel_name = get_channel_name(c)
921
+ c += 1
922
+ for voice in channel:
923
+ voice_name = get_voice_name(v)
924
+ voice_id = track_name + channel_name + voice_name
925
+ item = voice_first_item(voice)
926
+
927
+ if item and item.__class__ == Note:
928
+ skip = 'r'
929
+ if global_options.skip:
930
+ skip = 's'
931
+ s += '%(voice_id)s = ' % locals()
932
+ if not global_options.absolute_pitches:
933
+ s += '\\relative c '
934
+ elif item and item.__class__ == Text:
935
+ skip = '" "'
936
+ s += '%(voice_id)s = \\lyricmode ' % locals()
937
+ else:
938
+ skip = '\\skip '
939
+ s += '%(voice_id)s = ' % locals()
940
+ s += '{\n'
941
+ if not n and not vv and global_options.key:
942
+ s += global_options.key.dump()
943
+ if average_pitch[vv+1] and voices > 1:
944
+ vl = get_voice_layout(average_pitch[1:])[vv]
945
+ if vl:
946
+ s += ' \\voice' + vl + '\n'
947
+ else:
948
+ if not global_options.quiet:
949
+ ly.warning(
950
+ _('found more than 5 voices on a staff, expect bad output'))
951
+ s += ' ' + dump_voice(voice, skip)
952
+ s += '}\n\n'
953
+ v += 1
954
+ vv += 1
955
+
956
+ s += '%(track_name)s = <<\n' % locals()
957
+
958
+ if clef.type != 2:
959
+ s += clef.dump() + '\n'
960
+
961
+ c = 0
962
+ vv = 0
963
+ for channel in track:
964
+ v = 0
965
+ channel_name = get_channel_name(c)
966
+ c += 1
967
+ for voice in channel:
968
+ voice_context_name = get_voice_name(vv, zero_too_p=True)
969
+ voice_name = get_voice_name(v)
970
+ v += 1
971
+ vv += 1
972
+ voice_id = track_name + channel_name + voice_name
973
+ item = voice_first_item(voice)
974
+ context = 'Voice'
975
+ if item and item.__class__ == Text:
976
+ context = 'Lyrics'
977
+ s += ' \\context %(context)s = %(voice_context_name)s \\%(voice_id)s\n' % locals()
978
+ s += '>>\n\n'
979
+ return s
980
+
981
+
982
+ def voice_first_item(voice):
983
+ for event in voice:
984
+ if (event[1].__class__ == Note
985
+ or (event[1].__class__ == Text
986
+ and event[1].type == midi.LYRIC)):
987
+ return event[1]
988
+ return None
989
+
990
+
991
+ def channel_first_item(channel):
992
+ for voice in channel:
993
+ first = voice_first_item(voice)
994
+ if first:
995
+ return first
996
+ return None
997
+
998
+
999
+ def track_first_item(track):
1000
+ for channel in track:
1001
+ first = channel_first_item(channel)
1002
+ if first:
1003
+ return first
1004
+ return None
1005
+
1006
+
1007
+ def track_average_pitch(track):
1008
+ i = 0
1009
+ p = [0]
1010
+ v = 1
1011
+ for channel in track:
1012
+ for voice in channel:
1013
+ c = 0
1014
+ p.append(0)
1015
+ for event in voice:
1016
+ if event[1].__class__ == Note:
1017
+ i += 1
1018
+ c += 1
1019
+ p[v] += event[1].pitch
1020
+ if c:
1021
+ p[0] += p[v]
1022
+ p[v] = p[v] / c
1023
+ v += 1
1024
+ if i:
1025
+ p[0] = p[0] / i
1026
+ return p
1027
+
1028
+
1029
+ def get_best_clef(average_pitch):
1030
+ if average_pitch:
1031
+ if average_pitch <= 3*12:
1032
+ return Clef(0)
1033
+ elif average_pitch <= 5*12:
1034
+ return Clef(1)
1035
+ elif average_pitch >= 7*12:
1036
+ return Clef(3)
1037
+ return Clef(2)
1038
+
1039
+
1040
+ class Staff:
1041
+ def __init__(self, track):
1042
+ self.voices = track.get_voices()
1043
+
1044
+ def dump(self, i):
1045
+ return dump_track(self.voices, i)
1046
+
1047
+
1048
+ def convert_midi(in_file, out_file):
1049
+ global midi
1050
+ import midi
1051
+
1052
+ global clocks_per_1, clocks_per_4, key
1053
+ global start_quant_clocks
1054
+ global duration_quant_clocks
1055
+ global allowed_tuplet_clocks
1056
+ global time
1057
+
1058
+ full_content = open(in_file, 'rb').read()
1059
+ clocks_max = bar_max * clocks_per_1 * 2
1060
+ midi_dump = midi.parse(full_content, clocks_max)
1061
+
1062
+ clocks_per_1 = midi_dump[0][1]
1063
+ clocks_per_4 = clocks_per_1 / 4
1064
+ time = Time(4, 4)
1065
+
1066
+ if global_options.start_quant:
1067
+ start_quant_clocks = clocks_per_1 / global_options.start_quant
1068
+
1069
+ if global_options.duration_quant:
1070
+ duration_quant_clocks = clocks_per_1 / global_options.duration_quant
1071
+
1072
+ allowed_tuplet_clocks = []
1073
+ for (dur, num, den) in global_options.allowed_tuplets:
1074
+ allowed_tuplet_clocks.append(clocks_per_1 / dur * num / den)
1075
+
1076
+ if global_options.verbose:
1077
+ print('allowed tuplet clocks:', allowed_tuplet_clocks)
1078
+
1079
+ tracks = [create_track(t) for t in midi_dump[1]]
1080
+ # urg, parse all global track events, such as Key first
1081
+ # this fixes key in different voice/staff problem
1082
+ for t in tracks:
1083
+ t.music = t.parse()
1084
+ prev = None
1085
+ staves = []
1086
+ for t in tracks:
1087
+ voices = t.get_voices()
1088
+ if ((t.name and prev and prev.name)
1089
+ and t.name.split(':')[0] == prev.name.split(':')[0]):
1090
+ # staves[-1].voices += voices
1091
+ # all global track events first
1092
+ staves[-1].voices = ([staves[-1].voices[0]]
1093
+ + [voices[0]]
1094
+ + staves[-1].voices[1:]
1095
+ + voices[1:])
1096
+ else:
1097
+ staves.append(Staff(t))
1098
+ prev = t
1099
+
1100
+ tag = '%% Lily was here -- automatically converted by %s from %s' % (
1101
+ ly.program_name, in_file)
1102
+
1103
+ s = tag
1104
+ s += r'''
1105
+ \version "2.14.0"
1106
+ '''
1107
+
1108
+ s += r'''
1109
+ \layout {
1110
+ \context {
1111
+ \Voice
1112
+ \remove Note_heads_engraver
1113
+ \consists Completion_heads_engraver
1114
+ \remove Rest_engraver
1115
+ \consists Completion_rest_engraver
1116
+ }
1117
+ }
1118
+ '''
1119
+
1120
+ for i in global_options.include_header:
1121
+ s += '\n%% included from %(i)s\n' % locals()
1122
+ s += open(i, encoding='utf-8').read()
1123
+ if s[-1] != '\n':
1124
+ s += '\n'
1125
+ s += '% end\n'
1126
+
1127
+ for i, t in enumerate(staves):
1128
+ s += t.dump(i)
1129
+
1130
+ s += '\n\\score {\n <<\n'
1131
+
1132
+ control_track = False
1133
+ i = 0
1134
+ output_track_count = 0
1135
+ for i, staff in enumerate(staves):
1136
+ track_name = get_track_name(i)
1137
+ item = track_first_item(staff.voices)
1138
+ staff_name = track_name
1139
+ context = None
1140
+ if not i and not item and len(staves) > 1:
1141
+ control_track = track_name
1142
+ continue
1143
+ elif (item and item.__class__ == Note):
1144
+ context = 'Staff'
1145
+ if control_track:
1146
+ s += ' \\context %(context)s=%(staff_name)s \\%(control_track)s\n' % locals()
1147
+ elif item and item.__class__ == Text:
1148
+ context = 'Lyrics'
1149
+ if context:
1150
+ output_track_count += 1
1151
+ s += ' \\context %(context)s=%(staff_name)s \\%(track_name)s\n' % locals()
1152
+
1153
+ # If we found a control track but no other tracks with which
1154
+ # to combine it, create a Staff for the control track alone.
1155
+ if (output_track_count == 0) and control_track:
1156
+ s += ' \\context Staff \\%(control_track)s\n' % locals()
1157
+
1158
+ s = s + r''' >>
1159
+ \layout {}
1160
+ \midi {}
1161
+ }
1162
+ '''
1163
+
1164
+ if not global_options.quiet:
1165
+ ly.progress(_("%s output to `%s'...") % ('LY', out_file))
1166
+
1167
+ if out_file == '-':
1168
+ handle = sys.stdout
1169
+ else:
1170
+ handle = open(out_file, 'w', encoding='utf-8')
1171
+
1172
+ handle.write(s)
1173
+ handle.close()
1174
+
1175
+
1176
+ def get_option_parser():
1177
+ p = ly.get_option_parser(usage=_("%s [OPTION]... FILE") % 'midi2ly',
1178
+ description=_(
1179
+ "Convert %s to LilyPond input.\n") % 'MIDI',
1180
+ add_help_option=False)
1181
+
1182
+ p.add_option('-a', '--absolute-pitches',
1183
+ action='store_true',
1184
+ help=_('print absolute pitches'))
1185
+ p.add_option('-d', '--duration-quant',
1186
+ metavar=_('DUR'),
1187
+ help=_('quantise note durations on DUR'))
1188
+ p.add_option('-D', '--debug',
1189
+ action='store_true',
1190
+ help=_('debug printing'))
1191
+ p.add_option('-e', '--explicit-durations',
1192
+ action='store_true',
1193
+ help=_('print explicit durations'))
1194
+ p.add_option('-h', '--help',
1195
+ action='help',
1196
+ help=_('show this help and exit'))
1197
+ p.add_option('-i', '--include-header',
1198
+ help=_('prepend FILE to output'),
1199
+ action='append',
1200
+ default=[],
1201
+ metavar=_('FILE'))
1202
+ p.add_option('-k', '--key', help=_('set key: ALT=+sharps|-flats; MINOR=1'),
1203
+ metavar=_('ALT[:MINOR]'),
1204
+ default=None),
1205
+ p.add_option('-o', '--output', help=_('write output to FILE'),
1206
+ metavar=_('FILE'),
1207
+ action='store')
1208
+ p.add_option('-p', '--preview', help=_('preview of first 4 bars'),
1209
+ action='store_true')
1210
+ p.add_option('-q', '--quiet',
1211
+ action="store_true",
1212
+ help=_("suppress progress messages and warnings about excess voices"))
1213
+ p.add_option('-s', '--start-quant', help=_('quantise note starts on DUR'),
1214
+ metavar=_('DUR'))
1215
+ p.add_option('-S', '--skip',
1216
+ action="store_true",
1217
+ help=_("use s instead of r for rests"))
1218
+ p.add_option('-t', '--allow-tuplet',
1219
+ metavar=_('DUR*NUM/DEN'),
1220
+ action='append',
1221
+ dest='allowed_tuplets',
1222
+ help=_('allow tuplet durations DUR*NUM/DEN'),
1223
+ default=[])
1224
+ p.add_option('-V', '--verbose', help=_('be verbose'),
1225
+ action='store_true')
1226
+ p.version = 'midi2ly (LilyPond) 2.24.2'
1227
+ p.add_option('--version',
1228
+ action='version',
1229
+ help=_('show version number and exit'))
1230
+ p.add_option('-w', '--warranty', help=_('show warranty and copyright'),
1231
+ action='store_true',)
1232
+ p.add_option('-x', '--text-lyrics', help=_('treat every text as a lyric'),
1233
+ action='store_true')
1234
+
1235
+ p.add_option_group(_('Examples'),
1236
+ description=r'''
1237
+ $ midi2ly --key=-2:1 --duration-quant=32 --allow-tuplet=4*2/3 --allow-tuplet=2*4/3 foo.midi
1238
+ ''')
1239
+ p.add_option_group('',
1240
+ description=(
1241
+ _('Report bugs via %s')
1242
+ % '[email protected]') + '\n')
1243
+ return p
1244
+
1245
+
1246
+ def do_options():
1247
+ opt_parser = get_option_parser()
1248
+ (options, args) = opt_parser.parse_args()
1249
+
1250
+ if options.warranty:
1251
+ warranty()
1252
+ sys.exit(0)
1253
+
1254
+ if not args or args[0] == '-':
1255
+ opt_parser.print_help()
1256
+ sys.stderr.write('\n%s: %s %s\n' % (ly.program_name, _('error: '),
1257
+ _('no files specified on command line.')))
1258
+ sys.exit(2)
1259
+
1260
+ if options.duration_quant:
1261
+ options.duration_quant = int(options.duration_quant)
1262
+
1263
+ if options.key:
1264
+ (alterations, minor) = list(
1265
+ map(int, (options.key + ':0').split(':')))[0:2]
1266
+ sharps = 0
1267
+ flats = 0
1268
+ if alterations >= 0:
1269
+ sharps = alterations
1270
+ else:
1271
+ flats = - alterations
1272
+ options.key = Key(sharps, flats, minor)
1273
+
1274
+ if options.start_quant:
1275
+ options.start_quant = int(options.start_quant)
1276
+
1277
+ global bar_max
1278
+ if options.preview:
1279
+ bar_max = 4
1280
+
1281
+ options.allowed_tuplets = [list(map(int, a.replace('/', '*').split('*')))
1282
+ for a in options.allowed_tuplets]
1283
+
1284
+ if options.verbose:
1285
+ sys.stderr.write('Allowed tuplets: %s\n' %
1286
+ repr(options.allowed_tuplets))
1287
+
1288
+ global global_options
1289
+ global_options = options
1290
+
1291
+ return args
1292
+
1293
+
1294
+ def main():
1295
+ files = do_options()
1296
+
1297
+ exts = ['.midi', '.mid', '.MID']
1298
+ for f in files:
1299
+ g = f
1300
+ for e in exts:
1301
+ g = strip_extension(g, e)
1302
+ if not os.path.exists(f):
1303
+ for e in exts:
1304
+ n = g + e
1305
+ if os.path.exists(n):
1306
+ f = n
1307
+ break
1308
+
1309
+ if not global_options.output:
1310
+ outdir = '.'
1311
+ outbase = os.path.basename(g)
1312
+ o = outbase + '-midi.ly'
1313
+ elif (global_options.output[-1] == os.sep
1314
+ or os.path.isdir(global_options.output)):
1315
+ outdir = global_options.output
1316
+ outbase = os.path.basename(g)
1317
+ o = os.path.join(outdir, outbase + '-midi.ly')
1318
+ else:
1319
+ o = global_options.output
1320
+ (outdir, outbase) = os.path.split(o)
1321
+
1322
+ if outdir and outdir != '.' and not os.path.exists(outdir):
1323
+ os.mkdir(outdir, 0o777)
1324
+
1325
+ convert_midi(f, o)
1326
+
1327
+
1328
+ if __name__ == '__main__':
1329
+ main()
lilypond-2.24.2/bin/musicxml2ly.py ADDED
The diff for this file is too large to render. See raw diff
 
lilypond-2.24.2/bin/pyexpat.pyd ADDED
Binary file (199 kB). View file
 
lilypond-2.24.2/bin/python.exe ADDED
Binary file (102 kB). View file
 
lilypond-2.24.2/bin/python310.dll ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c30589187be320bc8e65177aeb8dc1d39957f7b7dcda4c13524dd7f436fb0948
3
+ size 4492160
lilypond-2.24.2/bin/python310.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1fc143399b184ff1c26246da037d1d20f99b166922cd3ac16ed299b99b80e4de
3
+ size 2640871
lilypond-2.24.2/etc/fonts/conf.d/10-hinting-slight.conf ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set hintslight to hintstyle</description>
5
+
6
+ <match target="pattern">
7
+ <!--
8
+ This sort of configuration is available on the major desktop environments
9
+ and we don't have to break it with "assign" unconditionally. however, we
10
+ want to set something for others. So we use "append" here to get this working
11
+ in both cases so that most clients would takes a look at the first place only.
12
+ -->
13
+ <edit name="hintstyle" mode="append"><const>hintslight</const></edit>
14
+ </match>
15
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/10-scale-bitmap-fonts.conf ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Bitmap scaling</description>
5
+ <!--
6
+ If font is bitmap, calculate scale factor.
7
+ Note that color bitmap fonts have scalable=true, while
8
+ non-color ones have scalable=false. Both groups have outline=false.
9
+ -->
10
+ <match target="font">
11
+ <test name="outline" compare="eq">
12
+ <bool>false</bool>
13
+ </test>
14
+ <edit name="pixelsizefixupfactor" mode="assign">
15
+ <divide>
16
+ <name target="pattern">pixelsize</name>
17
+ <name target="font" >pixelsize</name>
18
+ </divide>
19
+ </edit>
20
+ </match>
21
+ <!--
22
+ For non-scalable bitmap fonts (ie. non-color), skip
23
+ minor scaling if hinting is enabled.
24
+ -->
25
+ <match target="font">
26
+ <test name="outline" compare="eq">
27
+ <bool>false</bool>
28
+ </test>
29
+ <test name="scalable" compare="eq">
30
+ <bool>false</bool>
31
+ </test>
32
+ <test name="hinting" compare="eq">
33
+ <bool>true</bool>
34
+ </test>
35
+ <edit name="scalingnotneeded" mode="assign">
36
+ <and>
37
+ <less>
38
+ <name>pixelsizefixupfactor</name>
39
+ <double>1.2</double>
40
+ </less>
41
+ <more>
42
+ <name>pixelsizefixupfactor</name>
43
+ <double>0.8</double>
44
+ </more>
45
+ </and>
46
+ </edit>
47
+ </match>
48
+ <match target="font">
49
+ <test name="scalingnotneeded" compare="eq">
50
+ <bool>true</bool>
51
+ </test>
52
+ <edit name="pixelsizefixupfactor" mode="assign">
53
+ <double>1.0</double>
54
+ </edit>
55
+ </match>
56
+ <!--
57
+ If we *are* going to scale, go ahead and do it.
58
+ -->
59
+ <match target="font">
60
+ <test name="outline" compare="eq">
61
+ <bool>false</bool>
62
+ </test>
63
+ <test name="pixelsizefixupfactor" compare="not_eq">
64
+ <double>1.0</double>
65
+ </test>
66
+ <edit name="matrix" mode="assign">
67
+ <times>
68
+ <name>matrix</name>
69
+ <matrix>
70
+ <name>pixelsizefixupfactor</name> <double>0</double>
71
+ <double>0</double> <name>pixelsizefixupfactor</name>
72
+ </matrix>
73
+ </times>
74
+ </edit>
75
+ <edit name="size" mode="assign">
76
+ <divide>
77
+ <name>size</name>
78
+ <name>pixelsizefixupfactor</name>
79
+ </divide>
80
+ </edit>
81
+ </match>
82
+
83
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/10-sub-pixel-none.conf ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Disable sub-pixel rendering</description>
5
+ <!-- Disable sub-pixel rendering -->
6
+ <match target="pattern">
7
+ <!--
8
+ This sort of configuration is available on the major desktop environments
9
+ and we don't have to break it with "assign" unconditionally. however, we
10
+ want to set something for others. So we use "append" here to get this working
11
+ in both cases so that most clients would takes a look at the first place only.
12
+ -->
13
+ <edit name="rgba" mode="append"><const>none</const></edit>
14
+ </match>
15
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/10-yes-antialias.conf ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Enable antialiasing</description>
5
+ <match target="pattern">
6
+ <edit name="antialias" mode="append"><bool>true</bool></edit>
7
+ </match>
8
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/11-lcdfilter-default.conf ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Use lcddefault as default for LCD filter</description>
5
+ <!-- Use lcddefault as default for LCD filter -->
6
+ <match target="pattern">
7
+ <!--
8
+ This sort of configuration is available on the major desktop environments
9
+ and we don't have to break it with "assign" unconditionally. however, we
10
+ want to set something for others. So we use "append" here to get this working
11
+ in both cases so that most clients would takes a look at the first place only.
12
+ -->
13
+ <edit mode="append" name="lcdfilter">
14
+ <const>lcddefault</const>
15
+ </edit>
16
+ </match>
17
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/20-unhint-small-vera.conf ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Disable hinting for Bitstream Vera fonts when the size is less than 8ppem</description>
5
+ <!--
6
+ The Bitstream Vera fonts have GASP entries suggesting that hinting be
7
+ disabled below 8 ppem, but FreeType ignores those, preferring to use
8
+ the data found in the instructed hints. The initial Vera release
9
+ didn't include the right instructions in the 'prep' table. Fix this
10
+ by disabling hinting manually at smaller sizes (< 8ppem)
11
+ -->
12
+
13
+ <match target="font">
14
+ <test name="family" compare="eq" ignore-blanks="true">
15
+ <string>Bitstream Vera Sans</string>
16
+ </test>
17
+ <test name="pixelsize" compare="less">
18
+ <double>7.5</double>
19
+ </test>
20
+ <edit name="hinting">
21
+ <bool>false</bool>
22
+ </edit>
23
+ </match>
24
+
25
+ <match target="font">
26
+ <test name="family" compare="eq" ignore-blanks="true">
27
+ <string>Bitstream Vera Serif</string>
28
+ </test>
29
+ <test name="pixelsize" compare="less">
30
+ <double>7.5</double>
31
+ </test>
32
+ <edit name="hinting">
33
+ <bool>false</bool>
34
+ </edit>
35
+ </match>
36
+
37
+ <match target="font">
38
+ <test name="family" compare="eq" ignore-blanks="true">
39
+ <string>Bitstream Vera Sans Mono</string>
40
+ </test>
41
+ <test name="pixelsize" compare="less">
42
+ <double>7.5</double>
43
+ </test>
44
+ <edit name="hinting">
45
+ <bool>false</bool>
46
+ </edit>
47
+ </match>
48
+
49
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/30-metric-aliases.conf ADDED
@@ -0,0 +1,637 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set substitutions for similar/metric-compatible families</description>
5
+
6
+ <!--
7
+
8
+ Alias similar/metric-compatible families from various sources:
9
+
10
+ PostScript fonts: URW fonts: GUST fonts: Windows fonts:
11
+ ====================== ================== ================= ==================
12
+ Helvetica Nimbus Sans TeX Gyre Heros
13
+ Helvetica Narrow Nimbus Sans Narrow TeX Gyre Heros Cn
14
+ Times Nimbus Roman TeX Gyre Termes
15
+ Courier Nimbus Mono PS TeX Gyre Cursor
16
+ ITC Avant Garde Gothic URW Gothic TeX Gyre Adventor
17
+ ITC Bookman URW Bookman TeX Gyre Bonum Bookman Old Style
18
+ ITC Zapf Chancery Z003 TeX Gyre Chorus
19
+ Palatino P052 TeX Gyre Pagella Palatino Linotype
20
+ New Century Schoolbook C059 TeX Gyre Schola Century Schoolbook
21
+
22
+ Microsoft fonts: Liberation fonts: Google CrOS core fonts: StarOffice fonts: AMT fonts:
23
+ ================ ====================== ======================= ================= ==============
24
+ Arial Liberation Sans Arimo Albany Albany AMT
25
+ Arial Narrow Liberation Sans Narrow
26
+ Times New Roman Liberation Serif Tinos Thorndale Thorndale AMT
27
+ Courier New Liberation Mono Cousine Cumberland Cumberland AMT
28
+ Cambria Caladea
29
+ Calibri Carlito
30
+ Symbol SymbolNeu
31
+
32
+ Microsoft fonts: Other fonts:
33
+ ================ ============
34
+ Georgia Gelasio
35
+
36
+ We want for each of them to fallback to any of these available,
37
+ but in an order preferring similar designs first. We do this in three steps:
38
+
39
+ 1) Alias each specific to its generic family.
40
+ e.g. Liberation Sans to Arial
41
+
42
+ 2) Weak alias each generic to the other generic of its family.
43
+ e.g. Arial to Helvetica
44
+
45
+ 3) Alias each generic to its specifics.
46
+ e.g. Arial to Liberation Sans, Arimo, Albany, and Albany AMT
47
+
48
+ NOTE: The (URW)++ fonts mappings of generics to specifics were removed, because
49
+ upstream now includes them in their release of (URW)++ Core Font Set here:
50
+ https://github.com/ArtifexSoftware/urw-base35-fonts/tree/master/fontconfig
51
+ -->
52
+
53
+ <!-- Map specifics to generics -->
54
+
55
+ <!-- PostScript -->
56
+ <alias binding="same">
57
+ <family>Nimbus Sans L</family>
58
+ <default>
59
+ <family>Helvetica</family>
60
+ </default>
61
+ </alias>
62
+
63
+ <alias binding="same">
64
+ <family>Nimbus Sans</family>
65
+ <default>
66
+ <family>Helvetica</family>
67
+ </default>
68
+ </alias>
69
+
70
+ <alias binding="same">
71
+ <family>TeX Gyre Heros</family>
72
+ <default>
73
+ <family>Helvetica</family>
74
+ </default>
75
+ </alias>
76
+
77
+ <alias binding="same">
78
+ <family>Nimbus Sans Narrow</family>
79
+ <default>
80
+ <family>Helvetica Narrow</family>
81
+ </default>
82
+ </alias>
83
+
84
+ <alias binding="same">
85
+ <family>TeX Gyre Heros Cn</family>
86
+ <default>
87
+ <family>Helvetica Narrow</family>
88
+ </default>
89
+ </alias>
90
+
91
+ <alias binding="same">
92
+ <family>Nimbus Roman No9 L</family>
93
+ <default>
94
+ <family>Times</family>
95
+ </default>
96
+ </alias>
97
+
98
+ <alias binding="same">
99
+ <family>Nimbus Roman</family>
100
+ <default>
101
+ <family>Times</family>
102
+ </default>
103
+ </alias>
104
+
105
+ <alias binding="same">
106
+ <family>TeX Gyre Termes</family>
107
+ <default>
108
+ <family>Times</family>
109
+ </default>
110
+ </alias>
111
+
112
+ <alias binding="same">
113
+ <family>Nimbus Mono L</family>
114
+ <default>
115
+ <family>Courier</family>
116
+ </default>
117
+ </alias>
118
+
119
+ <alias binding="same">
120
+ <family>Nimbus Mono</family>
121
+ <default>
122
+ <family>Courier</family>
123
+ </default>
124
+ </alias>
125
+
126
+ <alias binding="same">
127
+ <family>Nimbus Mono PS</family>
128
+ <default>
129
+ <family>Courier</family>
130
+ </default>
131
+ </alias>
132
+
133
+ <alias binding="same">
134
+ <family>TeX Gyre Cursor</family>
135
+ <default>
136
+ <family>Courier</family>
137
+ </default>
138
+ </alias>
139
+
140
+ <alias binding="same">
141
+ <family>Avant Garde</family>
142
+ <default>
143
+ <family>ITC Avant Garde Gothic</family>
144
+ </default>
145
+ </alias>
146
+
147
+ <alias binding="same">
148
+ <family>URW Gothic L</family>
149
+ <default>
150
+ <family>ITC Avant Garde Gothic</family>
151
+ </default>
152
+ </alias>
153
+
154
+ <alias binding="same">
155
+ <family>URW Gothic</family>
156
+ <default>
157
+ <family>ITC Avant Garde Gothic</family>
158
+ </default>
159
+ </alias>
160
+
161
+ <alias binding="same">
162
+ <family>TeX Gyre Adventor</family>
163
+ <default>
164
+ <family>ITC Avant Garde Gothic</family>
165
+ </default>
166
+ </alias>
167
+
168
+ <alias binding="same">
169
+ <family>Bookman</family>
170
+ <default>
171
+ <family>ITC Bookman</family>
172
+ </default>
173
+ </alias>
174
+
175
+ <alias binding="same">
176
+ <family>URW Bookman L</family>
177
+ <default>
178
+ <family>ITC Bookman</family>
179
+ </default>
180
+ </alias>
181
+
182
+ <alias binding="same">
183
+ <family>Bookman URW</family>
184
+ <default>
185
+ <family>ITC Bookman</family>
186
+ </default>
187
+ </alias>
188
+
189
+ <alias binding="same">
190
+ <family>URW Bookman</family>
191
+ <default>
192
+ <family>ITC Bookman</family>
193
+ </default>
194
+ </alias>
195
+
196
+ <alias binding="same">
197
+ <family>TeX Gyre Bonum</family>
198
+ <default>
199
+ <family>ITC Bookman</family>
200
+ </default>
201
+ </alias>
202
+
203
+ <alias binding="same">
204
+ <family>Bookman Old Style</family>
205
+ <default>
206
+ <family>ITC Bookman</family>
207
+ </default>
208
+ </alias>
209
+
210
+ <alias binding="same">
211
+ <family>Zapf Chancery</family>
212
+ <default>
213
+ <family>ITC Zapf Chancery</family>
214
+ </default>
215
+ </alias>
216
+
217
+ <alias binding="same">
218
+ <family>URW Chancery L</family>
219
+ <default>
220
+ <family>ITC Zapf Chancery</family>
221
+ </default>
222
+ </alias>
223
+
224
+ <alias binding="same">
225
+ <family>Chancery URW</family>
226
+ <default>
227
+ <family>ITC Zapf Chancery</family>
228
+ </default>
229
+ </alias>
230
+
231
+ <alias binding="same">
232
+ <family>Z003</family>
233
+ <default>
234
+ <family>ITC Zapf Chancery</family>
235
+ </default>
236
+ </alias>
237
+
238
+ <alias binding="same">
239
+ <family>TeX Gyre Chorus</family>
240
+ <default>
241
+ <family>ITC Zapf Chancery</family>
242
+ </default>
243
+ </alias>
244
+
245
+ <alias binding="same">
246
+ <family>URW Palladio L</family>
247
+ <default>
248
+ <family>Palatino</family>
249
+ </default>
250
+ </alias>
251
+
252
+ <alias binding="same">
253
+ <family>Palladio URW</family>
254
+ <default>
255
+ <family>Palatino</family>
256
+ </default>
257
+ </alias>
258
+
259
+ <alias binding="same">
260
+ <family>P052</family>
261
+ <default>
262
+ <family>Palatino</family>
263
+ </default>
264
+ </alias>
265
+
266
+ <alias binding="same">
267
+ <family>TeX Gyre Pagella</family>
268
+ <default>
269
+ <family>Palatino</family>
270
+ </default>
271
+ </alias>
272
+
273
+ <alias binding="same">
274
+ <family>Palatino Linotype</family>
275
+ <default>
276
+ <family>Palatino</family>
277
+ </default>
278
+ </alias>
279
+
280
+ <alias binding="same">
281
+ <family>Century Schoolbook L</family>
282
+ <default>
283
+ <family>New Century Schoolbook</family>
284
+ </default>
285
+ </alias>
286
+
287
+ <alias binding="same">
288
+ <family>Century SchoolBook URW</family>
289
+ <default>
290
+ <family>New Century Schoolbook</family>
291
+ </default>
292
+ </alias>
293
+
294
+ <alias binding="same">
295
+ <family>C059</family>
296
+ <default>
297
+ <family>New Century Schoolbook</family>
298
+ </default>
299
+ </alias>
300
+
301
+ <alias binding="same">
302
+ <family>TeX Gyre Schola</family>
303
+ <default>
304
+ <family>New Century Schoolbook</family>
305
+ </default>
306
+ </alias>
307
+
308
+ <alias binding="same">
309
+ <family>Century Schoolbook</family>
310
+ <default>
311
+ <family>New Century Schoolbook</family>
312
+ </default>
313
+ </alias>
314
+
315
+ <!-- Microsoft -->
316
+ <alias binding="same">
317
+ <family>Arimo</family>
318
+ <default>
319
+ <family>Arial</family>
320
+ </default>
321
+ </alias>
322
+
323
+ <alias binding="same">
324
+ <family>Liberation Sans</family>
325
+ <default>
326
+ <family>Arial</family>
327
+ </default>
328
+ </alias>
329
+
330
+ <alias binding="same">
331
+ <family>Liberation Sans Narrow</family>
332
+ <default>
333
+ <family>Arial Narrow</family>
334
+ </default>
335
+ </alias>
336
+
337
+ <alias binding="same">
338
+ <family>Albany</family>
339
+ <default>
340
+ <family>Arial</family>
341
+ </default>
342
+ </alias>
343
+
344
+ <alias binding="same">
345
+ <family>Albany AMT</family>
346
+ <default>
347
+ <family>Arial</family>
348
+ </default>
349
+ </alias>
350
+
351
+ <alias binding="same">
352
+ <family>Tinos</family>
353
+ <default>
354
+ <family>Times New Roman</family>
355
+ </default>
356
+ </alias>
357
+
358
+ <alias binding="same">
359
+ <family>Liberation Serif</family>
360
+ <default>
361
+ <family>Times New Roman</family>
362
+ </default>
363
+ </alias>
364
+
365
+ <alias binding="same">
366
+ <family>Thorndale</family>
367
+ <default>
368
+ <family>Times New Roman</family>
369
+ </default>
370
+ </alias>
371
+
372
+ <alias binding="same">
373
+ <family>Thorndale AMT</family>
374
+ <default>
375
+ <family>Times New Roman</family>
376
+ </default>
377
+ </alias>
378
+
379
+ <alias binding="same">
380
+ <family>Cousine</family>
381
+ <default>
382
+ <family>Courier New</family>
383
+ </default>
384
+ </alias>
385
+
386
+ <alias binding="same">
387
+ <family>Liberation Mono</family>
388
+ <default>
389
+ <family>Courier New</family>
390
+ </default>
391
+ </alias>
392
+
393
+ <alias binding="same">
394
+ <family>Cumberland</family>
395
+ <default>
396
+ <family>Courier New</family>
397
+ </default>
398
+ </alias>
399
+
400
+ <alias binding="same">
401
+ <family>Cumberland AMT</family>
402
+ <default>
403
+ <family>Courier New</family>
404
+ </default>
405
+ </alias>
406
+
407
+ <alias binding="same">
408
+ <family>Gelasio</family>
409
+ <default>
410
+ <family>Georgia</family>
411
+ </default>
412
+ </alias>
413
+
414
+ <alias binding="same">
415
+ <family>Caladea</family>
416
+ <default>
417
+ <family>Cambria</family>
418
+ </default>
419
+ </alias>
420
+
421
+ <alias binding="same">
422
+ <family>Carlito</family>
423
+ <default>
424
+ <family>Calibri</family>
425
+ </default>
426
+ </alias>
427
+
428
+ <alias binding="same">
429
+ <family>SymbolNeu</family>
430
+ <default>
431
+ <family>Symbol</family>
432
+ </default>
433
+ </alias>
434
+
435
+ <!-- Accept the other group as fallback -->
436
+
437
+ <!-- PostScript -->
438
+ <alias>
439
+ <family>Helvetica</family>
440
+ <default>
441
+ <family>Arial</family>
442
+ </default>
443
+ </alias>
444
+
445
+ <alias>
446
+ <family>Helvetica Narrow</family>
447
+ <default>
448
+ <family>Arial Narrow</family>
449
+ </default>
450
+ </alias>
451
+
452
+ <alias>
453
+ <family>Times</family>
454
+ <default>
455
+ <family>Times New Roman</family>
456
+ </default>
457
+ </alias>
458
+
459
+ <alias>
460
+ <family>Courier</family>
461
+ <default>
462
+ <family>Courier New</family>
463
+ </default>
464
+ </alias>
465
+
466
+ <!-- Microsoft -->
467
+ <alias>
468
+ <family>Arial</family>
469
+ <default>
470
+ <family>Helvetica</family>
471
+ </default>
472
+ </alias>
473
+
474
+ <alias>
475
+ <family>Arial Narrow</family>
476
+ <default>
477
+ <family>Helvetica Narrow</family>
478
+ </default>
479
+ </alias>
480
+
481
+ <alias>
482
+ <family>Times New Roman</family>
483
+ <default>
484
+ <family>Times</family>
485
+ </default>
486
+ </alias>
487
+
488
+ <alias>
489
+ <family>Courier New</family>
490
+ <default>
491
+ <family>Courier</family>
492
+ </default>
493
+ </alias>
494
+
495
+ <!-- Map generics to specifics -->
496
+
497
+ <!-- PostScript -->
498
+ <alias binding="same">
499
+ <family>Helvetica</family>
500
+ <accept>
501
+ <family>TeX Gyre Heros</family>
502
+ </accept>
503
+ </alias>
504
+
505
+ <alias binding="same">
506
+ <family>Helvetica Narrow</family>
507
+ <accept>
508
+ <family>TeX Gyre Heros Cn</family>
509
+ </accept>
510
+ </alias>
511
+
512
+ <alias binding="same">
513
+ <family>Times</family>
514
+ <accept>
515
+ <family>TeX Gyre Termes</family>
516
+ </accept>
517
+ </alias>
518
+
519
+ <alias binding="same">
520
+ <family>Courier</family>
521
+ <accept>
522
+ <family>TeX Gyre Cursor</family>
523
+ </accept>
524
+ </alias>
525
+
526
+ <alias binding="same">
527
+ <family>Courier Std</family>
528
+ <accept>
529
+ <family>Courier</family>
530
+ </accept>
531
+ </alias>
532
+
533
+ <alias binding="same">
534
+ <family>ITC Avant Garde Gothic</family>
535
+ <accept>
536
+ <family>TeX Gyre Adventor</family>
537
+ </accept>
538
+ </alias>
539
+
540
+ <alias binding="same">
541
+ <family>ITC Bookman</family>
542
+ <accept>
543
+ <family>Bookman Old Style</family>
544
+ <family>TeX Gyre Bonum</family>
545
+ </accept>
546
+ </alias>
547
+
548
+ <alias binding="same">
549
+ <family>ITC Zapf Chancery</family>
550
+ <accept>
551
+ <family>TeX Gyre Chorus</family>
552
+ </accept>
553
+ </alias>
554
+
555
+ <alias binding="same">
556
+ <family>Palatino</family>
557
+ <accept>
558
+ <family>Palatino Linotype</family>
559
+ <family>TeX Gyre Pagella</family>
560
+ </accept>
561
+ </alias>
562
+
563
+ <alias binding="same">
564
+ <family>New Century Schoolbook</family>
565
+ <accept>
566
+ <family>Century Schoolbook</family>
567
+ <family>TeX Gyre Schola</family>
568
+ </accept>
569
+ </alias>
570
+
571
+ <!-- Microsoft -->
572
+ <alias binding="same">
573
+ <family>Arial</family>
574
+ <accept>
575
+ <family>Arimo</family>
576
+ <family>Liberation Sans</family>
577
+ <family>Albany</family>
578
+ <family>Albany AMT</family>
579
+ </accept>
580
+ </alias>
581
+
582
+ <alias binding="same">
583
+ <family>Arial Narrow</family>
584
+ <accept>
585
+ <family>Liberation Sans Narrow</family>
586
+ </accept>
587
+ </alias>
588
+
589
+ <alias binding="same">
590
+ <family>Times New Roman</family>
591
+ <accept>
592
+ <family>Tinos</family>
593
+ <family>Liberation Serif</family>
594
+ <family>Thorndale</family>
595
+ <family>Thorndale AMT</family>
596
+ </accept>
597
+ </alias>
598
+
599
+ <alias binding="same">
600
+ <family>Courier New</family>
601
+ <accept>
602
+ <family>Cousine</family>
603
+ <family>Liberation Mono</family>
604
+ <family>Cumberland</family>
605
+ <family>Cumberland AMT</family>
606
+ </accept>
607
+ </alias>
608
+
609
+ <alias binding="same">
610
+ <family>Georgia</family>
611
+ <accept>
612
+ <family>Gelasio</family>
613
+ </accept>
614
+ </alias>
615
+
616
+ <alias binding="same">
617
+ <family>Cambria</family>
618
+ <accept>
619
+ <family>Caladea</family>
620
+ </accept>
621
+ </alias>
622
+
623
+ <alias binding="same">
624
+ <family>Calibri</family>
625
+ <accept>
626
+ <family>Carlito</family>
627
+ </accept>
628
+ </alias>
629
+
630
+ <alias binding="same">
631
+ <family>Symbol</family>
632
+ <accept>
633
+ <family>SymbolNeu</family>
634
+ </accept>
635
+ </alias>
636
+
637
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/40-nonlatin.conf ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set substitutions for non-Latin fonts</description>
5
+ <!--
6
+ Mark common families with their generics so we'll get
7
+ something reasonable
8
+ -->
9
+
10
+ <!--
11
+ Serif faces
12
+ -->
13
+ <alias>
14
+ <family>Nazli</family>
15
+ <default><family>serif</family></default>
16
+ </alias>
17
+ <alias>
18
+ <family>Lotoos</family>
19
+ <default><family>serif</family></default>
20
+ </alias>
21
+ <alias>
22
+ <family>Mitra</family>
23
+ <default><family>serif</family></default>
24
+ </alias>
25
+ <alias>
26
+ <family>Ferdosi</family>
27
+ <default><family>serif</family></default>
28
+ </alias>
29
+ <alias>
30
+ <family>Badr</family>
31
+ <default><family>serif</family></default>
32
+ </alias>
33
+ <alias>
34
+ <family>Zar</family>
35
+ <default><family>serif</family></default>
36
+ </alias>
37
+ <alias>
38
+ <family>Titr</family>
39
+ <default><family>serif</family></default>
40
+ </alias>
41
+ <alias>
42
+ <family>Jadid</family>
43
+ <default><family>serif</family></default>
44
+ </alias>
45
+ <alias>
46
+ <family>Kochi Mincho</family>
47
+ <default><family>serif</family></default>
48
+ </alias>
49
+ <alias>
50
+ <family>AR PL SungtiL GB</family>
51
+ <default><family>serif</family></default>
52
+ </alias>
53
+ <alias>
54
+ <family>AR PL Mingti2L Big5</family>
55
+ <default><family>serif</family></default>
56
+ </alias>
57
+ <alias>
58
+ <family>MS 明朝</family>
59
+ <default><family>serif</family></default>
60
+ </alias>
61
+ <alias>
62
+ <family>NanumMyeongjo</family>
63
+ <default><family>serif</family></default>
64
+ </alias>
65
+ <alias>
66
+ <family>UnBatang</family>
67
+ <default><family>serif</family></default>
68
+ </alias>
69
+ <alias>
70
+ <family>Baekmuk Batang</family>
71
+ <default><family>serif</family></default>
72
+ </alias>
73
+ <alias>
74
+ <family>MgOpen Canonica</family>
75
+ <default><family>serif</family></default>
76
+ </alias>
77
+ <alias>
78
+ <family>Sazanami Mincho</family>
79
+ <default><family>serif</family></default>
80
+ </alias>
81
+ <alias>
82
+ <family>AR PL ZenKai Uni</family>
83
+ <default><family>serif</family></default>
84
+ </alias>
85
+ <alias>
86
+ <family>ZYSong18030</family>
87
+ <default><family>serif</family></default>
88
+ </alias>
89
+ <alias>
90
+ <family>FreeSerif</family>
91
+ <default><family>serif</family></default>
92
+ </alias>
93
+ <alias>
94
+ <family>SimSun</family>
95
+ <default><family>serif</family></default>
96
+ </alias>
97
+ <!--
98
+ Sans-serif faces
99
+ -->
100
+ <alias>
101
+ <family>Arshia</family>
102
+ <default><family>sans-serif</family></default>
103
+ </alias>
104
+ <alias>
105
+ <family>Elham</family>
106
+ <default><family>sans-serif</family></default>
107
+ </alias>
108
+ <alias>
109
+ <family>Farnaz</family>
110
+ <default><family>sans-serif</family></default>
111
+ </alias>
112
+ <alias>
113
+ <family>Nasim</family>
114
+ <default><family>sans-serif</family></default>
115
+ </alias>
116
+ <alias>
117
+ <family>Sina</family>
118
+ <default><family>sans-serif</family></default>
119
+ </alias>
120
+ <alias>
121
+ <family>Roya</family>
122
+ <default><family>sans-serif</family></default>
123
+ </alias>
124
+ <alias>
125
+ <family>Koodak</family>
126
+ <default><family>sans-serif</family></default>
127
+ </alias>
128
+ <alias>
129
+ <family>Terafik</family>
130
+ <default><family>sans-serif</family></default>
131
+ </alias>
132
+ <alias>
133
+ <family>Kochi Gothic</family>
134
+ <default><family>sans-serif</family></default>
135
+ </alias>
136
+ <alias>
137
+ <family>AR PL KaitiM GB</family>
138
+ <default><family>sans-serif</family></default>
139
+ </alias>
140
+ <alias>
141
+ <family>AR PL KaitiM Big5</family>
142
+ <default><family>sans-serif</family></default>
143
+ </alias>
144
+ <alias>
145
+ <family>MS ゴシック</family>
146
+ <default><family>sans-serif</family></default>
147
+ </alias>
148
+ <alias>
149
+ <family>NanumGothic</family>
150
+ <default><family>sans-serif</family></default>
151
+ </alias>
152
+ <alias>
153
+ <family>UnDotum</family>
154
+ <default><family>sans-serif</family></default>
155
+ </alias>
156
+ <alias>
157
+ <family>Baekmuk Dotum</family>
158
+ <default><family>sans-serif</family></default>
159
+ </alias>
160
+ <alias>
161
+ <family>MgOpen Modata</family>
162
+ <default><family>sans-serif</family></default>
163
+ </alias>
164
+ <alias>
165
+ <family>Sazanami Gothic</family>
166
+ <default><family>sans-serif</family></default>
167
+ </alias>
168
+ <alias>
169
+ <family>AR PL ShanHeiSun Uni</family>
170
+ <default><family>sans-serif</family></default>
171
+ </alias>
172
+ <alias>
173
+ <family>ZYSong18030</family>
174
+ <default><family>sans-serif</family></default>
175
+ </alias>
176
+ <alias>
177
+ <family>FreeSans</family>
178
+ <default><family>sans-serif</family></default>
179
+ </alias>
180
+ <!--
181
+ Monospace faces
182
+ -->
183
+ <alias>
184
+ <family>NSimSun</family>
185
+ <default><family>monospace</family></default>
186
+ </alias>
187
+ <alias>
188
+ <family>ZYSong18030</family>
189
+ <default><family>monospace</family></default>
190
+ </alias>
191
+ <alias>
192
+ <family>NanumGothicCoding</family>
193
+ <default><family>monospace</family></default>
194
+ </alias>
195
+ <alias>
196
+ <family>FreeMono</family>
197
+ <default><family>monospace</family></default>
198
+ </alias>
199
+
200
+ <!--
201
+ Fantasy faces
202
+ -->
203
+ <alias>
204
+ <family>Homa</family>
205
+ <default><family>fantasy</family></default>
206
+ </alias>
207
+ <alias>
208
+ <family>Kamran</family>
209
+ <default><family>fantasy</family></default>
210
+ </alias>
211
+ <alias>
212
+ <family>Fantezi</family>
213
+ <default><family>fantasy</family></default>
214
+ </alias>
215
+ <alias>
216
+ <family>Tabassom</family>
217
+ <default><family>fantasy</family></default>
218
+ </alias>
219
+
220
+ <!--
221
+ Cursive faces
222
+ -->
223
+ <alias>
224
+ <family>IranNastaliq</family>
225
+ <default><family>cursive</family></default>
226
+ </alias>
227
+ <alias>
228
+ <family>Nafees Nastaleeq</family>
229
+ <default><family>cursive</family></default>
230
+ </alias>
231
+
232
+ <!--
233
+ system-ui
234
+ -->
235
+ <alias>
236
+ <family>Noto Sans Arabic UI</family>
237
+ <default><family>system-ui</family></default>
238
+ </alias>
239
+ <alias>
240
+ <family>Noto Sans Bengali UI</family>
241
+ <default><family>system-ui</family></default>
242
+ </alias>
243
+ <alias>
244
+ <family>Noto Sans Devanagari UI</family>
245
+ <default><family>system-ui</family></default>
246
+ </alias>
247
+ <alias>
248
+ <family>Noto Sans Gujarati UI</family>
249
+ <default><family>system-ui</family></default>
250
+ </alias>
251
+ <alias>
252
+ <family>Noto Sans Gurmukhi UI</family>
253
+ <default><family>system-ui</family></default>
254
+ </alias>
255
+ <alias>
256
+ <family>Noto Sans Kannada UI</family>
257
+ <default><family>system-ui</family></default>
258
+ </alias>
259
+ <alias>
260
+ <family>Noto Sans Khmer UI</family>
261
+ <default><family>system-ui</family></default>
262
+ </alias>
263
+ <alias>
264
+ <family>Noto Sans Lao UI</family>
265
+ <default><family>system-ui</family></default>
266
+ </alias>
267
+ <alias>
268
+ <family>Noto Sans Malayalam UI</family>
269
+ <default><family>system-ui</family></default>
270
+ </alias>
271
+ <alias>
272
+ <family>Noto Sans Myanmar UI</family>
273
+ <default><family>system-ui</family></default>
274
+ </alias>
275
+ <alias>
276
+ <family>Noto Sans Oriya UI</family>
277
+ <default><family>system-ui</family></default>
278
+ </alias>
279
+ <alias>
280
+ <family>Noto Sans Sinhala UI</family>
281
+ <default><family>system-ui</family></default>
282
+ </alias>
283
+ <alias>
284
+ <family>Noto Sans Tamil UI</family>
285
+ <default><family>system-ui</family></default>
286
+ </alias>
287
+ <alias>
288
+ <family>Noto Sans Telugu UI</family>
289
+ <default><family>system-ui</family></default>
290
+ </alias>
291
+ <alias>
292
+ <family>Noto Sans Thai UI</family>
293
+ <default><family>system-ui</family></default>
294
+ </alias>
295
+ <alias>
296
+ <family>Leelawadee UI</family>
297
+ <default><family>system-ui</family></default>
298
+ </alias>
299
+ <alias>
300
+ <family>Nirmala UI</family>
301
+ <default><family>system-ui</family></default>
302
+ </alias>
303
+ <alias>
304
+ <family>Yu Gothic UI</family>
305
+ <default><family>system-ui</family></default>
306
+ </alias>
307
+ <alias>
308
+ <family>Meiryo UI</family>
309
+ <default><family>system-ui</family></default>
310
+ </alias>
311
+ <alias>
312
+ <family>MS UI Gothic</family>
313
+ <default><family>system-ui</family></default>
314
+ </alias>
315
+ <alias>
316
+ <family>Khmer UI</family>
317
+ <default><family>system-ui</family></default>
318
+ </alias>
319
+ <alias>
320
+ <family>Lao UI</family>
321
+ <default><family>system-ui</family></default>
322
+ </alias>
323
+ <alias>
324
+ <family>Microsoft JhengHei UI</family>
325
+ <default><family>system-ui</family></default>
326
+ </alias>
327
+ <alias>
328
+ <family>Microsoft YaHei UI</family>
329
+ <default><family>system-ui</family></default>
330
+ </alias>
331
+
332
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/45-generic.conf ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set substitutions for emoji/math fonts</description>
5
+
6
+ <!-- Keep in sync with 60-generic.conf -->
7
+
8
+ <!-- Emoji -->
9
+
10
+ <!-- System emoji -->
11
+ <alias binding="same">
12
+ <family>Noto Color Emoji</family> <!-- Google -->
13
+ <default><family>emoji</family></default>
14
+ </alias>
15
+ <alias binding="same">
16
+ <family>Apple Color Emoji</family> <!-- Apple -->
17
+ <default><family>emoji</family></default>
18
+ </alias>
19
+ <alias binding="same">
20
+ <family>Segoe UI Emoji</family> <!-- Microsoft -->
21
+ <default><family>emoji</family></default>
22
+ </alias>
23
+ <alias binding="same">
24
+ <family>Twitter Color Emoji</family> <!-- Twitter -->
25
+ <default><family>emoji</family></default>
26
+ </alias>
27
+ <alias binding="same">
28
+ <family>EmojiOne Mozilla</family> <!-- Mozilla -->
29
+ <default><family>emoji</family></default>
30
+ </alias>
31
+ <!-- Third-party emoji -->
32
+ <alias binding="same">
33
+ <family>Emoji Two</family>
34
+ <default><family>emoji</family></default>
35
+ </alias>
36
+ <alias binding="same">
37
+ <family>JoyPixels</family>
38
+ <default><family>emoji</family></default>
39
+ </alias>
40
+ <alias binding="same">
41
+ <family>Emoji One</family>
42
+ <default><family>emoji</family></default>
43
+ </alias>
44
+ <!-- B&W -->
45
+ <alias binding="same">
46
+ <family>Noto Emoji</family> <!-- Google -->
47
+ <default><family>emoji</family></default>
48
+ </alias>
49
+ <alias binding="same">
50
+ <family>Android Emoji</family> <!-- Google -->
51
+ <default><family>emoji</family></default>
52
+ </alias>
53
+
54
+ <!-- Add language for emoji, to match other emoji fonts. -->
55
+ <match>
56
+ <test name="family">
57
+ <string>emoji</string>
58
+ </test>
59
+ <edit name="lang" mode="prepend">
60
+ <string>und-zsye</string>
61
+ </edit>
62
+ </match>
63
+
64
+ <match>
65
+ <test name="lang">
66
+ <string>und-zsye</string>
67
+ </test>
68
+ <test qual="all" name="family" compare="not_eq">
69
+ <string>emoji</string>
70
+ </test>
71
+
72
+ <!-- Add generic family. -->
73
+ <edit name="family" mode="append" binding="strong">
74
+ <string>emoji</string>
75
+ </edit>
76
+ </match>
77
+
78
+
79
+ <!-- Math -->
80
+
81
+ <!-- https://en.wikipedia.org/wiki/Category:Mathematical_OpenType_typefaces -->
82
+ <alias binding="same">
83
+ <family>XITS Math</family> <!-- Khaled Hosny -->
84
+ <default><family>math</family></default>
85
+ </alias>
86
+ <alias binding="same">
87
+ <family>STIX Two Math</family> <!-- AMS -->
88
+ <default><family>math</family></default>
89
+ </alias>
90
+ <alias binding="same">
91
+ <family>Cambria Math</family> <!-- Microsoft -->
92
+ <default><family>math</family></default>
93
+ </alias>
94
+ <alias binding="same">
95
+ <family>Latin Modern Math</family> <!-- TeX -->
96
+ <default><family>math</family></default>
97
+ </alias>
98
+ <alias binding="same">
99
+ <family>Minion Math</family> <!-- Adobe -->
100
+ <default><family>math</family></default>
101
+ </alias>
102
+ <alias binding="same">
103
+ <family>Lucida Math</family> <!-- Adobe -->
104
+ <default><family>math</family></default>
105
+ </alias>
106
+ <alias binding="same">
107
+ <family>Asana Math</family>
108
+ <default><family>math</family></default>
109
+ </alias>
110
+
111
+ <!-- Add language for math, to match other math fonts. -->
112
+ <match>
113
+ <test name="family">
114
+ <string>math</string>
115
+ </test>
116
+ <edit name="lang" mode="prepend">
117
+ <string>und-zmth</string>
118
+ </edit>
119
+ </match>
120
+
121
+ <match>
122
+ <test name="lang">
123
+ <string>und-zmth</string>
124
+ </test>
125
+ <test qual="all" name="family" compare="not_eq">
126
+ <string>math</string>
127
+ </test>
128
+
129
+ <!-- Add generic family -->
130
+ <edit name="family" mode="append" binding="strong">
131
+ <string>math</string>
132
+ </edit>
133
+ </match>
134
+
135
+
136
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/45-latin.conf ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set substitutions for Latin fonts</description>
5
+ <!--
6
+ Mark common families with their generics so we'll get
7
+ something reasonable
8
+ -->
9
+
10
+ <!--
11
+ Serif faces
12
+ -->
13
+ <alias>
14
+ <family>Bitstream Vera Serif</family>
15
+ <default><family>serif</family></default>
16
+ </alias>
17
+ <alias>
18
+ <family>Cambria</family>
19
+ <default><family>serif</family></default>
20
+ </alias>
21
+ <alias>
22
+ <family>Constantia</family>
23
+ <default><family>serif</family></default>
24
+ </alias>
25
+ <alias>
26
+ <family>DejaVu Serif</family>
27
+ <default><family>serif</family></default>
28
+ </alias>
29
+ <alias>
30
+ <family>Elephant</family>
31
+ <default><family>serif</family></default>
32
+ </alias>
33
+ <alias>
34
+ <family>Garamond</family>
35
+ <default><family>serif</family></default>
36
+ </alias>
37
+ <alias>
38
+ <family>Georgia</family>
39
+ <default><family>serif</family></default>
40
+ </alias>
41
+ <alias>
42
+ <family>Liberation Serif</family>
43
+ <default><family>serif</family></default>
44
+ </alias>
45
+ <alias>
46
+ <family>Luxi Serif</family>
47
+ <default><family>serif</family></default>
48
+ </alias>
49
+ <alias>
50
+ <family>MS Serif</family>
51
+ <default><family>serif</family></default>
52
+ </alias>
53
+ <alias>
54
+ <family>Nimbus Roman No9 L</family>
55
+ <default><family>serif</family></default>
56
+ </alias>
57
+ <alias>
58
+ <family>Nimbus Roman</family>
59
+ <default><family>serif</family></default>
60
+ </alias>
61
+ <alias>
62
+ <family>Palatino Linotype</family>
63
+ <default><family>serif</family></default>
64
+ </alias>
65
+ <alias>
66
+ <family>Thorndale AMT</family>
67
+ <default><family>serif</family></default>
68
+ </alias>
69
+ <alias>
70
+ <family>Thorndale</family>
71
+ <default><family>serif</family></default>
72
+ </alias>
73
+ <alias>
74
+ <family>Times New Roman</family>
75
+ <default><family>serif</family></default>
76
+ </alias>
77
+ <alias>
78
+ <family>Times</family>
79
+ <default><family>serif</family></default>
80
+ </alias>
81
+ <!--
82
+ Sans-serif faces
83
+ -->
84
+ <alias>
85
+ <family>Albany AMT</family>
86
+ <default><family>sans-serif</family></default>
87
+ </alias>
88
+ <alias>
89
+ <family>Albany</family>
90
+ <default><family>sans-serif</family></default>
91
+ </alias>
92
+ <alias>
93
+ <family>Arial Unicode MS</family>
94
+ <default><family>sans-serif</family></default>
95
+ </alias>
96
+ <alias>
97
+ <family>Arial</family>
98
+ <default><family>sans-serif</family></default>
99
+ </alias>
100
+ <alias>
101
+ <family>Bitstream Vera Sans</family>
102
+ <default><family>sans-serif</family></default>
103
+ </alias>
104
+ <alias>
105
+ <family>Britannic</family>
106
+ <default><family>sans-serif</family></default>
107
+ </alias>
108
+ <alias>
109
+ <family>Calibri</family>
110
+ <default><family>sans-serif</family></default>
111
+ </alias>
112
+ <alias>
113
+ <family>Candara</family>
114
+ <default><family>sans-serif</family></default>
115
+ </alias>
116
+ <alias>
117
+ <family>Century Gothic</family>
118
+ <default><family>sans-serif</family></default>
119
+ </alias>
120
+ <alias>
121
+ <family>Corbel</family>
122
+ <default><family>sans-serif</family></default>
123
+ </alias>
124
+ <alias>
125
+ <family>DejaVu Sans</family>
126
+ <default><family>sans-serif</family></default>
127
+ </alias>
128
+ <alias>
129
+ <family>Helvetica</family>
130
+ <default><family>sans-serif</family></default>
131
+ </alias>
132
+ <alias>
133
+ <family>Haettenschweiler</family>
134
+ <default><family>sans-serif</family></default>
135
+ </alias>
136
+ <alias>
137
+ <family>Liberation Sans</family>
138
+ <default><family>sans-serif</family></default>
139
+ </alias>
140
+ <alias>
141
+ <family>MS Sans Serif</family>
142
+ <default><family>sans-serif</family></default>
143
+ </alias>
144
+ <alias>
145
+ <family>Nimbus Sans L</family>
146
+ <default><family>sans-serif</family></default>
147
+ </alias>
148
+ <alias>
149
+ <family>Nimbus Sans</family>
150
+ <default><family>sans-serif</family></default>
151
+ </alias>
152
+ <alias>
153
+ <family>Luxi Sans</family>
154
+ <default><family>sans-serif</family></default>
155
+ </alias>
156
+ <alias>
157
+ <family>Tahoma</family>
158
+ <default><family>sans-serif</family></default>
159
+ </alias>
160
+ <alias>
161
+ <family>Trebuchet MS</family>
162
+ <default><family>sans-serif</family></default>
163
+ </alias>
164
+ <alias>
165
+ <family>Twentieth Century</family>
166
+ <default><family>sans-serif</family></default>
167
+ </alias>
168
+ <alias>
169
+ <family>Verdana</family>
170
+ <default><family>sans-serif</family></default>
171
+ </alias>
172
+ <!--
173
+ Monospace faces
174
+ -->
175
+ <alias>
176
+ <family>Andale Mono</family>
177
+ <default><family>monospace</family></default>
178
+ </alias>
179
+ <alias>
180
+ <family>Bitstream Vera Sans Mono</family>
181
+ <default><family>monospace</family></default>
182
+ </alias>
183
+ <alias>
184
+ <family>Consolas</family>
185
+ <default><family>monospace</family></default>
186
+ </alias>
187
+ <alias>
188
+ <family>Courier New</family>
189
+ <default><family>monospace</family></default>
190
+ </alias>
191
+ <alias>
192
+ <family>Courier</family>
193
+ <default><family>monospace</family></default>
194
+ </alias>
195
+ <alias>
196
+ <family>Courier Std</family>
197
+ <default><family>monospace</family></default>
198
+ </alias>
199
+ <alias>
200
+ <family>Cumberland AMT</family>
201
+ <default><family>monospace</family></default>
202
+ </alias>
203
+ <alias>
204
+ <family>Cumberland</family>
205
+ <default><family>monospace</family></default>
206
+ </alias>
207
+ <alias>
208
+ <family>DejaVu Sans Mono</family>
209
+ <default><family>monospace</family></default>
210
+ </alias>
211
+ <alias>
212
+ <family>Fixedsys</family>
213
+ <default><family>monospace</family></default>
214
+ </alias>
215
+ <alias>
216
+ <family>Inconsolata</family>
217
+ <default><family>monospace</family></default>
218
+ </alias>
219
+ <alias>
220
+ <family>Liberation Mono</family>
221
+ <default><family>monospace</family></default>
222
+ </alias>
223
+ <alias>
224
+ <family>Luxi Mono</family>
225
+ <default><family>monospace</family></default>
226
+ </alias>
227
+ <alias>
228
+ <family>Nimbus Mono L</family>
229
+ <default><family>monospace</family></default>
230
+ </alias>
231
+ <alias>
232
+ <family>Nimbus Mono</family>
233
+ <default><family>monospace</family></default>
234
+ </alias>
235
+ <alias>
236
+ <family>Nimbus Mono PS</family>
237
+ <default><family>monospace</family></default>
238
+ </alias>
239
+ <alias>
240
+ <family>Terminal</family>
241
+ <default><family>monospace</family></default>
242
+ </alias>
243
+ <!--
244
+ Fantasy faces
245
+ -->
246
+ <alias>
247
+ <family>Bauhaus Std</family>
248
+ <default><family>fantasy</family></default>
249
+ </alias>
250
+ <alias>
251
+ <family>Cooper Std</family>
252
+ <default><family>fantasy</family></default>
253
+ </alias>
254
+ <alias>
255
+ <family>Copperplate Gothic Std</family>
256
+ <default><family>fantasy</family></default>
257
+ </alias>
258
+ <alias>
259
+ <family>Impact</family>
260
+ <default><family>fantasy</family></default>
261
+ </alias>
262
+ <!--
263
+ Cursive faces
264
+ -->
265
+ <alias>
266
+ <family>Comic Sans MS</family>
267
+ <default><family>cursive</family></default>
268
+ </alias>
269
+ <alias>
270
+ <family>ITC Zapf Chancery Std</family>
271
+ <default><family>cursive</family></default>
272
+ </alias>
273
+ <alias>
274
+ <family>Zapfino</family>
275
+ <default><family>cursive</family></default>
276
+ </alias>
277
+ <!--
278
+ system-ui
279
+ -->
280
+ <alias>
281
+ <family>Cantarell</family>
282
+ <default><family>system-ui</family></default>
283
+ </alias>
284
+ <alias>
285
+ <family>Noto Sans UI</family>
286
+ <default><family>system-ui</family></default>
287
+ </alias>
288
+ <alias>
289
+ <family>Segoe UI</family>
290
+ <default><family>system-ui</family></default>
291
+ </alias>
292
+ <alias>
293
+ <family>Segoe UI Historic</family>
294
+ <default><family>system-ui</family></default>
295
+ </alias>
296
+ <alias>
297
+ <family>Segoe UI Symbol</family>
298
+ <default><family>system-ui</family></default>
299
+ </alias>
300
+
301
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/48-spacing.conf ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Add mono to the family when spacing is 100</description>
5
+ <!--
6
+ If the request specifies spacing 100, add monospace to family
7
+ -->
8
+ <match target="pattern">
9
+ <test qual="any" name="spacing" compare="eq">
10
+ <int>100</int>
11
+ </test>
12
+ <edit name="family" mode="prepend">
13
+ <string>monospace</string>
14
+ </edit>
15
+ </match>
16
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/49-sansserif.conf ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Add sans-serif to the family when no generic name</description>
5
+ <!--
6
+ If the font still has no generic name, add sans-serif
7
+ -->
8
+ <match target="pattern">
9
+ <test qual="all" name="family" compare="not_eq">
10
+ <string>sans-serif</string>
11
+ </test>
12
+ <test qual="all" name="family" compare="not_eq">
13
+ <string>serif</string>
14
+ </test>
15
+ <test qual="all" name="family" compare="not_eq">
16
+ <string>monospace</string>
17
+ </test>
18
+ <edit name="family" mode="append_last">
19
+ <string>sans-serif</string>
20
+ </edit>
21
+ </match>
22
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/50-user.conf ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Load per-user customization files</description>
5
+ <!--
6
+ Load per-user customization files where stored on XDG Base Directory
7
+ specification compliant places. it should be usually:
8
+ $HOME/.config/fontconfig/conf.d
9
+ $HOME/.config/fontconfig/fonts.conf
10
+ -->
11
+ <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include>
12
+ <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include>
13
+ <!-- the following elements will be removed in the future -->
14
+ <include ignore_missing="yes" deprecated="yes">~/.fonts.conf.d</include>
15
+ <include ignore_missing="yes" deprecated="yes">~/.fonts.conf</include>
16
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/51-local.conf ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Load local customization file</description>
5
+ <!-- Load local system customization file -->
6
+ <include ignore_missing="yes">local.conf</include>
7
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/60-generic.conf ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set preferable fonts for emoji/math fonts</description>
5
+ <!-- Keep in sync with 45-generic.conf -->
6
+
7
+ <!-- Emoji -->
8
+
9
+ <!-- Prefer to match color emoji font. -->
10
+ <match>
11
+ <test name="lang">
12
+ <string>und-zsye</string>
13
+ </test>
14
+ <test qual="all" name="color" compare="not_eq">
15
+ <bool>true</bool>
16
+ </test>
17
+ <test qual="all" name="color" compare="not_eq">
18
+ <bool>false</bool>
19
+ </test>
20
+ <edit name="color" mode="append">
21
+ <bool>true</bool>
22
+ </edit>
23
+ </match>
24
+
25
+ <!-- TODO
26
+ ! Match on "color" and alias B&W ones first if no color is requested.
27
+ ! That's "hard" because <alias> doesn't work in match and needs to be
28
+ ! expanded to its non-sugar form.
29
+ !-->
30
+ <alias binding="same">
31
+ <family>emoji</family>
32
+ <prefer>
33
+ <!-- System fonts -->
34
+ <family>Noto Color Emoji</family> <!-- Google -->
35
+ <family>Apple Color Emoji</family> <!-- Apple -->
36
+ <family>Segoe UI Emoji</family> <!-- Microsoft -->
37
+ <family>Twitter Color Emoji</family> <!-- Twitter -->
38
+ <family>EmojiOne Mozilla</family> <!-- Mozilla -->
39
+ <!-- Third-Party fonts -->
40
+ <family>Emoji Two</family>
41
+ <family>JoyPixels</family>
42
+ <family>Emoji One</family>
43
+ <!-- Non-color -->
44
+ <family>Noto Emoji</family> <!-- Google -->
45
+ <family>Android Emoji</family> <!-- Google -->
46
+ </prefer>
47
+ </alias>
48
+
49
+ <!-- Math -->
50
+ <alias binding="same">
51
+ <!-- https://en.wikipedia.org/wiki/Category:Mathematical_OpenType_typefaces -->
52
+ <family>math</family>
53
+ <prefer>
54
+ <family>XITS Math</family> <!-- Khaled Hosny -->
55
+ <family>STIX Two Math</family> <!-- AMS -->
56
+ <family>Cambria Math</family> <!-- Microsoft -->
57
+ <family>Latin Modern Math</family> <!-- TeX -->
58
+ <family>Minion Math</family> <!-- Adobe -->
59
+ <family>Lucida Math</family> <!-- Adobe -->
60
+ <family>Asana Math</family>
61
+ </prefer>
62
+ </alias>
63
+
64
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/60-latin.conf ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set preferable fonts for Latin</description>
5
+ <alias>
6
+ <family>serif</family>
7
+ <prefer>
8
+ <family>Noto Serif</family>
9
+ <family>DejaVu Serif</family>
10
+ <family>Times New Roman</family>
11
+ <family>Thorndale AMT</family>
12
+ <family>Luxi Serif</family>
13
+ <family>Nimbus Roman No9 L</family>
14
+ <family>Nimbus Roman</family>
15
+ <family>Times</family>
16
+ </prefer>
17
+ </alias>
18
+ <alias>
19
+ <family>sans-serif</family>
20
+ <prefer>
21
+ <family>Noto Sans</family>
22
+ <family>DejaVu Sans</family>
23
+ <family>Verdana</family>
24
+ <family>Arial</family>
25
+ <family>Albany AMT</family>
26
+ <family>Luxi Sans</family>
27
+ <family>Nimbus Sans L</family>
28
+ <family>Nimbus Sans</family>
29
+ <family>Helvetica</family>
30
+ <family>Lucida Sans Unicode</family>
31
+ <family>BPG Glaho International</family> <!-- lat,cyr,arab,geor -->
32
+ <family>Tahoma</family> <!-- lat,cyr,greek,heb,arab,thai -->
33
+ </prefer>
34
+ </alias>
35
+ <alias>
36
+ <family>monospace</family>
37
+ <prefer>
38
+ <family>Noto Sans Mono</family>
39
+ <family>DejaVu Sans Mono</family>
40
+ <family>Inconsolata</family>
41
+ <family>Andale Mono</family>
42
+ <family>Courier New</family>
43
+ <family>Cumberland AMT</family>
44
+ <family>Luxi Mono</family>
45
+ <family>Nimbus Mono L</family>
46
+ <family>Nimbus Mono</family>
47
+ <family>Nimbus Mono PS</family>
48
+ <family>Courier</family>
49
+ </prefer>
50
+ </alias>
51
+ <!--
52
+ Fantasy faces
53
+ -->
54
+ <alias>
55
+ <family>fantasy</family>
56
+ <prefer>
57
+ <family>Impact</family>
58
+ <family>Copperplate Gothic Std</family>
59
+ <family>Cooper Std</family>
60
+ <family>Bauhaus Std</family>
61
+ </prefer>
62
+ </alias>
63
+ <!--
64
+ Cursive faces
65
+ -->
66
+ <alias>
67
+ <family>cursive</family>
68
+ <prefer>
69
+ <family>ITC Zapf Chancery Std</family>
70
+ <family>Zapfino</family>
71
+ <family>Comic Sans MS</family>
72
+ </prefer>
73
+ </alias>
74
+ <!--
75
+ system-ui
76
+ -->
77
+ <alias>
78
+ <family>system-ui</family>
79
+ <prefer>
80
+ <family>Cantarell</family>
81
+ <family>Noto Sans UI</family>
82
+ <family>Segoe UI</family>
83
+ <family>Segoe UI Historic</family>
84
+ <family>Segoe UI Symbol</family>
85
+ </prefer>
86
+ </alias>
87
+
88
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/65-fonts-persian.conf ADDED
@@ -0,0 +1,418 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <!--
4
+ fonts-persian.conf
5
+ To configure Persian fonts from The FarsiWeb Project.
6
+
7
+ Copyright (C) 2005 Sharif FarsiWeb, Inc. <[email protected]>
8
+
9
+ Permission to use, copy, modify, distribute, and sell this software and its
10
+ documentation for any purpose is hereby granted without fee, provided that
11
+ the above copyright notice appear in all copies and that both that
12
+ copyright notice and this permission notice appear in supporting
13
+ documentation, and that the name of Sharif FarsiWeb, Inc. not be used in
14
+ advertising or publicity pertaining to distribution of the software without
15
+ specific, written prior permission. Sharif FarsiWeb, Inc. makes no
16
+ representations about the suitability of this software for any purpose. It
17
+ is provided "as is" without express or implied warranty.
18
+
19
+ SHARIF FARSIWEB, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
21
+ EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25
+ PERFORMANCE OF THIS SOFTWARE.
26
+
27
+ ChangeLog:
28
+ 2005-04-03 Behdad Esfahbod: Initial revision.
29
+ 2005-10-09 Behdad Esfahbod: Turned off back-slant and Tahoma sections.
30
+ 2005-11-30 Behdad Esfahbod: Set Titr susbtitution size to 24 points.
31
+ 2008 Behdad Esfahbod: Cleanup. Add fantasy and cursive.
32
+ -->
33
+ <fontconfig>
34
+
35
+ <!-- Deprecated fonts are discouraged -->
36
+
37
+ <!-- Nesf[2] is officially deprecated and has problematic tables -->
38
+ <alias binding="same">
39
+ <family>Nesf</family>
40
+ <accept><family>Nesf2</family></accept>
41
+ </alias>
42
+ <alias binding="same">
43
+ <family>Nesf2</family>
44
+ <accept><family>Persian_sansserif_default</family></accept>
45
+ </alias>
46
+
47
+ <!-- Name changes and spelling variant aliases -->
48
+
49
+ <alias binding="same">
50
+ <family>Nazanin</family>
51
+ <accept><family>Nazli</family></accept>
52
+ </alias>
53
+ <alias binding="same">
54
+ <family>Lotus</family>
55
+ <accept><family>Lotoos</family></accept>
56
+ </alias>
57
+ <alias binding="same">
58
+ <family>Yaqut</family>
59
+ <accept><family>Yaghoot</family></accept>
60
+ </alias>
61
+ <alias binding="same">
62
+ <family>Yaghut</family>
63
+ <accept><family>Yaghoot</family></accept>
64
+ </alias>
65
+ <alias binding="same">
66
+ <family>Traffic</family>
67
+ <accept><family>Terafik</family></accept>
68
+ </alias>
69
+ <alias binding="same">
70
+ <family>Ferdowsi</family>
71
+ <accept><family>Ferdosi</family></accept>
72
+ </alias>
73
+ <alias binding="same">
74
+ <family>Fantezy</family>
75
+ <accept><family>Fantezi</family></accept>
76
+ </alias>
77
+
78
+
79
+ <!-- Classify fonts. -->
80
+
81
+ <!-- Persian_title class -->
82
+ <alias binding="same">
83
+ <family>Jadid</family>
84
+ <accept><family>Persian_title</family></accept>
85
+ </alias>
86
+ <alias binding="same">
87
+ <family>Titr</family>
88
+ <accept><family>Persian_title</family></accept>
89
+ </alias>
90
+
91
+ <!-- Persian_fantasy class -->
92
+ <alias binding="same">
93
+ <family>Kamran</family>
94
+ <accept>
95
+ <family>Persian_fantasy</family>
96
+ <family>Homa</family>
97
+ </accept>
98
+ </alias>
99
+ <alias binding="same">
100
+ <family>Homa</family>
101
+ <accept>
102
+ <family>Persian_fantasy</family>
103
+ <family>Kamran</family>
104
+ </accept>
105
+ </alias>
106
+ <alias binding="same">
107
+ <family>Fantezi</family>
108
+ <accept><family>Persian_fantasy</family></accept>
109
+ </alias>
110
+ <alias binding="same">
111
+ <family>Tabassom</family>
112
+ <accept><family>Persian_fantasy</family></accept>
113
+ </alias>
114
+
115
+ <!-- Persian_square class -->
116
+ <alias binding="same">
117
+ <family>Arshia</family>
118
+ <accept><family>Persian_square</family></accept>
119
+ </alias>
120
+ <alias binding="same">
121
+ <family>Nasim</family>
122
+ <accept><family>Persian_square</family></accept>
123
+ </alias>
124
+ <alias binding="same">
125
+ <family>Elham</family>
126
+ <accept>
127
+ <family>Persian_square</family>
128
+ <family>Farnaz</family>
129
+ </accept>
130
+ </alias>
131
+ <alias binding="same">
132
+ <family>Farnaz</family>
133
+ <accept>
134
+ <family>Persian_square</family>
135
+ <family>Elham</family>
136
+ </accept>
137
+ </alias>
138
+ <alias binding="same">
139
+ <family>Sina</family>
140
+ <accept><family>Persian_square</family></accept>
141
+ </alias>
142
+
143
+ <!-- Font ordering per class -->
144
+
145
+ <!-- Persian_title class -->
146
+ <alias binding="same">
147
+ <family>Persian_title</family>
148
+ <accept>
149
+ <family>Titr</family>
150
+ <family>Jadid</family>
151
+ <family>Persian_serif</family>
152
+ </accept>
153
+ </alias>
154
+
155
+ <!-- Persian_fantasy class -->
156
+ <alias binding="same">
157
+ <family>Persian_fantasy</family>
158
+ <accept>
159
+ <family>Homa</family>
160
+ <family>Kamran</family>
161
+ <family>Fantezi</family>
162
+ <family>Tabassom</family>
163
+ <family>Persian_square</family>
164
+ </accept>
165
+ </alias>
166
+
167
+ <!-- Persian_square class -->
168
+ <alias binding="same">
169
+ <family>Persian_square</family>
170
+ <accept>
171
+ <family>Arshia</family>
172
+ <family>Elham</family>
173
+ <family>Farnaz</family>
174
+ <family>Nasim</family>
175
+ <family>Sina</family>
176
+ <family>Persian_serif</family>
177
+ </accept>
178
+ </alias>
179
+
180
+ <!-- Register the fonts that we actually do have -->
181
+
182
+ <match target="scan">
183
+ <test name="family" compare="eq" ignore-blanks="true">
184
+ <string>Elham</string>
185
+ </test>
186
+ <edit name="foundry">
187
+ <string>farsiweb</string>
188
+ </edit>
189
+ </match>
190
+
191
+ <match target="scan">
192
+ <test name="family" compare="eq" ignore-blanks="true">
193
+ <string>Homa</string>
194
+ </test>
195
+ <edit name="foundry">
196
+ <string>farsiweb</string>
197
+ </edit>
198
+ </match>
199
+
200
+ <match target="scan">
201
+ <test name="family" compare="eq" ignore-blanks="true">
202
+ <string>Koodak</string>
203
+ </test>
204
+ <edit name="foundry">
205
+ <string>farsiweb</string>
206
+ </edit>
207
+ </match>
208
+
209
+ <match target="scan">
210
+ <test name="family" compare="eq" ignore-blanks="true">
211
+ <string>Nazli</string>
212
+ </test>
213
+ <edit name="foundry">
214
+ <string>farsiweb</string>
215
+ </edit>
216
+ </match>
217
+
218
+ <match target="scan">
219
+ <test name="family" compare="eq" ignore-blanks="true">
220
+ <string>Roya</string>
221
+ </test>
222
+ <edit name="foundry">
223
+ <string>farsiweb</string>
224
+ </edit>
225
+ </match>
226
+
227
+ <match target="scan">
228
+ <test name="family" compare="eq" ignore-blanks="true">
229
+ <string>Terafik</string>
230
+ </test>
231
+ <edit name="foundry">
232
+ <string>farsiweb</string>
233
+ </edit>
234
+ </match>
235
+
236
+ <match target="scan">
237
+ <test name="family" compare="eq" ignore-blanks="true">
238
+ <string>Titr</string>
239
+ </test>
240
+ <edit name="foundry">
241
+ <string>farsiweb</string>
242
+ </edit>
243
+ </match>
244
+
245
+
246
+ <!-- Our fonts should oblique to the other side (TURNED-OFF) -->
247
+
248
+ <match target="font">
249
+ <test name="foundry">
250
+ <!--string>farsiweb</string-->
251
+ <string>TURNED-OFF</string>
252
+ </test>
253
+ <test name="foundry">
254
+ <string>farsiweb</string>
255
+ </test>
256
+ <!-- check to see if the font is roman -->
257
+ <test name="slant">
258
+ <const>roman</const>
259
+ </test>
260
+ <!-- check to see if the pattern requested non-roman -->
261
+ <test target="pattern" name="slant" compare="not_eq">
262
+ <const>roman</const>
263
+ </test>
264
+ <!-- multiply the matrix to slant the font -->
265
+ <edit name="matrix" mode="assign">
266
+ <times>
267
+ <name>matrix</name>
268
+ <matrix><double>1</double><double>-0.2</double>
269
+ <double>0</double><double>1</double>
270
+ </matrix>
271
+ </times>
272
+ </edit>
273
+ <!-- pretend the font is oblique now -->
274
+ <edit name="slant" mode="assign">
275
+ <const>oblique</const>
276
+ </edit>
277
+ </match>
278
+
279
+
280
+ <!--
281
+ We can't hint our fonts well, so turn off hinting.
282
+ Moreover, the bitmaps we have designed (well, they
283
+ have designed), suck, so disable them too.
284
+ -->
285
+
286
+ <match target="font">
287
+ <test name="foundry">
288
+ <string>farsiweb</string>
289
+ </test>
290
+ <edit name="autohint">
291
+ <bool>false</bool>
292
+ </edit>
293
+ <edit name="hinting">
294
+ <bool>false</bool>
295
+ </edit>
296
+ <edit name="embeddedbitmap">
297
+ <bool>false</bool>
298
+ </edit>
299
+ </match>
300
+
301
+
302
+ <!-- Alias our fonts to common families -->
303
+
304
+ <!-- Persian serif fonts -->
305
+ <alias>
306
+ <family>serif</family>
307
+ <accept>
308
+ <family>Nazli</family>
309
+ <family>Lotoos</family>
310
+ <family>Mitra</family>
311
+ <family>Ferdosi</family>
312
+ <family>Badr</family>
313
+ <family>Zar</family>
314
+ </accept>
315
+ </alias>
316
+
317
+ <!-- Persian sans-serif fonts -->
318
+ <alias>
319
+ <family>sans-serif</family>
320
+ <accept>
321
+ <family>Roya</family>
322
+ <family>Koodak</family>
323
+ <family>Terafik</family>
324
+ </accept>
325
+ </alias>
326
+
327
+ <!-- Persian monospace fonts -->
328
+ <alias>
329
+ <family>monospace</family>
330
+ <accept>
331
+ <!-- Not really monospace -->
332
+ <family>Terafik</family>
333
+ </accept>
334
+ </alias>
335
+
336
+ <!-- Persian fantasy fonts -->
337
+ <alias>
338
+ <family>fantasy</family>
339
+ <accept>
340
+ <family>Homa</family>
341
+ <family>Kamran</family>
342
+ <family>Fantezi</family>
343
+ <family>Tabassom</family>
344
+ </accept>
345
+ </alias>
346
+
347
+ <!-- Persian (and Urdu) Nastaliq/cursive fonts -->
348
+ <alias>
349
+ <family>cursive</family>
350
+ <accept>
351
+ <family>IranNastaliq</family>
352
+ <family>Nafees Nastaleeq</family>
353
+ </accept>
354
+ </alias>
355
+
356
+ <!-- Use Titr in titles -->
357
+
358
+ <!-- Both serif... -->
359
+ <match>
360
+ <test name="family">
361
+ <string>serif</string>
362
+ </test>
363
+ <test name="weight" compare="more_eq">
364
+ <int>200</int>
365
+ </test>
366
+ <test name="size" compare="more_eq">
367
+ <double>24</double>
368
+ </test>
369
+ <edit name="family" mode="prepend">
370
+ <string>Titr</string>
371
+ </edit>
372
+ </match>
373
+
374
+ <!-- and sans-serif. -->
375
+ <match>
376
+ <test name="family">
377
+ <string>sans-serif</string>
378
+ </test>
379
+ <test name="weight" compare="more_eq">
380
+ <int>200</int>
381
+ </test>
382
+ <test name="size" compare="more_eq">
383
+ <double>24</double>
384
+ </test>
385
+ <edit name="family" mode="prepend">
386
+ <string>Titr</string>
387
+ </edit>
388
+ </match>
389
+
390
+ <!-- and more. -->
391
+ <match>
392
+ <test name="family">
393
+ <string>Persian_sansserif_default</string>
394
+ </test>
395
+ <test name="weight" compare="more_eq">
396
+ <int>200</int>
397
+ </test>
398
+ <test name="size" compare="more_eq">
399
+ <double>24</double>
400
+ </test>
401
+ <edit name="family" mode="prepend" binding="same">
402
+ <string>Titr</string>
403
+ </edit>
404
+ </match>
405
+
406
+
407
+ <!-- Default substituted for deprecated sans-serif fonts -->
408
+
409
+ <match>
410
+ <test name="family">
411
+ <string>Persian_sansserif_default</string>
412
+ </test>
413
+ <edit name="family" mode="assign" binding="same">
414
+ <string>Roya</string>
415
+ </edit>
416
+ </match>
417
+
418
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/65-nonlatin.conf ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <description>Set preferable fonts for non-Latin</description>
5
+ <alias>
6
+ <family>serif</family>
7
+ <prefer>
8
+ <family>Artsounk</family> <!-- armenian -->
9
+ <family>BPG UTF8 M</family> <!-- georgian -->
10
+ <family>Kinnari</family> <!-- thai -->
11
+ <family>Norasi</family> <!-- thai -->
12
+ <family>Frank Ruehl</family> <!-- hebrew -->
13
+ <family>Dror</family> <!-- hebrew -->
14
+ <family>JG LaoTimes</family> <!-- lao -->
15
+ <family>Saysettha Unicode</family> <!-- lao -->
16
+ <family>Pigiarniq</family> <!-- canadian syllabics -->
17
+ <family>B Davat</family> <!-- arabic (fa) -->
18
+ <family>B Compset</family> <!-- arabic (fa) -->
19
+ <family>Kacst-Qr</family> <!-- arabic (ar) -->
20
+ <family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
21
+ <family>Raghindi</family> <!-- devanagari -->
22
+ <family>Mukti Narrow</family> <!-- bengali -->
23
+ <family>malayalam</family> <!-- malayalam -->
24
+ <family>Sampige</family> <!-- kannada -->
25
+ <family>padmaa</family> <!-- gujarati -->
26
+ <family>Hapax Berbère</family> <!-- tifinagh -->
27
+ <family>MS Mincho</family> <!-- han (ja) -->
28
+ <family>SimSun</family> <!-- han (zh-cn,zh-tw) -->
29
+ <family>PMingLiu</family> <!-- han (zh-tw) -->
30
+ <family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
31
+ <family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
32
+ <family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
33
+ <family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
34
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
35
+ <family>HanyiSong</family> <!-- han (zh-cn,zh-tw) -->
36
+ <family>MgOpen Canonica</family>
37
+ <family>Sazanami Mincho</family>
38
+ <family>IPAMonaMincho</family>
39
+ <family>IPAMincho</family>
40
+ <family>Kochi Mincho</family>
41
+ <family>AR PL SungtiL GB</family>
42
+ <family>AR PL Mingti2L Big5</family>
43
+ <family>AR PL Zenkai Uni</family>
44
+ <family>MS 明朝</family>
45
+ <family>ZYSong18030</family>
46
+ <family>NanumMyeongjo</family> <!-- hangul (ko) -->
47
+ <family>UnBatang</family> <!-- hangul (ko) -->
48
+ <family>Baekmuk Batang</family> <!-- hangul (ko) -->
49
+ <family>KacstQura</family>
50
+ <family>Frank Ruehl CLM</family>
51
+ <family>Lohit Bengali</family>
52
+ <family>Lohit Gujarati</family>
53
+ <family>Lohit Hindi</family>
54
+ <family>Lohit Marathi</family>
55
+ <family>Lohit Maithili</family>
56
+ <family>Lohit Kashmiri</family>
57
+ <family>Lohit Konkani</family>
58
+ <family>Lohit Nepali</family>
59
+ <family>Lohit Sindhi</family>
60
+ <family>Lohit Punjabi</family>
61
+ <family>Lohit Tamil</family>
62
+ <family>Rachana</family>
63
+ <family>Lohit Malayalam</family>
64
+ <family>Lohit Kannada</family>
65
+ <family>Lohit Telugu</family>
66
+ <family>Lohit Oriya</family>
67
+ <family>LKLUG</family>
68
+ </prefer>
69
+ </alias>
70
+ <alias>
71
+ <family>sans-serif</family>
72
+ <prefer>
73
+ <family>Nachlieli</family> <!-- hebrew -->
74
+ <family>Lucida Sans Unicode</family>
75
+ <family>Yudit Unicode</family>
76
+ <family>Kerkis</family> <!-- greek -->
77
+ <family>ArmNet Helvetica</family> <!-- armenian -->
78
+ <family>Artsounk</family> <!-- armenian -->
79
+ <family>BPG UTF8 M</family> <!-- georgian -->
80
+ <family>Waree</family> <!-- thai -->
81
+ <family>Loma</family> <!-- thai -->
82
+ <family>Garuda</family> <!-- thai -->
83
+ <family>Umpush</family> <!-- thai -->
84
+ <family>Saysettha Unicode</family> <!-- lao? -->
85
+ <family>JG Lao Old Arial</family> <!-- lao -->
86
+ <family>GF Zemen Unicode</family> <!-- ethiopic -->
87
+ <family>Pigiarniq</family> <!-- canadian syllabics -->
88
+ <family>B Davat</family> <!-- arabic (fa) -->
89
+ <family>B Compset</family> <!-- arabic (fa) -->
90
+ <family>Kacst-Qr</family> <!-- arabic (ar) -->
91
+ <family>Urdu Nastaliq Unicode</family> <!-- arabic (ur) -->
92
+ <family>Raghindi</family> <!-- devanagari -->
93
+ <family>Mukti Narrow</family> <!-- bengali -->
94
+ <family>malayalam</family> <!-- malayalam -->
95
+ <family>Sampige</family> <!-- kannada -->
96
+ <family>padmaa</family> <!-- gujarati -->
97
+ <family>Hapax Berbère</family> <!-- tifinagh -->
98
+ <family>MS Gothic</family> <!-- han (ja) -->
99
+ <family>UmePlus P Gothic</family> <!-- han (ja) -->
100
+ <family>Microsoft YaHei</family> <!-- han (zh-cn,zh-tw) -->
101
+ <family>Microsoft JhengHei</family> <!-- han (zh-tw) -->
102
+ <family>WenQuanYi Zen Hei</family> <!-- han (zh-cn,zh-tw) -->
103
+ <family>WenQuanYi Bitmap Song</family> <!-- han (zh-cn,zh-tw) -->
104
+ <family>AR PL ShanHeiSun Uni</family> <!--han (ja,zh-cn,zh-tw) -->
105
+ <family>AR PL New Sung</family> <!-- han (zh-cn,zh-tw) -->
106
+ <family>MgOpen Modata</family>
107
+ <family>VL Gothic</family>
108
+ <family>IPAMonaGothic</family>
109
+ <family>IPAGothic</family>
110
+ <family>Sazanami Gothic</family>
111
+ <family>Kochi Gothic</family>
112
+ <family>AR PL KaitiM GB</family>
113
+ <family>AR PL KaitiM Big5</family>
114
+ <family>AR PL ShanHeiSun Uni</family>
115
+ <family>AR PL SungtiL GB</family>
116
+ <family>AR PL Mingti2L Big5</family>
117
+ <family>MS ゴ��ック</family>
118
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
119
+ <family>TSCu_Paranar</family> <!-- tamil -->
120
+ <family>NanumGothic</family> <!-- hangul (ko) -->
121
+ <family>UnDotum</family> <!-- hangul (ko) -->
122
+ <family>Baekmuk Dotum</family> <!-- hangul (ko) -->
123
+ <family>Baekmuk Gulim</family> <!-- hangul (ko) -->
124
+ <family>KacstQura</family>
125
+ <family>Lohit Bengali</family>
126
+ <family>Lohit Gujarati</family>
127
+ <family>Lohit Hindi</family>
128
+ <family>Lohit Marathi</family>
129
+ <family>Lohit Maithili</family>
130
+ <family>Lohit Kashmiri</family>
131
+ <family>Lohit Konkani</family>
132
+ <family>Lohit Nepali</family>
133
+ <family>Lohit Sindhi</family>
134
+ <family>Lohit Punjabi</family>
135
+ <family>Lohit Tamil</family>
136
+ <family>Meera</family>
137
+ <family>Lohit Malayalam</family>
138
+ <family>Lohit Kannada</family>
139
+ <family>Lohit Telugu</family>
140
+ <family>Lohit Oriya</family>
141
+ <family>LKLUG</family>
142
+ </prefer>
143
+ </alias>
144
+ <alias>
145
+ <family>monospace</family>
146
+ <prefer>
147
+ <family>Miriam Mono</family> <!-- hebrew -->
148
+ <family>VL Gothic</family>
149
+ <family>IPAMonaGothic</family>
150
+ <family>IPAGothic</family>
151
+ <family>Sazanami Gothic</family>
152
+ <family>Kochi Gothic</family>
153
+ <family>AR PL KaitiM GB</family>
154
+ <family>MS Gothic</family> <!-- han (ja) -->
155
+ <family>UmePlus Gothic</family> <!-- han (ja) -->
156
+ <family>NSimSun</family> <!-- han (zh-cn,zh-tw) -->
157
+ <family>MingLiu</family> <!-- han (zh-tw) -->
158
+ <family>AR PL ShanHeiSun Uni</family> <!-- han (ja,zh-cn,zh-tw) -->
159
+ <family>AR PL New Sung Mono</family> <!-- han (zh-cn,zh-tw) -->
160
+ <family>HanyiSong</family> <!-- han (zh-cn) -->
161
+ <family>AR PL SungtiL GB</family>
162
+ <family>AR PL Mingti2L Big5</family>
163
+ <family>ZYSong18030</family> <!-- han (zh-cn,zh-tw) -->
164
+ <family>NanumGothicCoding</family> <!-- hangul (ko) -->
165
+ <family>NanumGothic</family> <!-- hangul (ko) -->
166
+ <family>UnDotum</family> <!-- hangul (ko) -->
167
+ <family>Baekmuk Dotum</family> <!-- hangul (ko) -->
168
+ <family>Baekmuk Gulim</family> <!-- hangul (ko) -->
169
+ <family>TlwgTypo</family> <!-- thai -->
170
+ <family>TlwgTypist</family> <!-- thai -->
171
+ <family>TlwgTypewriter</family> <!-- thai -->
172
+ <family>TlwgMono</family> <!-- thai -->
173
+ <family>Hasida</family> <!-- hebrew -->
174
+ <family>GF Zemen Unicode</family> <!-- ethiopic -->
175
+ <family>Hapax Berbère</family> <!-- tifinagh -->
176
+ <family>Lohit Bengali</family>
177
+ <family>Lohit Gujarati</family>
178
+ <family>Lohit Hindi</family>
179
+ <family>Lohit Marathi</family>
180
+ <family>Lohit Maithili</family>
181
+ <family>Lohit Kashmiri</family>
182
+ <family>Lohit Konkani</family>
183
+ <family>Lohit Nepali</family>
184
+ <family>Lohit Sindhi</family>
185
+ <family>Lohit Punjabi</family>
186
+ <family>Lohit Tamil</family>
187
+ <family>Meera</family>
188
+ <family>Lohit Malayalam</family>
189
+ <family>Lohit Kannada</family>
190
+ <family>Lohit Telugu</family>
191
+ <family>Lohit Oriya</family>
192
+ <family>LKLUG</family>
193
+ </prefer>
194
+ </alias>
195
+ <!--
196
+ system-ui
197
+ -->
198
+ <alias>
199
+ <family>system-ui</family>
200
+ <prefer>
201
+ <family>Noto Sans Arabic UI</family><!-- ar -->
202
+ <family>Noto Sans Bengali UI</family><!-- bn -->
203
+ <family>Noto Sans Devanagari UI</family><!-- hi, mai, mr -->
204
+ <family>Noto Sans Gujarati UI</family><!-- gu -->
205
+ <family>Noto Sans Gurmukhi UI</family><!-- pa -->
206
+ <family>Noto Sans Kannada UI</family><!-- kn -->
207
+ <family>Noto Sans Khmer UI</family><!-- km -->
208
+ <family>Noto Sans Lao UI</family><!-- lo -->
209
+ <family>Noto Sans Malayalam UI</family><!-- ml -->
210
+ <family>Noto Sans Myanmar UI</family><!-- my -->
211
+ <family>Noto Sans Oriya UI</family><!-- or -->
212
+ <family>Noto Sans Sinhala UI</family><!-- si -->
213
+ <family>Noto Sans Tamil UI</family><!-- ta -->
214
+ <family>Noto Sans Telugu UI</family><!-- te -->
215
+ <family>Noto Sans Thai UI</family><!-- th -->
216
+ <family>Leelawadee UI</family><!-- bug, th, jv, km, lo -->
217
+ <family>Nirmala UI</family><!-- Indic -->
218
+ <family>Yu Gothic UI</family><!-- han (ja) -->
219
+ <family>Meiryo UI</family><!-- han (ja) -->
220
+ <family>MS UI Gothic</family><!-- han (ja) -->
221
+ <family>Khmer UI</family><!-- km -->
222
+ <family>Lao UI</family><!-- lo -->
223
+ <family>Microsoft YaHei UI</family><!-- han (zh-cn) -->
224
+ <family>Microsoft JhengHei UI</family><!-- han (zh-tw) -->
225
+ </prefer>
226
+ </alias>
227
+
228
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/69-unifont.conf ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <alias>
5
+ <family>serif</family>
6
+ <prefer>
7
+ <family>FreeSerif</family>
8
+ <family>Code2000</family>
9
+ <family>Code2001</family> <!-- plane1 and beyond -->
10
+ </prefer>
11
+ </alias>
12
+ <alias>
13
+ <family>sans-serif</family>
14
+ <prefer>
15
+ <family>FreeSans</family>
16
+ <family>Arial Unicode MS</family>
17
+ <family>Arial Unicode</family>
18
+ <family>Code2000</family> <!-- almost everything; serif actually -->
19
+ <family>Code2001</family> <!-- plane1 and beyond -->
20
+ </prefer>
21
+ </alias>
22
+ <alias>
23
+ <family>monospace</family>
24
+ <prefer>
25
+ <family>FreeMono</family>
26
+ </prefer>
27
+ </alias>
28
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/80-delicious.conf ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <!-- Fix-ups for Delicious family -->
5
+
6
+ <!-- Delicious 'heavy' variant says its Medium weight -->
7
+ <match target="scan">
8
+ <test name="family" compare="eq" ignore-blanks="true">
9
+ <string>Delicious</string>
10
+ </test>
11
+ <test name="style">
12
+ <string>Heavy</string>
13
+ </test>
14
+ <edit name="weight">
15
+ <const>heavy</const>
16
+ </edit>
17
+ </match>
18
+
19
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/90-synthetic.conf ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <fontconfig>
4
+ <!--
5
+ Artificial oblique for fonts without an italic or oblique version
6
+ -->
7
+
8
+ <match target="font">
9
+ <!-- check to see if the font is roman -->
10
+ <test name="slant">
11
+ <const>roman</const>
12
+ </test>
13
+ <!-- check to see if the pattern requested non-roman -->
14
+ <test target="pattern" name="slant" compare="not_eq">
15
+ <const>roman</const>
16
+ </test>
17
+ <!-- multiply the matrix to slant the font -->
18
+ <edit name="matrix" mode="assign">
19
+ <times>
20
+ <name>matrix</name>
21
+ <matrix><double>1</double><double>0.2</double>
22
+ <double>0</double><double>1</double>
23
+ </matrix>
24
+ </times>
25
+ </edit>
26
+ <!-- pretend the font is oblique now -->
27
+ <edit name="slant" mode="assign">
28
+ <const>oblique</const>
29
+ </edit>
30
+ <!-- and disable embedded bitmaps for artificial oblique -->
31
+ <edit name="embeddedbitmap" mode="assign">
32
+ <bool>false</bool>
33
+ </edit>
34
+ </match>
35
+
36
+ <!--
37
+ Synthetic emboldening for fonts that do not have bold face available
38
+ -->
39
+
40
+ <match target="font">
41
+ <!-- check to see if the weight in the font is less than medium which possibly need emboldening -->
42
+ <test name="weight" compare="less_eq">
43
+ <const>medium</const>
44
+ </test>
45
+ <!-- check to see if the pattern requests bold -->
46
+ <test target="pattern" name="weight" compare="more_eq">
47
+ <const>bold</const>
48
+ </test>
49
+ <!--
50
+ set the embolden flag
51
+ needed for applications using cairo, e.g. gucharmap, gedit, ...
52
+ -->
53
+ <edit name="embolden" mode="assign">
54
+ <bool>true</bool>
55
+ </edit>
56
+ <!--
57
+ set weight to bold
58
+ needed for applications using Xft directly, e.g. Firefox, ...
59
+ -->
60
+ <edit name="weight" mode="assign">
61
+ <const>bold</const>
62
+ </edit>
63
+ </match>
64
+ </fontconfig>
lilypond-2.24.2/etc/fonts/conf.d/README ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ conf.d/README
2
+
3
+ Each file in this directory is a fontconfig configuration file. Fontconfig
4
+ scans this directory, loading all files of the form [0-9][0-9]*.conf.
5
+ These files are normally installed in /usr/share/fontconfig/conf.avail
6
+ and then symlinked here, allowing them to be easily installed and then
7
+ enabled/disabled by adjusting the symlinks.
8
+
9
+ The files are loaded in numeric order, the structure of the configuration
10
+ has led to the following conventions in usage:
11
+
12
+ Files beginning with: Contain:
13
+
14
+ 00 through 09 Font directories
15
+ 10 through 19 system rendering defaults (AA, etc)
16
+ 20 through 29 font rendering options
17
+ 30 through 39 family substitution
18
+ 40 through 49 generic identification, map family->generic
19
+ 50 through 59 alternate config file loading
20
+ 60 through 69 generic aliases, map generic->family
21
+ 70 through 79 select font (adjust which fonts are available)
22
+ 80 through 89 match target="scan" (modify scanned patterns)
23
+ 90 through 99 font synthesis
lilypond-2.24.2/etc/fonts/fonts.conf ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
3
+ <!-- /etc/fonts/fonts.conf file to configure system font access -->
4
+ <fontconfig>
5
+ <description>Default configuration file</description>
6
+
7
+ <!--
8
+ DO NOT EDIT THIS FILE.
9
+ IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
10
+ LOCAL CHANGES BELONG IN 'local.conf'.
11
+
12
+ The intent of this standard configuration file is to be adequate for
13
+ most environments. If you have a reasonably normal environment and
14
+ have found problems with this configuration, they are probably
15
+ things that others will also want fixed. Please submit any problems
16
+ to the fontconfig issue tracking system located at fontconfig.org
17
+
18
+ Note that the normal 'make install' procedure for fontconfig is to
19
+ replace any existing fonts.conf file with the new version. Place
20
+ any local customizations in local.conf which this file references.
21
+
22
+ Keith Packard
23
+ -->
24
+
25
+ <!-- Font directory list -->
26
+
27
+ <dir>WINDOWSFONTDIR</dir> <dir>WINDOWSUSERFONTDIR</dir>
28
+
29
+ <dir prefix="xdg">fonts</dir>
30
+ <!-- the following element will be removed in the future -->
31
+ <dir>~/.fonts</dir>
32
+
33
+ <!--
34
+ Accept deprecated 'mono' alias, replacing it with 'monospace'
35
+ -->
36
+ <match target="pattern">
37
+ <test qual="any" name="family">
38
+ <string>mono</string>
39
+ </test>
40
+ <edit name="family" mode="assign" binding="same">
41
+ <string>monospace</string>
42
+ </edit>
43
+ </match>
44
+
45
+ <!--
46
+ Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
47
+ -->
48
+ <match target="pattern">
49
+ <test qual="any" name="family">
50
+ <string>sans serif</string>
51
+ </test>
52
+ <edit name="family" mode="assign" binding="same">
53
+ <string>sans-serif</string>
54
+ </edit>
55
+ </match>
56
+
57
+ <!--
58
+ Accept deprecated 'sans' alias, replacing it with 'sans-serif'
59
+ -->
60
+ <match target="pattern">
61
+ <test qual="any" name="family">
62
+ <string>sans</string>
63
+ </test>
64
+ <edit name="family" mode="assign" binding="same">
65
+ <string>sans-serif</string>
66
+ </edit>
67
+ </match>
68
+ <!--
69
+ Accept alternate 'system ui' spelling, replacing it with 'system-ui'
70
+ -->
71
+ <match target="pattern">
72
+ <test qual="any" name="family">
73
+ <string>system ui</string>
74
+ </test>
75
+ <edit name="family" mode="assign" binding="same">
76
+ <string>system-ui</string>
77
+ </edit>
78
+ </match>
79
+
80
+ <!--
81
+ Load local system customization file
82
+ -->
83
+ <include ignore_missing="yes">conf.d</include>
84
+
85
+ <!-- Font cache directory list -->
86
+
87
+ <cachedir>LOCAL_APPDATA_FONTCONFIG_CACHE</cachedir>
88
+ <cachedir prefix="xdg">fontconfig</cachedir>
89
+ <!-- the following element will be removed in the future -->
90
+ <cachedir>~/.fontconfig</cachedir>
91
+
92
+ <config>
93
+ <!--
94
+ Rescan configuration every 30 seconds when FcFontSetList is called
95
+ -->
96
+ <rescan>
97
+ <int>30</int>
98
+ </rescan>
99
+ </config>
100
+
101
+ </fontconfig>
lilypond-2.24.2/etc/relocate/fontconfig.reloc ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ set? FONTCONFIG_FILE=$INSTALLER_PREFIX/etc/fonts/fonts.conf
2
+ set? FONTCONFIG_PATH=$INSTALLER_PREFIX/etc/fonts
lilypond-2.24.2/etc/relocate/guile.reloc ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ prependdir GUILE_LOAD_PATH=$INSTALLER_PREFIX/share/guile/2.2
2
+ prependdir GUILE_LOAD_COMPILED_PATH=$INSTALLER_PREFIX/lib/guile/2.2/ccache
lilypond-2.24.2/etc/relocate/libexec.reloc ADDED
@@ -0,0 +1 @@
 
 
1
+ prependdir PATH=$INSTALLER_PREFIX/libexec
lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/and-let-star.go ADDED
Binary file (76.1 kB). View file
 
lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/arrays.go ADDED
Binary file (69.8 kB). View file
 
lilypond-2.24.2/lib/guile/2.2/ccache/ice-9/atomic.go ADDED
Binary file (68.9 kB). View file