1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
|
@c -*- coding: utf-8; mode: texinfo; -*-
@ignore
Translation of GIT committish: FILL-IN-HEAD-COMMITTISH
When revising a translation, copy the HEAD committish of the
version that you are working on. For details, see the Contributors'
Guide, node Updating translation committishes..
@end ignore
@c \version "2.19.22"
@node Scheme tutorial
@chapter Scheme tutorial
@cindex Scheme
@cindex GUILE
@cindex Scheme, in-line code
@cindex accessing Scheme
@cindex evaluating Scheme
@cindex LISP
LilyPond uses the Scheme programming language, both as part of the
input syntax, and as internal mechanism to glue modules of the program
together. This section is a very brief overview of entering data in
Scheme. If you want to know more about Scheme, see
@uref{http://@/www@/.schemers@/.org}.
LilyPond uses the GNU Guile implementation of Scheme, which is
based on the Scheme @qq{R5RS} standard. If you are learning Scheme
to use with LilyPond, working with a different implementation (or
referring to a different standard) is not recommended. Information
on guile can be found at @uref{http://www.gnu.org/software/guile/}.
The @qq{R5RS} Scheme standard is located at
@uref{http://www.schemers.org/Documents/Standards/R5RS/}.
@menu
* Introduction to Scheme::
* Scheme in LilyPond::
* Building complicated functions::
@end menu
@node Introduction to Scheme
@section Introduction to Scheme
We begin with an introduction to Scheme. For this brief introduction,
we will use the GUILE interpreter to explore how the language works.
Once we are familiar with Scheme, we will show how the language can
be integrated in LilyPond files.
@menu
* Scheme sandbox::
* Scheme variables::
* Scheme simple data types::
* Scheme compound data types::
* Calculations in Scheme::
* Scheme procedures::
* Scheme conditionals::
@end menu
@node Scheme sandbox
@subsection Scheme sandbox
The LilyPond installation includes the Guile implementation of
Scheme. On most systems you can experiment in a Scheme sandbox by
opening a terminal window and typing @q{guile}. On some systems,
notably Windows, you may need to set the environment variable
@code{GUILE_LOAD_PATH} to the directory @code{../usr/share/guile/1.8}
in the LilyPond installation. For the full path to this directory
see @rlearning{Other sources of information}. Alternatively, Windows
users may simply choose @q{Run} from the Start menu and enter
@q{guile}.
However, a hands-on Scheme sandbox with all of LilyPond loaded is
available with this command line:
@example
lilypond scheme-sandbox
@end example
@noindent
Once the sandbox is running, you will receive a guile prompt:
@lisp
guile>
@end lisp
You can enter Scheme expressions at this prompt to experiment with
Scheme. If you want to be able to use the GNU readline library for
nicer editing of the Scheme command line, check the file
@file{ly/scheme-sandbox.ly} for more information. If you already have
enabled the readline library for your interactive Guile sessions outside
of LilyPond, this should work in the sandbox as well.
@node Scheme variables
@subsection Scheme variables
Scheme variables can have any valid scheme value, including a Scheme
procedure.
Scheme variables are created with @code{define}:
@lisp
guile> (define a 2)
guile>
@end lisp
Scheme variables can be evaluated at the guile prompt simply by
typing the variable name:
@lisp
guile> a
2
guile>
@end lisp
Scheme variables can be printed on the display by using the display function:
@lisp
guile> (display a)
2guile>
@end lisp
@noindent
Note that both the value @code{2} and the guile prompt @code{guile}
showed up on the same line. This can be avoided by calling the
newline procedure or displaying a newline character.
@lisp
guile> (display a)(newline)
2
guile> (display a)(display "\n")
2
guile>
@end lisp
Once a variable has been created, its value can be changed with @code{set!}:
@lisp
guile> (set! a 12345)
guile> a
12345
guile>
@end lisp
@node Scheme simple data types
@subsection Scheme simple data types
The most basic concept in a language is data typing: numbers, character
strings, lists, etc. Here is a list of simple Scheme data types that are
often used with LilyPond.
@table @asis
@item Booleans
Boolean values are True or False. The Scheme for True is @code{#t}
and False is @code{#f}.
@funindex ##t
@funindex ##f
@item Numbers
Numbers are entered in the standard fashion,
@code{1} is the (integer) number one, while @w{@code{-1.5}} is a
floating point number (a non-integer number).
@item Strings
Strings are enclosed in double quotes:
@example
"this is a string"
@end example
Strings may span several lines:
@example
"this
is
a string"
@end example
@noindent
and the newline characters at the end of each line will be included
in the string.
Newline characters can also be added by including @code{\n} in the
string.
@example
"this\nis a\nmultiline string"
@end example
Quotation marks and backslashes are added to strings
by preceding them with a backslash.
The string @code{\a said "b"} is entered as
@example
"\\a said \"b\""
@end example
@end table
There are additional Scheme data types that are not discussed here.
For a complete listing see the Guile reference guide,
@uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.
@node Scheme compound data types
@subsection Scheme compound data types
There are also compound data types in Scheme. The types commonly used in
LilyPond programming include pairs, lists, alists, and hash tables.
@menu
* Pairs::
* Lists::
* Association lists (alists)::
* Hash tables::
@end menu
@node Pairs
@unnumberedsubsubsec Pairs
The foundational compound data type of Scheme is the @code{pair}. As
might be expected from its name, a pair is two values glued together.
The operator used to form a pair is called @code{cons}.
@lisp
guile> (cons 4 5)
(4 . 5)
guile>
@end lisp
Note that the pair is displayed as two items surrounded by
parentheses and separated by whitespace, a period (@code{.}), and
more whitespace. The period is @emph{not} a decimal point, but
rather an indicator of the pair.
Pairs can also be entered as literal values by preceding them with
a single quote character.
@lisp
guile> '(4 . 5)
(4 . 5)
guile>
@end lisp
The two elements of a pair may be any valid Scheme value:
@lisp
guile> (cons #t #f)
(#t . #f)
guile> '("blah-blah" . 3.1415926535)
("blah-blah" . 3.1415926535)
guile>
@end lisp
The first and second elements of the pair can be accessed by the
Scheme procedures @code{car} and @code{cdr}, respectively.
@lisp
guile> (define mypair (cons 123 "hello there")
@dots{} )
guile> (car mypair)
123
guile> (cdr mypair)
"hello there"
guile>
@end lisp
@noindent
Note: @code{cdr} is pronounced "could-er", according Sussman and
Abelson, see
@uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}
@node Lists
@unnumberedsubsubsec Lists
A very common Scheme data structure is the @emph{list}. Formally,
a @q{proper} list is defined to be either the empty list with its
input form @code{'()} and length@tie{}0, or a pair whose
@code{cdr} in turn is a shorter list.
There are many ways of creating lists. Perhaps the most common is
with the @code{list} procedure:
@lisp
guile> (list 1 2 3 "abc" 17.5)
(1 2 3 "abc" 17.5)
@end lisp
Representing a list as individual
elements separated by whitespace and enclosed in parentheses
is actually a compacted rendition of the actual dotted pairs
constituting the list, where the dot and an immediately following
starting paren are removed along with the matching closing paren.
Without this compaction, the output would have been
@lisp
(1 . (2 . (3 . ("abc" . (17.5 . ())))))
@end lisp
As with the output, a list can also be entered (after adding a
quote to avoid interpretation as a function call) as a literal
list by enclosing its elements in parentheses:
@lisp
guile> '(17 23 "foo" "bar" "bazzle")
(17 23 "foo" "bar" "bazzle")
@end lisp
Lists are a central part of Scheme. In, fact, Scheme is considered
a dialect of lisp, where @q{lisp} is an abbreviation for
@q{List Processing}. Scheme expressions are all lists.
@node Association lists (alists)
@unnumberedsubsubsec Association lists (alists)
A special type of list is an @emph{association list} or @emph{alist}.
An alist is used to store data for easy retrieval.
Alists are lists whose elements are pairs. The @code{car} of each
element is called the @emph{key}, and the @code{cdr} of each element
is called the @emph{value}. The Scheme procedure @code{assoc} is
used to retrieve an entry from the alist, and @code{cdr} is used to
retrieve the value:
@lisp
guile> (define my-alist '((1 . "A") (2 . "B") (3 . "C")))
guile> my-alist
((1 . "A") (2 . "B") (3 . "C"))
guile> (assoc 2 my-alist)
(2 . "B")
guile> (cdr (assoc 2 my-alist))
"B"
guile>
@end lisp
Alists are widely used in LilyPond to store properties and other data.
@node Hash tables
@unnumberedsubsubsec Hash tables
A data structure that is used occasionally in LilyPond. A hash table
is similar to an array, but the indexes to the array can be any type
of Scheme value, not just integers.
Hash tables are more efficient than alists if there is a lot of data
to store and the data changes very infrequently.
The syntax to create hash tables is a bit complex, but you
can see examples of it in the LilyPond source.
@lisp
guile> (define h (make-hash-table 10))
guile> h
#<hash-table 0/31>
guile> (hashq-set! h 'key1 "val1")
"val1"
guile> (hashq-set! h 'key2 "val2")
"val2"
guile> (hashq-set! h 3 "val3")
"val3"
@end lisp
Values are retrieved from hash tables with @code{hashq-ref}.
@lisp
guile> (hashq-ref h 3)
"val3"
guile> (hashq-ref h 'key2)
"val2"
guile>
@end lisp
Keys and values are retrieved as a pair with @code{hashq-get-handle}.
This is a preferred way, because it will return @code{#f} if a key is
not found.
@lisp
guile> (hashq-get-handle h 'key1)
(key1 . "val1")
guile> (hashq-get-handle h 'frob)
#f
guile>
@end lisp
@node Calculations in Scheme
@subsection Calculations in Scheme
@ignore
We have been using lists all along. A calculation, like @code{(+ 1 2)}
is also a list (containing the symbol @code{+} and the numbers 1
and@tie{}2). Normally lists are interpreted as calculations, and the
Scheme interpreter substitutes the outcome of the calculation. To enter a
list, we stop the evaluation. This is done by quoting the list with a
quote @code{'} symbol. So, for calculations do not use a quote.
Inside a quoted list or pair, there is no need to quote anymore. The
following is a pair of symbols, a list of symbols and a list of lists
respectively,
@example
#'(stem . head)
#'(staff clef key-signature)
#'((1) (2))
@end example
@end ignore
Scheme can be used to do calculations. It uses @emph{prefix}
syntax. Adding 1 and@tie{}2 is written as @code{(+ 1 2)} rather than the
traditional @math{1+2}.
@lisp
guile> (+ 1 2)
3
@end lisp
Calculations may be nested; the result of a function may
be used for another calculation.
@lisp
guile> (+ 1 (* 3 4))
13
@end lisp
These calculations are examples of evaluations; an expression like
@code{(* 3 4)} is replaced by its value @code{12}.
Scheme calculations are sensitive to the differences between integers
and non-integers. Integer calculations are exact, while non-integers
are calculated to the appropriate limits of precision:
@lisp
guile> (/ 7 3)
7/3
guile> (/ 7.0 3.0)
2.33333333333333
@end lisp
When the scheme interpreter encounters an expression that is a list,
the first element of the list is treated as a procedure to be
evaluated with the arguments of the remainder of the list. Therefore,
all operators in Scheme are prefix operators.
If the first element of a Scheme expression that is a list passed to
the interpreter is @emph{not} an operator or procedure, an error will
occur:
@lisp
guile> (1 2 3)
Backtrace:
In current input:
52: 0* [1 2 3]
<unnamed port>:52:1: In expression (1 2 3):
<unnamed port>:52:1: Wrong type to apply: 1
ABORT: (misc-error)
guile>
@end lisp
Here you can see that the interpreter was trying to treat 1 as an
operator or procedure, and it couldn't. Hence the error is "Wrong
type to apply: 1".
Therefore, to create a list we need to use the list operator, or to
quote the list so that the interpreter will not try to evaluate it.
@lisp
guile> (list 1 2 3)
(1 2 3)
guile> '(1 2 3)
(1 2 3)
guile>
@end lisp
This is an error that can appear as you are working with Scheme in LilyPond.
@ignore
The same assignment can be done in completely in Scheme as well,
@example
#(define twentyFour (* 2 twelve))
@end example
@c this next section is confusing -- need to rewrite
The @emph{name} of a variable is also an expression, similar to a
number or a string. It is entered as
@example
#'twentyFour
@end example
@funindex #'symbol
@cindex quoting in Scheme
The quote mark @code{'} prevents the Scheme interpreter from substituting
@code{24} for the @code{twentyFour}. Instead, we get the name
@code{twentyFour}.
@end ignore
@node Scheme procedures
@subsection Scheme procedures
Scheme procedures are executable scheme expressions that return a
value resulting from their execution. They can also manipulate
variables defined outside of the procedure.
@menu
* Defining procedures::
* Predicates::
* Return values::
@end menu
@node Defining procedures
@unnumberedsubsubsec Defining procedures
Procedures are defined in Scheme with define
@example
(define (function-name arg1 arg2 ... argn)
scheme-expression-that-gives-a-return-value)
@end example
For example, we could define a procedure to calculate the average:
@lisp
guile> (define (average x y) (/ (+ x y) 2))
guile> average
#<procedure average (x y)>
@end lisp
Once a procedure is defined, it is called by putting the procedure
name and the arguments in a list. For example, we can calculate
the average of 3 and 12:
@lisp
guile> (average 3 12)
15/2
@end lisp
@node Predicates
@unnumberedsubsubsec Predicates
Scheme procedures that return boolean values are often called
@emph{predicates}. By convention (but not necessity), predicate names
typically end in a question mark:
@lisp
guile> (define (less-than-ten? x) (< x 10))
guile> (less-than-ten? 9)
#t
guile> (less-than-ten? 15)
#f
@end lisp
@node Return values
@unnumberedsubsubsec Return values
Scheme procedures always return a return value, which is the value
of the last expression executed in the procedure. The return
value can be any valid Scheme value, including a complex data
structure or a procedure.
Sometimes the user would like to have multiple Scheme expressions in
a procedure. There are two ways that multiple expressions can be
combined. The first is the @code{begin} procedure, which allows
multiple expressions to be evaluated, and returns the value of
the last expression.
@lisp
guile> (begin (+ 1 2) (- 5 8) (* 2 2))
4
@end lisp
The second way to combine multiple expressions is in a @code{let} block.
In a let block, a series of bindings are created, and then a sequence
of expressions that can include those bindings is evaluated. The
return value of the let block is the return value of the last
statement in the let block:
@lisp
guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
@dots{} (+ (* x y) (/ z x)))
508
@end lisp
@node Scheme conditionals
@subsection Scheme conditionals
@menu
* if::
* cond::
@end menu
@node if
@unnumberedsubsubsec if
Scheme has an @code{if} procedure:
@example
(if test-expression true-expression false-expression)
@end example
@var{test-expression} is an expression that returns a boolean
value. If @var{test-expression} returns @code{#t}, the if
procedure returns the value of @var{true-expression}, otherwise
it returns the value of @var{false-expression}.
@lisp
guile> (define a 3)
guile> (define b 5)
guile> (if (> a b) "a is greater than b" "a is not greater than b")
"a is not greater than b"
@end lisp
@node cond
@unnumberedsubsubsec cond
Another conditional procedure in scheme is @code{cond}:
@example
(cond (test-expression-1 result-expression-sequence-1)
(test-expression-2 result-expression-sequence-2)
@dots{}
(test-expression-n result-expression-sequence-n))
@end example
For example:
@lisp
guile> (define a 6)
guile> (define b 8)
guile> (cond ((< a b) "a is less than b")
... ((= a b) "a equals b")
... ((> a b) "a is greater than b"))
"a is less than b"
@end lisp
@node Scheme in LilyPond
@section Scheme in LilyPond
@menu
* LilyPond Scheme syntax::
* LilyPond variables::
* Input variables and Scheme::
* Importing Scheme in LilyPond::
* Object properties::
* LilyPond compound variables::
* Internal music representation::
@end menu
@node LilyPond Scheme syntax
@subsection LilyPond Scheme syntax
@funindex $
@funindex #
The Guile interpreter is part of LilyPond, which means that
Scheme can be included in LilyPond input files. There are several
methods for including Scheme in LilyPond.
The simplest way is to use a hash mark@tie{}@code{#} before a Scheme
expression.
Now LilyPond's input is structured into tokens and expressions, much
like human language is structured into words and sentences. LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
@rcontrib{LilyPond grammar}. Once it knows that a particular syntax rule
applies, it executes actions associated with it.
The hash mark@tie{}@code{#} method of embedding Scheme is a natural fit
for this system. Once the lexer sees a hash mark, it calls the Scheme
reader to read one full Scheme expression (this can be an identifier, an
expression enclosed in parentheses, or several other things). After the
Scheme expression is read, it is stored away as the value for an
@code{SCM_TOKEN} in the grammar. Once the parser knows how to make use
of this token, it calls Guile for evaluating the Scheme expression.
Since the parser usually requires a bit of lookahead from the lexer to
make its parsing decisions, this separation of reading and evaluation
between lexer and parser is exactly what is needed to keep the execution
of LilyPond and Scheme expressions in sync. For this reason, you should
use the hash mark@tie{}@code{#} for calling Scheme whenever this is
feasible.
Another way to call the Scheme interpreter from LilyPond is the use of
dollar@tie{}@code{$} instead of a hash mark for introducing Scheme
expressions. In this case, LilyPond evaluates the code right after the
lexer has read it. It checks the resulting type of the Scheme
expression and then picks a token type (one of several
@code{xxx_IDENTIFIER} in the syntax) for it. It creates a @emph{copy}
of the value and uses that for the value of the token. If the value of
the expression is void (Guile's value of @code{*unspecified*}), nothing
at all is passed to the parser.
This is, in fact, exactly the same mechanism that LilyPond employs when
you call any variable or music function by name, as @code{\name}, with
the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
consistent with the current LilyPond mode are accepted.
The immediate action of @code{$} can lead to surprises, see
@ref{Importing Scheme in LilyPond}. Using @code{#} where the
parser supports it is usually preferable. Inside of music expressions,
expressions created using @code{#} @emph{are} interpreted as
music. However, they are @emph{not} copied before use. If they are
part of some structure that might still get used, you may need to use
@code{ly:music-deep-copy} explicitly.
@funindex $@@
@funindex #@@
There are also @q{list splicing} operators @code{$@@} and @code{#@@}
that insert all elements of a list in the surrounding context.
Now let's take a look at some actual Scheme code. Scheme procedures can
be defined in LilyPond input files:
@example
#(define (average a b c) (/ (+ a b c) 3))
@end example
Note that LilyPond comments (@code{%} and @code{%@{ %@}}) cannot
be used within Scheme code, even in a LilyPond input file, because
the Guile interpreter, not the LilyPond lexer, is reading
the Scheme expression. Comments in Guile Scheme are entered
as follows:
@example
; this is a single-line comment
#!
This a (non-nestable) Guile-style block comment
But these are rarely used by Schemers and never in
LilyPond source code
!#
@end example
For the rest of this section, we will assume that the data is entered
in a music file, so we add a @code{#} at the beginning of each Scheme
expression.
All of the top-level Scheme expressions in a LilyPond input file can
be combined into a single Scheme expression by use of the
@code{begin} statement:
@example
#(begin
(define foo 0)
(define bar 1))
@end example
@node LilyPond variables
@subsection LilyPond variables
LilyPond variables are stored internally in the form of Scheme
variables. Thus,
@example
twelve = 12
@end example
@noindent
is equivalent to
@example
#(define twelve 12)
@end example
This means that LilyPond variables are available
for use in Scheme expressions. For example, we could use
@example
twentyFour = #(* 2 twelve)
@end example
@noindent
which would result in the number 24 being stored in the
LilyPond (and Scheme) variable @code{twentyFour}.
The usual way to refer to LilyPond variables is to call them using a
backslash, i.e., @code{\twentyFour} (see @ref{LilyPond Scheme syntax}).
Since this creates a copy of the value for most of LilyPond's internal
types, in particular music expressions, music functions don't usually
create copies of material they change. For this reason, music
expressions given with @code{#} should usually not contain material that
is not either created from scratch or explicitly copied rather than
directly referenced.
@node Input variables and Scheme
@subsection Input variables and Scheme
The input format supports the notion of variables: in the following
example, a music expression is assigned to a variable with the name
@code{traLaLa}.
@example
traLaLa = @{ c'4 d'4 @}
@end example
@noindent
There is also a form of scoping: in the following example, the
@code{\layout} block also contains a @code{traLaLa} variable, which is
independent of the outer @code{\traLaLa}.
@example
traLaLa = @{ c'4 d'4 @}
\layout @{ traLaLa = 1.0 @}
@end example
@c
In effect, each input file is a scope, and all @code{\header},
@code{\midi}, and @code{\layout} blocks are scopes nested inside that
toplevel scope.
Both variables and scoping are implemented in the GUILE module system.
An anonymous Scheme module is attached to each scope. An assignment of
the form:
@example
traLaLa = @{ c'4 d'4 @}
@end example
@noindent
is internally converted to a Scheme definition:
@example
(define traLaLa @var{Scheme value of `@code{@dots{}}'})
@end example
This means that LilyPond variables and Scheme variables may be freely
mixed. In the following example, a music fragment is stored in the
variable @code{traLaLa}, and duplicated using Scheme. The result is
imported in a @code{\score} block by means of a second variable
@code{twice}:
@lilypond[verbatim]
traLaLa = { c'4 d'4 }
#(define newLa (map ly:music-deep-copy
(list traLaLa traLaLa)))
#(define twice
(make-sequential-music newLa))
\twice
@end lilypond
@c Due to parser lookahead
This is actually a rather interesting example. The assignment will only
take place after the parser has ascertained that nothing akin to
@code{\addlyrics} follows, so it needs to check what comes next. It
reads @code{#} and the following Scheme expression @emph{without}
evaluating it, so it can go ahead with the assignment, and
@emph{afterwards} execute the Scheme code without problem.
@node Importing Scheme in LilyPond
@subsection Importing Scheme in LilyPond
@funindex $
@funindex #
The above example shows how to @q{export} music expressions from the
input to the Scheme interpreter. The opposite is also possible. By
placing it after @code{$}, a Scheme
value is interpreted as if it were entered in LilyPond syntax.
Instead of defining @code{\twice}, the example above could also have
been written as
@example
@dots{}
$(make-sequential-music newLa)
@end example
You can use @code{$} with a Scheme expression anywhere you could use
@code{\@var{name}} after having assigned the Scheme expression to a
variable @var{name}. This replacement happens in the @q{lexer}, so
LilyPond is not even aware of the difference.
One drawback, however, is that of timing. If we had been using @code{$}
instead of @code{#} for defining @code{newLa} in the above example, the
following Scheme definition would have failed because @code{traLaLa}
would not yet have been defined. For an explanation of this timing
problem, @ref{LilyPond Scheme syntax}.
@funindex $@@
@funindex #@@
A further convenience can be the @q{list splicing} operators @code{$@@}
and @code{#@@} for inserting the elements of a list in the surrounding
context. Using those, the last part of the example could have been
written as
@example
@dots{}
@{ #@@newLa @}
@end example
Here, every element of the list stored in @code{newLa} is taken in
sequence and inserted into the list, as if we had written
@example
@{ #(first newLa) #(second newLa) @}
@end example
Now in all of these forms, the Scheme code is evaluated while the
input is still being consumed, either in the lexer or in the parser.
If you need it to be executed at a later point of time, check out
@ref{Void scheme functions}, or store it in a procedure:
@example
#(define (nopc)
(ly:set-option 'point-and-click #f))
@dots{}
#(nopc)
@{ c'4 @}
@end example
@knownissues
Mixing Scheme and LilyPond variables is not possible with the
@option{--safe} option.
@node Object properties
@subsection Object properties
Object properties are stored in LilyPond in the form of alist-chains,
which are lists of alists. Properties are set by adding values at
the beginning of the property list. Properties are read by retrieving
values from the alists.
Setting a new value for a property requires assigning a value to
the alist with both a key and a value. The LilyPond syntax for doing
this is:
@example
\override Stem.thickness = #2.6
@end example
This instruction adjusts the appearance of stems. An alist entry
@code{'(thickness . 2.6)} is added to the property list of the
@code{Stem}
object. @code{thickness} is measured relative to the thickness of
staff lines, so these stem lines will be @code{2.6} times the
width of staff lines. This makes stems almost twice as thick as their
normal size. To distinguish between variables defined in input files (like
@code{twentyFour} in the example above) and variables of internal
objects, we will call the latter @q{properties} and the former
@q{variables.} So, the stem object has a @code{thickness} property,
while @code{twentyFour} is a variable.
@cindex properties vs. variables
@cindex variables vs. properties
@c todo -- here we're getting interesting. We're now introducing
@c LilyPond variable types. I think this deserves a section all
@c its own
@node LilyPond compound variables
@subsection LilyPond compound variables
@menu
* Offsets::
* Fractions::
* Extents::
* Property alists::
* Alist chains::
@end menu
@node Offsets
@unnumberedsubsubsec Offsets
Two-dimensional offsets (X and Y coordinates) are stored as @emph{pairs}.
The @code{car} of the offset is the X coordinate, and the @code{cdr} is
the Y coordinate.
@example
\override TextScript.extra-offset = #'(1 . 2)
@end example
This assigns the pair @code{(1 . 2)} to the @code{extra-offset}
property of the
TextScript object. These numbers are measured in staff-spaces, so
this command moves the object 1 staff space to the right, and 2 spaces up.
Procedures for working with offsets are found in @file{scm/lily-library.scm}.
@node Fractions
@unnumberedsubsubsec Fractions
Fractions as used by LilyPond are again stored as @emph{pairs}, this
time of unsigned integers. While Scheme can represent rational numbers
as a native type, musically @samp{2/4} and @samp{1/2} are not the same,
and we need to be able to distinguish between them. Similarly there are
no negative @q{fractions} in LilyPond's mind. So @code{2/4} in LilyPond
means @code{(2 . 4)} in Scheme, and @code{#2/4} in LilyPond means
@code{1/2} in Scheme.
@node Extents
@unnumberedsubsubsec Extents
Pairs are also used to store intervals, which represent a range of numbers
from the minimum (the @code{car}) to the maximum (the @code{cdr}).
Intervals are used to store the X- and Y- extents of printable objects.
For X extents, the @code{car} is the left hand X coordinate, and the
@code{cdr} is the right hand X coordinate. For Y extents, the @code{car}
is the bottom coordinate, and the @code{cdr} is the top coordinate.
Procedures for working with intervals are found in
@file{scm/lily-library.scm}. These procedures should be used when possible
to ensure consistency of code.
@node Property alists
@unnumberedsubsubsec Property alists
A property alist is a LilyPond data structure that is an alist whose
keys are properties and whose values are Scheme expressions that give
the desired value for the property.
LilyPond properties are Scheme symbols, such as @code{'thickness}.
@node Alist chains
@unnumberedsubsubsec Alist chains
An alist chain is a list containing property alists.
The set of all properties that will apply to a grob is typically
stored as an alist chain. In order to find the value for a particular
property that a grob should have, each alist in the chain is searched in
order, looking for an entry containing the property key. The first alist
entry found is returned, and the value is the property value.
The Scheme procedure @code{chain-assoc-get} is normally used to get
grob property values.
@node Internal music representation
@subsection Internal music representation
Internally, music is represented as a Scheme list. The list contains
various elements that affect the printed output. Parsing is the process
of converting music from the LilyPond input representation to the
internal Scheme representation.
When a music expression is parsed, it is converted into a set of
Scheme music objects. The defining property of a music object is that
it takes up time. The time it takes up is called its @emph{duration}.
Durations are expressed as a rational number that measures the length
of the music object in whole notes.
A music object has three kinds of types:
@itemize
@item
music name: Each music expression has a name. For example, a note
leads to a @rinternals{NoteEvent}, and @code{\simultaneous} leads to
a @rinternals{SimultaneousMusic}. A list of all expressions
available is in the Internals Reference manual, under
@rinternals{Music expressions}.
@item
@q{type} or interface: Each music name has several @q{types} or
interfaces, for example, a note is an @code{event}, but it is also a
@code{note-event}, a @code{rhythmic-event}, and a
@code{melodic-event}. All classes of music are listed in the
Internals Reference, under
@rinternals{Music classes}.
@item
C++ object: Each music object is represented by an object of the C++
class @code{Music}.
@end itemize
The actual information of a music expression is stored in properties.
For example, a @rinternals{NoteEvent} has @code{pitch} and
@code{duration} properties that store the pitch and duration of that
note. A list of all properties available can be found in the
Internals Reference, under @rinternals{Music properties}.
A compound music expression is a music object that contains other
music objects in its properties. A list of objects can be stored in
the @code{elements} property of a music object, or a single @q{child}
music object in the @code{element} property. For example,
@rinternals{SequentialMusic} has its children in @code{elements},
and @rinternals{GraceMusic} has its single argument in
@code{element}. The body of a repeat is stored in the @code{element}
property of @rinternals{RepeatedMusic}, and the alternatives in
@code{elements}.
@node Building complicated functions
@section Building complicated functions
This section explains how to gather the information necessary
to create complicated music functions.
@menu
* Displaying music expressions::
* Music properties::
* Doubling a note with slurs (example)::
* Adding articulation to notes (example)::
@end menu
@node Displaying music expressions
@subsection Displaying music expressions
@cindex internal storage
@cindex displaying music expressions
@cindex internal representation, displaying
@cindex displayMusic
@funindex \displayMusic
When writing a music function it is often instructive to inspect how
a music expression is stored internally. This can be done with the
music function @code{\displayMusic}.
@example
@{
\displayMusic @{ c'4\f @}
@}
@end example
@noindent
will display
@example
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'articulations
(list (make-music
'AbsoluteDynamicEvent
'text
"f"))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))))
@end example
By default, LilyPond will print these messages to the console along
with all the other messages. To split up these messages and save
the results of @code{\display@{STUFF@}}, you can specify an optional
output port to use:
@example
@{
\displayMusic #(open-output-file "display.txt") @{ c'4\f @}
@}
@end example
This will overwrite a previous output file whenever it is called; if you
need to write more than one expression, you would use a variable for
your port and reuse it:
@example
@{
port = #(open-output-file "display.txt")
\displayMusic \port @{ c'4\f @}
\displayMusic \port @{ d'4 @}
#(close-output-port port)
@}
@end example
Guile's manual describes ports in detail. Closing the port is actually
only necessary if you need to read the file before LilyPond finishes; in
the first example, we did not bother to do so.
A bit of reformatting makes the above information easier to read:
@example
(make-music 'SequentialMusic
'elements (list
(make-music 'NoteEvent
'articulations (list
(make-music 'AbsoluteDynamicEvent
'text
"f"))
'duration (ly:make-duration 2 0 1/1)
'pitch (ly:make-pitch 0 0 0))))
@end example
A @code{@{ @dots{} @}} music sequence has the name
@code{SequentialMusic}, and its inner expressions are stored as a list
in its @code{'elements} property. A note is represented as a
@code{NoteEvent} object (storing the duration and pitch properties) with
attached information (in this case, an @code{AbsoluteDynamicEvent} with
a @code{"f"} text property) stored in its @code{articulations} property.
@funindex{\void}
@code{\displayMusic} returns the music it displays, so it will get
interpreted as well as displayed. To avoid interpretation, write
@code{\void} before @code{\displayMusic}.
@node Music properties
@subsection Music properties
@ignore
TODO -- make sure we delineate between @emph{music} properties,
@emph{context} properties, and @emph{layout} properties. These
are potentially confusing.
@end ignore
Let's look at an example:
@example
someNote = c'
\displayMusic \someNote
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))
@end example
The @code{NoteEvent} object is the representation of @code{someNote}.
Straightforward. How about putting c' in a chord?
@example
someNote = <c'>
\displayMusic \someNote
===>
(make-music
'EventChord
'elements
(list (make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))))
@end example
Now the @code{NoteEvent} object is the first object of the
@code{'elements} property of @code{someNote}.
The @code{display-scheme-music} function is the function used by
@code{\displayMusic} to display the Scheme representation of a music
expression.
@example
#(display-scheme-music (first (ly:music-property someNote 'elements)))
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 0 0))
@end example
Then the note pitch is accessed through the @code{'pitch} property
of the @code{NoteEvent} object.
@example
#(display-scheme-music
(ly:music-property (first (ly:music-property someNote 'elements))
'pitch))
===>
(ly:make-pitch 0 0 0)
@end example
The note pitch can be changed by setting this @code{'pitch} property.
@funindex \displayLilyMusic
@example
#(set! (ly:music-property (first (ly:music-property someNote 'elements))
'pitch)
(ly:make-pitch 0 1 0)) ;; set the pitch to d'.
\displayLilyMusic \someNote
===>
d'4
@end example
@node Doubling a note with slurs (example)
@subsection Doubling a note with slurs (example)
Suppose we want to create a function that translates input like
@code{a} into @code{@{ a( a) @}}. We begin by examining the internal
representation of the desired result.
@example
\displayMusic@{ a'( a') @}
===>
(make-music
'SequentialMusic
'elements
(list (make-music
'NoteEvent
'articulations
(list (make-music
'SlurEvent
'span-direction
-1))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 5 0))
(make-music
'NoteEvent
'articulations
(list (make-music
'SlurEvent
'span-direction
1))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 5 0))))
@end example
The bad news is that the @code{SlurEvent} expressions
must be added @q{inside} the note (in its @code{articulations}
property).
Now we examine the input.
@example
\displayMusic a'
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch 0 5 0))))
@end example
So in our function, we need to clone this expression (so that we have
two notes to build the sequence), add a @code{SlurEvent} to the
@code{'articulations} property of each one, and finally make a
@code{SequentialMusic} with the two @code{NoteEvent} elements. For adding to a
property, it is useful to know that an unset property is read out as
@code{'()}, the empty list, so no special checks are required before we
put another element at the front of the @code{articulations} property.
@example
doubleSlur = #(define-music-function (note) (ly:music?)
"Return: @{ note ( note ) @}.
`note' is supposed to be a single note."
(let ((note2 (ly:music-deep-copy note)))
(set! (ly:music-property note 'articulations)
(cons (make-music 'SlurEvent 'span-direction -1)
(ly:music-property note 'articulations)))
(set! (ly:music-property note2 'articulations)
(cons (make-music 'SlurEvent 'span-direction 1)
(ly:music-property note2 'articulations)))
(make-music 'SequentialMusic 'elements (list note note2))))
@end example
@node Adding articulation to notes (example)
@subsection Adding articulation to notes (example)
The easy way to add articulation to notes is to merge two music
expressions into one context.
However, suppose that we want to write a music function that does this.
This will have the additional advantage that we can use that music
function to add an articulation (like a fingering instruction) to a
single note inside of a chord which is not possible if we just merge
independent music.
A @code{$variable} inside the @code{#@{@dots{}#@}} notation is like
a regular @code{\variable} in classical LilyPond notation. We
know that
@example
@{ \music -. -> @}
@end example
@noindent
will not work in LilyPond. We could avoid this problem by attaching
the articulation to an empty chord,
@example
@{ << \music <> -. -> >> @}
@end example
@noindent
but for the sake of this example, we will learn how to do this in
Scheme. We begin by examining our input and desired output.
@example
% input
\displayMusic c4
===>
(make-music
'NoteEvent
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch -1 0 0))))
=====
% desired output
\displayMusic c4->
===>
(make-music
'NoteEvent
'articulations
(list (make-music
'ArticulationEvent
'articulation-type
"accent"))
'duration
(ly:make-duration 2 0 1/1)
'pitch
(ly:make-pitch -1 0 0))
@end example
We see that a note (@code{c4}) is represented as an @code{NoteEvent}
expression. To add an accent articulation, an @code{ArticulationEvent}
expression must be added to the @code{articulations} property of the
@code{NoteEvent} expression.
To build this function, we begin with
@example
(define (add-accent note-event)
"Add an accent ArticulationEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'ArticulationEvent
'articulation-type "accent")
(ly:music-property note-event 'articulations)))
note-event)
@end example
The first line is the way to define a function in Scheme: the function
name is @code{add-accent}, and has one variable called
@code{note-event}. In Scheme, the type of variable is often clear
from its name. (this is good practice in other programming languages,
too!)
@example
"Add an accent@dots{}"
@end example
@noindent
is a description of what the function does. This is not strictly
necessary, but just like clear variable names, it is good practice.
You may wonder why we modify the note event directly instead of working
on a copy (@code{ly:music-deep-copy} can be used for that). The reason
is a silent contract: music functions are allowed to modify their
arguments: they are either generated from scratch (like user input) or
are already copied (referencing a music variable with @samp{\name} or
music from immediate Scheme expressions @samp{$(@dots{})} provides a
copy). Since it would be inefficient to create unnecessary copies, the
return value from a music function is @emph{not} copied. So to heed
that contract, you must not use any arguments more than once, and
returning it counts as one use.
In an earlier example, we constructed music by repeating a given music
argument. In that case, at least one repetition had to be a copy of its
own. If it weren't, strange things may happen. For example, if you use
@code{\relative} or @code{\transpose} on the resulting music containing
the same elements multiple times, those will be subjected to
relativation or transposition multiple times. If you assign them to a
music variable, the curse is broken since referencing @samp{\name} will
again create a copy which does not retain the identity of the repeated
elements.
Now while the above function is not a music function, it will normally
be used within music functions. So it makes sense to heed the same
contract we use for music functions: the input may be modified for
producing the output, and the caller is responsible for creating copies
if it still needs the unchanged argument itself. If you take a look at
LilyPond's own functions like @code{music-map}, you'll find that they
stick with the same principles.
Where were we? Now we have a @code{note-event} we may modify, not
because of using @code{ly:music-deep-copy} but because of a long-winded
explanation. We add the accent to its @code{'articulations} list
property.
@example
(set! place new-value)
@end example
Here, what we want to set (the @q{place}) is the @code{'articulations}
property of @code{note-event} expression.
@example
(ly:music-property note-event 'articulations)
@end example
@code{ly:music-property} is the function used to access music properties
(the @code{'articulations}, @code{'duration}, @code{'pitch}, etc, that we
see in the @code{\displayMusic} output above). The new value is the
former @code{'articulations} property, with an extra item: the
@code{ArticulationEvent} expression, which we copy from the
@code{\displayMusic} output,
@example
(cons (make-music 'ArticulationEvent
'articulation-type "accent")
(ly:music-property result-event-chord 'articulations))
@end example
@code{cons} is used to add an element to the front of a list without
modifying the original list. This is what we want: the same list as
before, plus the new @code{ArticulationEvent} expression. The order
inside the @code{'articulations} property is not important here.
Finally, once we have added the accent articulation to its
@code{articulations} property, we can return @code{note-event}, hence
the last line of the function.
Now we transform the @code{add-accent} function into a music function (a
matter of some syntactic sugar and a declaration of the type of its
argument).
@example
addAccent = #(define-music-function (note-event)
(ly:music?)
"Add an accent ArticulationEvent to the articulations of `note-event',
which is supposed to be a NoteEvent expression."
(set! (ly:music-property note-event 'articulations)
(cons (make-music 'ArticulationEvent
'articulation-type "accent")
(ly:music-property note-event 'articulations)))
note-event)
@end example
We then verify that this music function works correctly:
@example
\displayMusic \addAccent c4
@end example
@ignore
@menu
* Tweaking with Scheme::
@end menu
@c @nod e Tweaking with Scheme
@c @sectio n Tweaking with Scheme
We have seen how LilyPond output can be heavily modified using
commands like
@code{\override TextScript.extra-offset = ( 1 . -1)}. But
we have even more power if we use Scheme. For a full explanation
of this, see the @ref{Scheme tutorial}, and
@ref{Interfaces for programmers}.
We can use Scheme to simply @code{\override} commands,
TODO Find a simple example
@c This isn't a valid example with skylining
@c It works fine without padText -td
@end ignore
@ignore
@lilypond[quote,verbatim,ragged-right]
padText = #(define-music-function (padding) (number?)
#{
\once \override TextScript.padding = #padding
#})
\relative {
c'''4^"piu mosso" b a b
\padText #1.8
c4^"piu mosso" d e f
\padText #2.6
c4^"piu mosso" fis a g
}
@end lilypond
@end ignore
@ignore
We can use it to create new commands:
@c Check this is a valid example with skylining
@c It is - 'padding still works
@lilypond[quote,verbatim,ragged-right]
tempoPadded = #(define-music-function (padding tempotext)
(number? markup?)
#{
\once \override Score.MetronomeMark.padding = #padding
\tempo \markup { \bold #tempotext }
#})
\relative {
\tempo \markup { "Low tempo" }
c''4 d e f g1
\tempoPadded #4.0 "High tempo"
g4 f e d c1
}
@end lilypond
Even music expressions can be passed in:
@lilypond[quote,verbatim,ragged-right]
pattern = #(define-music-function (x y) (ly:music? ly:music?)
#{
#x e8 a b #y b a e
#})
\relative c''{
\pattern c8 c8\f
\pattern {d16 dis} { ais16-> b\p }
}
@end lilypond
@end ignore
|