Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From bb366150962b55e3 To afc1222e0282b772
|
2022-02-16
| ||
| 15:53 | core: fix: bad setting of voice parameters in the tune header with possible crash - reported by Hudson Lacerda ... (check-in: 8a9b5595a4 user: jef tags: trunk) | |
|
2022-02-12
| ||
| 17:42 | New release v1.21.6 ... (check-in: afc1222e02 user: jef tags: trunk, v1.21.6) | |
| 15:42 | core: add !caesura!, !tick! and !short! ... (check-in: 21e5a0d63b user: jef tags: trunk) | |
|
2021-01-27
| ||
| 09:43 | util: abcweb: fix: accept class abc with other classes - ticket [f632b51e4d] ... (check-in: 16278b1c38 user: jef tags: trunk) | |
|
2021-01-24
| ||
| 18:23 | New release v1.20.17 ... (check-in: bb36615096 user: jef tags: trunk, v1.20.17) | |
| 18:21 | core: play: separate %%soundfont from the other fonts definitions ... (check-in: ec8cb878ad user: jef tags: trunk) | |
Added MIT.txt.
> > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Changes to README.md.
1 2 3 4 5 6 7 |
<style>
p{margin-left:.5cm;max-width:21cm}
li{margin-left:.5cm;max-width:20cm}
li p{margin-left:0}
</style>
## abc2svg
| | | | | < < < < < | 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 |
<style>
p{margin-left:.5cm;max-width:21cm}
li{margin-left:.5cm;max-width:20cm}
li p{margin-left:0}
</style>
## abc2svg
**abc2svg** is a set of ECMAscript files that handle the
[ABC music notation](http://abcnotation.com/). This includes
editing, displaying, printing, playing the music files and
converting them to other formats such as ABC and MEI notations.
The **abc2svg** core is based on the
[abcm2ps](https://github.com/lewdlime/abcm2ps) C code
which requires compilation on every operating system.
The **abc2svg** scripts can run in any system with no compilation on
any platform that contains an internet browser. This includes MS-Windows,
Apple, and Unix-like systems (Linux, BSD...) as well as portable devices
such as cell phones and iPads.
A description of the ABC parameters that relate to both abcm2ps
and abc2svg can be found [here][1].
[1]: http://moinejf.free.fr/abcm2ps-doc/index.html "abc2svg documentation"
### 1. Web browser usage
#### 1.1 Rendering ABC files from a local or remote source
After accessing ABC files with a web browser either from a local or web
source, you can render or play the music without much preparation.
One approach uses [bookmarklets](https://en.wikipedia.org/wiki/Bookmarklet).
|
| ︙ | ︙ | |||
54 55 56 57 58 59 60 | Once you see the textual abc code, click on the bookmarklet that you created. After a slight delay depending upon the complexity of the abc code, it should be replaced by a music representation or a list of the contents of the ABC file. Here are two bookmarklets that you can try. This | | | | | | 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 |
Once you see the textual abc code, click on the bookmarklet
that you created. After a slight delay depending upon the
complexity of the abc code, it should be replaced by a music
representation or a list of the contents of the ABC file. Here
are two bookmarklets that you can try.
This
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='<style>svg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}</style>\n';b.innerHTML='\n%25abc-2.2%25%3c!--\n'+b.textContent+'%25--%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb-1.js');f('snd-1.js')})()"
title="Copy me">first abc2svg bookmarklet</a>
renders all the music it finds in the page currently displayed.
Once the music is displayed, clicking inside a tune starts playing it
from the beginning.
Clicking on a particular note or rest starts playing from that point.
To print or convert the music to a PDF file,
simply click on the 'Print' button of the web browser.
(If the 'Print' button does not appear on your browser menu,
try right clicking on the web page.)
Alternatively, if your source contains many tunes, you can
use this
<a href="javascript:(function(){var%20s,n=2,d=document,b=d.body;d.head.innerHTML='<style>svg{display:block};@media print{body{margin:0;padding:0;border:0};.nop{display:none}}</style>\n';b.innerHTML='\n%25abc-2.2%25%3c!--\n'+b.textContent+'%25--%3e\n';function%20f(u){s=d.createElement('script');s.src='http://moinejf.free.fr/js/'+u;s.onload=function(){if(--n==0)dom_loaded()};d.head.appendChild(s)};f('abcweb1-1.js');f('snd-1.js')})()"
title="Copy me">second bookmarklet</a>.
The browser will list the titles of the tunes.
Clicking on a title displays the tune.
Playing and printing work in the same manner as above.
The generated pages contain a yellow menu in the top right corner which permits
you to return to the tune list or to modify the music. With this last option,
you can adjust the page size before printing, correct the ABC syntax or
do some transposition.
Note that these changes stay only with the browser and are not saved
to your system.
|
| ︙ | ︙ | |||
132 133 134 135 136 137 138 | in the HTML <head> and put the music as ABC sequences in the <body>. [This example][4] demonstrates how to do it. (Note that, in the example, the paths are relative - see why below.) | | | | < < < < < | | | | | 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 |
in the HTML <head> and put the music as
ABC sequences in the <body>.
[This example][4] demonstrates how to do it.
(Note that, in the example, the paths are relative - see why below.)
[4]: http://moinejf.free.fr/abcm2ps-doc/tabac.html "J'ai du bon tabac"
As it is apparent, HTML and ABC can be mixed in the same html file.
Both are rendered in the order you defined them.
You may also have noticed this CSS about SVG elements:
` svg { display: block }`
This permits to have the music on separate vertical areas.
Without this CSS, the music is in-lined as in [this other example][5].
[5]: http://moinejf.free.fr/abcm2ps-doc/dansou-i.html "Tune index example"
Global ABC parameters may be added as `parameter=value` in the query string
of the URL of the page. The [following example][16] calls the same
"J'ai du bon tabac" with `pagescale=1.2` (giving `%%pagescale 1.2`).
[16]: http://moinejf.free.fr/abcm2ps-doc/tabac.html?pagescale=1.2 "J'ai du bon tabac"
In the above examples, all the ABC music is generated (displayed
and ready to be played) by means of the script **abcweb-1.js**.
If there is a large collection of tunes, it may be preferable to
link to the other script, **abcweb1-1.js**, which permits you
to select particular tune(s). Without an explicit
selection (see below), a list of the tunes is displayed, and,
after a tune has been selected, the whole page is replaced by the music.
(The HTML code, if any, is not displayed.)
A menu on the top right corner of the screen
permits to get the tune list again. Here is [a real example][6].
[6]: http://moinejf.free.fr/abc/boyvin-2-2.html "J. Boyvin organ tunes"
As you may notice in the menu, the edition of the ABC content is proposed.
This permits, for example, to transpose the tunes.
This edition is done inside the browser, so, your changes will be lost
after leaving the page.
When accessing such pages, an external selection of the tunes
can be accomplished by ending the URL with the character '`#`'
followed by a [regular expression][7]
to be applied to the tune headers.
For instance, here is the ['Duo' de J. Boyvin][8].
[7]: https://en.wikibooks.org/wiki/Regular_Expressions "Regular expressions"
[8]: http://moinejf.free.fr/abc/boyvin-2-2.html#T:Duo "Duo"
With any of the above scripts the music may be printed using
the 'Print' button of the browser. You should add a style as:
` @media print{body{margin:0;padding:0;border:0}.nop{display:none}}`
to remove the margins, the error messages and the menus from the
printed pages.
#### 1.4 Installing abc2svg on your system or on your server
The **abc2svg** package on my server is still being tuned
which could change its behaviour at any unknown time; so you may
prefer to install and run it from your own system.
There are many ways to install abc2svg:
- [Guido Gonzato's page](http://abcplus.sourceforge.net/#abc2svg)
Guido maintains a ZIP archive of the abc2vg scripts after
each release of a new version (many thanks, Guido!).
You can just download and unzip this archive. **abc2svg** should
run immediately in your machine without connecting to my site.
In the same page, you can also find some binaries of QuickJS,
a fast javascript interpreter (see below).
- tarball
From the timeline in the [chisel repository][13], you can get a tarball
any version of the abc2svg source and install it in your system.
The abc2svg scripts must then be built from the raw source files
described in the section 'Build' below.
The disadvantage of this approach is that if you want
to use an other or newer version you need to download a new tarball.
[13]: https://chiselapp.com/user/moinejf/repository/abc2svg/timeline
- fossil clone
If you can get the fossil program (one binary) for your system,
you may clone the chisel repository by
` fossil clone https://chiselapp.com/user/moinejf/repository/abc2svg abc2svg.fossil`
` fossil open abc2svg.fossil`
and get the abc2svg source files containing the last changes
between the official versions. Updating your files is done by
` fossil pull`
` fossil update`
Building the scripts is done in the same way as with a tarball.
The repository is presently over 34Mb.
For those unfamiliar with [fossil][14], it is an integrated
software management system similar to [git](https://git-scm.com/).
Chisel acts like a repository similar to [github](https://github.com/).
[14]: https://fossil-scm.org/home/doc/trunk/www/index.wiki
|
| ︙ | ︙ | |||
272 273 274 275 276 277 278 | You can automate the process of creating music sheets with **abc2svg** using shell scripts running a Javascript interpreter. The interfaces to the various scripts are different. Below you will find various scripts that I had to built. - `abcqjs` with `qjs` [QuickJS by Fabrice Bellard and Charlie Gordon][10] | | < < | < > > > > > | 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 | You can automate the process of creating music sheets with **abc2svg** using shell scripts running a Javascript interpreter. The interfaces to the various scripts are different. Below you will find various scripts that I had to built. - `abcqjs` with `qjs` [QuickJS by Fabrice Bellard and Charlie Gordon][10] - `abcmjs` with `js78`, `js68`, `js60`, `js52` or `js24` (Mozilla JavaScript shell) - `abcjsc` with `jsc` (webkit2gtk) - `abcnode` with `node` (nodeJS without module) - `abc2svg` with `node` (nodeJS with modules) [10]: https://bellard.org/quickjs/ Each script gets the abc2svg options and ABC files from the command line and sends the generated file to `stdout` and possible errors to `stderr`. The general syntax of the command line is: ` script [script.js] [options] ABC_file [[options] ABC_file]* [options]` with: - `script.js` is an optional backend script. It defaults to `tohtml.js` (HTML+SVG) - `options` are the ABC options. For compatibility, the last options are moved before the last ABC file. These scripts try to read a file `default.abc` at startup time. This file and also the files included by `%%abc-include` are searched in the current directory or in the colon separated list of directories contained in the environment variable `ABCPATH`. #### 2.2 Backend scripts By default, the shell scripts generate (HTML+SVG) files. This output may be modified by backend scripts. These ones must appear immediately following the name of the shell script. They are: |
| ︙ | ︙ | |||
314 315 316 317 318 319 320 | - `toabw.js` This script outputs an Abiword file (ABW+SVG) that can be read by some word processors (abiword, libreoffice...). The word processor allows you to convert the file to many other formats from a command line. The abc2svg music font (`abc2svf.woff` or `abc2svg.ttf`) must be installed in the local system for displaying and/or converting the .abw file. Example: | | > > > | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | - `toabw.js` This script outputs an Abiword file (ABW+SVG) that can be read by some word processors (abiword, libreoffice...). The word processor allows you to convert the file to many other formats from a command line. The abc2svg music font (`abc2svf.woff` or `abc2svg.ttf`) must be installed in the local system for displaying and/or converting the .abw file. Example: ` abcmjs toabw.js my_file.abc > my_file.abw` - `tomei.js` This script outputs the music as a [MEI](https://music-encoding.org/) file. Note, only one tune may be translated from ABC to MEI (multi-tunes ABC generates bad MEI). - `tonotes.js` This script outputs a list of the MIDI events. - `toodt.js` This script creates an Open Document (ODT+SVG) which can be read by most word processors (abiword, libreoffice...). It runs only with the shell script `abc2svg` and asks for the npm module `jszip` to be installed. The output ODT document may be specified in the command line argument after `-o` (default `abc.odt`). |
| ︙ | ︙ | |||
434 435 436 437 438 439 440 | [fullsvg documentation](http://moinejf.free.fr/abcm2ps-doc/fullsvg.xhtml) for more information). - Playing uses the HTML5 audio and/or the midi APIs. For audio, by default, abc2svg uses a sound font (format SF2) which is split into one file per instrument. This sound font is stored in the subdirectory `Scc1t2/`. | | < | | < < | | | > > > | > | > > > | | < | | > | | | | | | 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 |
[fullsvg documentation](http://moinejf.free.fr/abcm2ps-doc/fullsvg.xhtml)
for more information).
- Playing uses the HTML5 audio and/or the midi APIs.
For audio, by default, abc2svg uses a sound font (format SF2)
which is split into one file
per instrument. This sound font is stored in the subdirectory `Scc1t2/`.
Each instrument file is a base64 encoded javascript array.
Other sound fonts may be used. Some of them are stored in the subdirectory
`sf2/` (`AWE_ROM_gm` and `2MBGMGS`). Two formats are supported: raw SF2 and
SF2 wrapped into javascript (the raw SF2 files can be loaded
only when they are in the same HTTP domain).
The shell script `sf.sh` (in `sf2/`) may be used to create the javacript files
from raw SF2 files.
The sound font to be used for playing may be defined in the ABC code
by the command `%%soundfont`. E.g.:
` %%soundfont http://moinejf.free.fr/js/sf2/AWE_ROM_gm.js`
- The names of the abc2svg scripts have a suffix which is the version of
the core interface (actually '`-1`').
#### 4.3 More about the web scripts
Here are the scripts which are used in a web context:
- `abcweb-1.js`
This script replaces the ABC or MEI sequences found in the (X)HTML file
by SVG images of the music.
The ABC sequences are searched:
- first inside <script> elements with a type
["text/vnd.abc"](https://www.iana.org/assignments/media-types/text/vnd.abc)
(the script tag is removed from the page),
- or inside (X)HTML elements with a class `abc` (lower case letters),
- otherwise on `X:` or `%abc-` at start of line up to a XML tag at start of line.
When a ABC sequence is not included in a <script> and when it contains
the characters '<', '>' or '&',
it must be enclosed in a XML comment or in a CDATA
(%<![CDATA[ .. %]]> - the comment or CDATA must be in a ABC comment).
See the
[%%beginml documentation](http://moinejf.free.fr/abcm2ps-doc/beginml.xhtml)
for an example, and here is [how to put inline music in HTML][15].
Playing and highlighting the played notes may be offered loading
the script `snd-1.js` (see below).
[15]: http://moinejf.free.fr/abcm2ps-doc/inline.html "abc2svg - inline music"
- `abcweb1-1.js`
The page body is analyzed as a ABC file and its content is
replaced by music as SVG images.
If the page contains reserved XML characters ('<', '>' and '&'),
the ABC code must be enclosed in a
` <script type="text/vnd.abc"> .. </script>`
sequence.
When there are many tunes in the file, the script displays a list
of the tunes. The list step may be bypassed when the URL of the file
contains a regular expression in the 'hash' value ('#' followed by
a string at the end of the URL).
This string does a
[%%select](http://moinejf.free.fr/abcm2ps-doc/select.xhtml).
When one or many tunes are displayed, a menu in the top/right corner
offers to go back to the tune list or to modify the ABC source.
- `snd-1.js`
This script may be used with `abcweb-1.js` or `abcweb1-1.js`
to play the rendered ABC music.
- `abcdoc-1.js`
This script is mainly used for ABC documentation.
It lets the ABC source sequences in the page before the SVG images.
See the source of
[abcm2ps/abc2svg features](http://moinejf.free.fr/abcm2ps-doc/features.html)
for an example.
### 5. MEI support
As an experimental feature, an extended core `mei2svg-1.js` may be generated.
This one may handle both the ABC and
[MEI](https://music-encoding.org/ "Music Encoding Initiative")
notations.
In browser mode, the script `abcweb-1.js` loads either `abc2svg-1.js` or
`mei2svg-1.js` after checking if `<mei` exists in the page (see
[this tune](http://moinejf.free.fr/abc/Czerny_op603_6.html)
|
| ︙ | ︙ |
Changes to abc2svg.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 |
}
abc2svg.quit = function() {
process.exit(1)
}
abc2svg.readFile = function(fname) {
var fs = require("fs")
| > | > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
}
abc2svg.quit = function() {
process.exit(1)
}
abc2svg.readFile = function(fname) {
var fs = require("fs")
try {
return fs.readFileSync(fname).toString()
} catch(e) {
}
return null
}
abc2svg.get_mtime = function(fn) {
var fs = require("fs")
return fs.statSync(fn).mtime
}
|
| ︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 |
}
// load the command line
m = require("abc2svg/cmdline");
global.user = m.user;
global.abc_cmd = m.abc_cmd
// main
var args = process.argv
args.shift();
args.shift()
| > > > > > | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
}
// load the command line
m = require("abc2svg/cmdline");
global.user = m.user;
global.abc_cmd = m.abc_cmd
// set the ABC path
var path = process.env.ABCPATH
if (path)
abc2svg.path = path.split(':')
// main
var args = process.argv
args.shift();
args.shift()
abc_cmd("abc2svg", args, "nodeJS")
|
Changes to abc2svg.ttf.
cannot compute difference between binary files
Changes to abcjsc.
1 2 | #!/bin/sh # abc2svg with jsc (webkit2gtk) | > > > > > > > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/sh
# abc2svg with jsc (webkit2gtk)
# search where are the abc2svg scripts
c=$0
if [ `dirname $c` = . ]; then
c=`which $c`
fi
if [ -L $c ]; then
c=`realpath $c`
fi
c=`dirname $c`
exec jsc -e "var progdir='${c}/'
// function to do utf-8 work...
// uncommenting this function asks for also uncommenting its call in cmdline.js
//function utf_convert(fin) {
// var b1, b2, b3,
// fout = ''
// for (var i = 0; i < fin.length; i++) {
|
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
printErr: function(str) {
printErr(str)
},
quit: function() {
quit(1)
},
readFile: function(fname) {
| > | > > > > > > > > > > > | 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 |
printErr: function(str) {
printErr(str)
},
quit: function() {
quit(1)
},
readFile: function(fname) {
try {
return read(fname)
} catch(e) {
}
return null
},
loadjs: function(fn, relay, onerror) {
try {
load(progdir + fn)
if (relay)
relay()
} catch(e) {
if (onerror)
onerror()
else
printErr('Cannot read file ' + fn)
}
} // loadjs()
} // abc2svg
load(progdir + 'abc2svg-1.js')
load(progdir + 'cmdline.js')
function main(args) {
var i = '${ABCPATH}'
console = {
log: printErr
}
if (i)
abc2svg.path = i.split(':')
abc_cmd('abcjsc', args, 'jsc (webkit2gtk)')
}
if (typeof arguments == 'undefined')
var arguments = ''
main(arguments)
" -- "$@"
|
Added abcmjs.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
:;# abc2svg with a Mozilla JavaScript interpreter
for c in js78 js68 js60 js52 js24 end; do
if [ $c = 'end' ]; then
echo "$0: could not find a javascript interpreter - abort"
exit 1
fi
if command -v $c >/dev/null 2>&1; then
break
fi
done
# search where are the abc2svg scripts
p=$0
if [ `dirname $p` = . ]; then
p=`which $p`
fi
if [ -L $p ]; then
p=`realpath $p`
fi
p=`dirname $p`
exec $c -e "// interpreter specific functions
var abc2svg = {
print: print,
printErr: printErr,
quit: function() {
quit(1)
},
readFile: function(fn) {
try {
return read(fn)
} catch(e) {
}
return null
},
loadjs: function(fn, relay, onerror) {
try {
load(fn[0] == '/' ? fn : (path + fn))
if (relay)
relay()
} catch(e) {
if (onerror)
onerror()
else
printErr('Cannot read file ' + fn)
}
} // loadjs()
} // abc2svg
var args = scriptArgs,
path = '${ABCPATH}'
if (path)
abc2svg.path = path.split(':')
path = '${p}/' // path to the abc2svg scripts
console.log = printErr
load(path + 'abc2svg-1.js')
load(path + 'cmdline.js')
// main
abc_cmd('abcmjs', args, '${c}')
" -- "$@"
|
Changes to abcnode.
1 | :;# abc2svg with raw nodeJS | > > > > > > > > > | | | | > | > > > | | > > > > | | 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 |
:;# abc2svg with raw nodeJS
# search where are the abc2svg scripts
p=$0
if [ `dirname $p` = . ]; then
p=`which $p`
fi
if [ -L $p ]; then
p=`realpath $p`
fi
p=`dirname $p`
cat ${p}/abc2svg-1.js ${p}/cmdline.js > /tmp/toto.js
case $1 in
*.js)
cat $1 >> /tmp/toto.js
if grep 'abc2svg.abc_init =' "$1" > /dev/null; then
x="no"
fi
shift
;;
esac
if [ "x$x" != 'xno' ]; then
cat ${p}/tohtml.js >> /tmp/toto.js
fi
cat <<EOF >> /tmp/toto.js
var path='${p}/'
// interpreter specific functions
abc2svg.print = function(str) {
process.stdout.write(str + '\n')
}
abc2svg.printErr = function(str) {
process.stderr.write(str + '\n')
}
abc2svg.quit = function() {
process.exit(1)
}
abc2svg.readFile = function(fname) {
var fs = require("fs");
try {
return fs.readFileSync(fname).toString()
} catch(e) {
}
return null
}
abc2svg.get_mtime= function(fn) {
var fs = require("fs")
return fs.statSync(fn).mtime
}
abc2svg.loadjs = function(fn, relay, onerror) {
try {
var geval = eval;
geval(abc2svg.readFile(path + fn))
if (relay)
relay()
} catch(e) {
if (onerror)
onerror()
else
abc2svg.printErr('Cannot read file ' + fn)
}
}
// (this file is wrapped)
global.Abc = Abc
global.abc2svg = abc2svg
// main
var args = process.argv,
i = '${ABCPATH}'
if (i)
abc2svg.path = i.split(':')
args.shift()
args.shift()
global.user = user; // (for modules/page.js)
abc_cmd("abcnode", args, "nodeJS")
EOF
node /tmp/toto.js "$@"
|
Changes to abcqjs.
1 2 3 4 5 6 7 8 |
:;# shell script to convert ABC or MEI music notation to other format
# using abc2svg and quickjs (https://bellard.org/quickjs/)
exec qjs --std -e '
var i,
args = scriptArgs,
core = "abc2svg-1.js",
| > > > > > > > > > > | < | < < | < < < < < < < < < < > > < < > | > > > | | 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 |
:;# shell script to convert ABC or MEI music notation to other format
# using abc2svg and quickjs (https://bellard.org/quickjs/)
# search where are the abc2svg scripts
p=$0
if [ `dirname $p` = . ]; then
p=`which $p`
fi
if [ -L $p ]; then
p=`realpath $p`
fi
p=`dirname $p`
exec qjs --std -e '
var i,
args = scriptArgs,
core = "abc2svg-1.js",
path = args.shift() + "/" // the 1st argument is the script path
// interpreter specific functions
function load(fn) {
return std.loadScript(fn)
}
var abc2svg = {
print: print,
printErr: function(str) {
std.err.printf("%s\n", str)
},
quit: function() {
std.exit(1)
},
readFile: std.loadFile,
get_mtime: function(fn) {
return new Date(os.stat(fn)[0].mtime)
},
loadjs: function(fn, relay, onerror) {
try {
load(fn[0] == "/" ? fn : (path + fn))
if (relay)
relay()
} catch(e) {
if (onerror)
onerror()
else
abc2svg.printErr("Cannot read file " + fn +
"\n " + e.name + ": " + e.message)
return
}
} // loadjs()
} // abc2svg
// --- main ---
console.log = abc2svg.printErr
i = std.getenv("ABCPATH")
if (i)
abc2svg.path = i.split(":")
i = args.length
while (--i >= 0) {
if (/\.mei$/.test(args[i])) {
core = "mei2svg-1.js"
break
}
}
load(path + core)
load(path + "cmdline.js")
abc_cmd("abcqjs", args, "QuickJS")
' $p "$@"
The previous solution with the shebang line as
#!/usr/bin/env -S qjs --std
did not work with non-GNU versions of env
|
Changes to abctopdf.
1 2 3 | :;# abctopdf # convert ABC to PDF using abc2svg and one of # - a chrome/chromium compatible web browser | | < | | < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | :;# abctopdf # convert ABC to PDF using abc2svg and one of # - a chrome/chromium compatible web browser # (if not found, you can set its name in the environment variable 'BROWSER') # - weasyprint (https://weasyprint.org/) # # Note: when weasyprint is used, # this script forces A4 as the paper size. # For an other size, change # 'size: A4' and '--pageheight 29.7cm' # # Copyright (C) 2019-2021 Jean-François Moine - License GPL3+ # set a browser if [ "x$BROWSER" = "x" ]; then BROWSER=chromium fi if [ $# -eq 0 ]; then cat << EOF ABC to PDF translator using abc2svg Usage: |
| ︙ | ︙ | |||
84 85 86 87 88 89 90 | else set -- "$@" "$a" fi shift done # check if some chromium-based browser is available | | | | > | | < < < < < < < < < < | > > > < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 |
else
set -- "$@" "$a"
fi
shift
done
# check if some chromium-based browser is available
for c in "$BROWSER" chromium-browser vivaldi opera brave-browser epic google-chrome; do
if command -v "$c" >/dev/null 2>&1; then
echo "and $c"
command $abcscr "$@" > /tmp/o.html
"$c" --headless --disable-gpu\
--print-to-pdf=$out --print-to-pdf-no-header /tmp/o.html
rm /tmp/o.html
exit 0
fi
done
# try weasyprint
if command -v weasyprint >/dev/null 2>&1; then
echo "and weasyprint"
rm -f /tmp/abc*.svg /tmp/abc.html
# generate a (HTML+SVG) file
# then, extract the SVG images (pages) to /tmp/ and build a file.html
touch /tmp/abc.html
n=0
command $abcscr --pageheight 29.7cm --fullsvg 1 --musicfont abc2svg "$@" | while read v; do
case "$v" in
"<svg"*)
n=$(($n+1))
fn="/tmp/abc$n.svg"
echo $v > $fn
echo "<img src=\"/tmp/abc${n}.svg\"/>" >> /tmp/abc.html
;;
"</svg"*)
echo $v >> $fn
fn=
;;
"<body>")
echo '<body bgcolor="white">' >> /tmp/abc.html
;;
"</body"*)
break;;
*)
if [ "X$fn" != "X" ]; then
echo $v >> $fn
else
echo $v >> /tmp/abc.html
fi
;;
esac
done
echo '</body>' >> /tmp/abc.html
echo weasyprint -f pdf /tmp/abc.html $out
weasyprint -f pdf /tmp/abc.html $out
rm -f /tmp/abc*.svg /tmp/abc.html
exit 0
fi
echo "$0: no program found for SVG to PDF translation - abort"
exit 1
|
Changes to build.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | gen modules/gamelan.js > gamelan-$MAJOR.js gen modules/grid.js > grid-$MAJOR.js gen modules/grid2.js > grid2-$MAJOR.js gen modules/grid3.js > grid3-$MAJOR.js gen modules/jazzchord.js > jazzchord-$MAJOR.js gen modules/jianpu.js > jianpu-$MAJOR.js gen modules/mdnn.js > mdnn-$MAJOR.js gen modules/MIDI.js > MIDI-$MAJOR.js gen modules/page.js modules/strftime.js > page-$MAJOR.js gen modules/pedline.js > pedline-$MAJOR.js gen modules/perc.js > perc-$MAJOR.js gen modules/wps.js modules/psvg.js > psvg-$MAJOR.js gen modules/soloffs.js > soloffs-$MAJOR.js gen modules/sth.js > sth-$MAJOR.js gen modules/strtab.js > strtab-$MAJOR.js gen modules/temper.js > temper-$MAJOR.js cp editor/edit.css edit-$MAJOR.css | > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | gen modules/gamelan.js > gamelan-$MAJOR.js gen modules/grid.js > grid-$MAJOR.js gen modules/grid2.js > grid2-$MAJOR.js gen modules/grid3.js > grid3-$MAJOR.js gen modules/jazzchord.js > jazzchord-$MAJOR.js gen modules/jianpu.js > jianpu-$MAJOR.js gen modules/mdnn.js > mdnn-$MAJOR.js gen modules/nns.js > nns-$MAJOR.js gen modules/MIDI.js > MIDI-$MAJOR.js gen modules/page.js modules/strftime.js > page-$MAJOR.js gen modules/pedline.js > pedline-$MAJOR.js gen modules/perc.js > perc-$MAJOR.js gen modules/wps.js modules/psvg.js > psvg-$MAJOR.js gen modules/roman.js > roman-$MAJOR.js gen modules/soloffs.js > soloffs-$MAJOR.js gen modules/sth.js > sth-$MAJOR.js gen modules/strtab.js > strtab-$MAJOR.js gen modules/temper.js > temper-$MAJOR.js cp editor/edit.css edit-$MAJOR.css |
| ︙ | ︙ |
Changes to build.ninja.
| ︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | build grid-$MAJOR.js: jscu modules/grid.js build grid2-$MAJOR.js: jscu modules/grid2.js build grid3-$MAJOR.js: jscu modules/grid3.js build jazzchord-$MAJOR.js: jscu modules/jazzchord.js build jianpu-$MAJOR.js: jscu modules/jianpu.js build mdnn-$MAJOR.js: jscu modules/mdnn.js build MIDI-$MAJOR.js: jscu modules/MIDI.js build page-$MAJOR.js: jscu modules/page.js modules/strftime.js build pedline-$MAJOR.js: jscu modules/pedline.js build perc-$MAJOR.js: jscu modules/perc.js build psvg-$MAJOR.js: jscu modules/wps.js modules/psvg.js build soloffs-$MAJOR.js: jscu modules/soloffs.js build sth-$MAJOR.js: jscu modules/sth.js build strtab-$MAJOR.js: jscu modules/strtab.js build temper-$MAJOR.js: jscu modules/temper.js build edit-$MAJOR.css: cp editor/edit.css | > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | build grid-$MAJOR.js: jscu modules/grid.js build grid2-$MAJOR.js: jscu modules/grid2.js build grid3-$MAJOR.js: jscu modules/grid3.js build jazzchord-$MAJOR.js: jscu modules/jazzchord.js build jianpu-$MAJOR.js: jscu modules/jianpu.js build mdnn-$MAJOR.js: jscu modules/mdnn.js build MIDI-$MAJOR.js: jscu modules/MIDI.js build nns-$MAJOR.js: jscu modules/nns.js build page-$MAJOR.js: jscu modules/page.js modules/strftime.js build pedline-$MAJOR.js: jscu modules/pedline.js build perc-$MAJOR.js: jscu modules/perc.js build psvg-$MAJOR.js: jscu modules/wps.js modules/psvg.js build roman-$MAJOR.js: jscu modules/roman.js build soloffs-$MAJOR.js: jscu modules/soloffs.js build sth-$MAJOR.js: jscu modules/sth.js build strtab-$MAJOR.js: jscu modules/strtab.js build temper-$MAJOR.js: jscu modules/temper.js build edit-$MAJOR.css: cp editor/edit.css |
| ︙ | ︙ | |||
147 148 149 150 151 152 153 | abcemb-$MAJOR.js abcemb1-$MAJOR.js abcemb2-$MAJOR.js $ abcweb-$MAJOR.js abcweb1-$MAJOR.js abcweb2-$MAJOR.js chord-$MAJOR.js $ json-$MAJOR.js toaudio-$MAJOR.js snd-$MAJOR.js play-$MAJOR.js psvg-$MAJOR.js $ ambitus-$MAJOR.js break-$MAJOR.js capo-$MAJOR.js $ chordnames-$MAJOR.js clair-$MAJOR.js clip-$MAJOR.js $ combine-$MAJOR.js diag-$MAJOR.js equalbars-$MAJOR.js gamelan-$MAJOR.js $ grid-$MAJOR.js grid2-$MAJOR.js grid3-$MAJOR.js jianpu-$MAJOR.js $ | | | | | | 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 | abcemb-$MAJOR.js abcemb1-$MAJOR.js abcemb2-$MAJOR.js $ abcweb-$MAJOR.js abcweb1-$MAJOR.js abcweb2-$MAJOR.js chord-$MAJOR.js $ json-$MAJOR.js toaudio-$MAJOR.js snd-$MAJOR.js play-$MAJOR.js psvg-$MAJOR.js $ ambitus-$MAJOR.js break-$MAJOR.js capo-$MAJOR.js $ chordnames-$MAJOR.js clair-$MAJOR.js clip-$MAJOR.js $ combine-$MAJOR.js diag-$MAJOR.js equalbars-$MAJOR.js gamelan-$MAJOR.js $ grid-$MAJOR.js grid2-$MAJOR.js grid3-$MAJOR.js jianpu-$MAJOR.js $ jazzchord-$MAJOR.js mdnn-$MAJOR.js MIDI-$MAJOR.js $ nns-$MAJOR.js page-$MAJOR.js pedline-$MAJOR.js perc-$MAJOR.js $ roman-$MAJOR.js soloffs-$MAJOR.js sth-$MAJOR.js strtab-$MAJOR.js $ temper-$MAJOR.js edit-$MAJOR.css edit-$MAJOR.js edit-$MAJOR.xhtml $ abckbd-$MAJOR.js abckbd2-$MAJOR.js follow-$MAJOR.js # not mei2svg-$MAJOR.js default all # npm/fossil new release rule version command = npm version $out;$ tag=`ag -Q '"version"' package.json|cut -d'"' -f4`;$ fossil commit -m "New release v$$tag" -tag v$$tag;$ $tool -v;$ echo 'do "npm publish --otp <authy_code>"' build minor: version build patch: version # temporary rule nul command = touch $out build follow-$MAJOR.js: nul |
Changes to cmdline.js.
1 2 | // abc2svg - cmdline.js - command line // | | > | > > > > > > > > > > > > > > > > > > > | < < | | | < | > > > > < < < | < < < < < < < < < < < | 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 |
// abc2svg - cmdline.js - command line
//
// Copyright (C) 2014-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// user definitions
var user = {
read_file: function(fn) { // read a file (main or included)
var i,
p = fn,
file = abc2svg.readFile(p)
if (!file && fn[0] != '/') {
for (i = 0; i < abc2svg.path.length; i++) {
p = abc2svg.path[i] + '/' + fn
file = abc2svg.readFile(p)
if (file)
break
}
}
if (!file)
return file
// memorize the file path
i = p.lastIndexOf('/')
if (i > 0) {
p = p.slice(0, i)
if (abc2svg.path.indexOf(p) < 0)
abc2svg.path.unshift(p)
}
// convert the file content into a Unix string
i = file.indexOf('\r')
if (i >= 0) {
if (file[i + 1] == '\n')
file = file.replace(/\r\n/g, '\n') // M$
else
fike = file.replace(/\r/g, '\n') // Mac
}
// load the required modules (synchronous)
abc2svg.modules.load(file)
return file
},
errtxt: '',
errmsg: // print or store the error messages
typeof abc2svg.printErr == 'function'
? function(msg, l, c) { abc2svg.printErr(msg) }
: function(msg, l, c) { user.errtxt += msg + '\n' }
} // user
var abc // (global for 'toxxx.js')
if (!abc2svg.path)
abc2svg.path = [] // path to ABC files - from env ABCPATH
// treat a file
function do_file(fn) {
var file = user.read_file(fn)
if (!file) {
if (fn != "default.abc")
user.errmsg("Cannot read file '" + fn + "'")
return
}
// if (typeof(utf_convert) == "function")
// file = utf_convert(file)
|
| ︙ | ︙ | |||
108 109 110 111 112 113 114 | i -= 2 f = a[--i] a.splice(i, 1) a.push(f) } // arg_reorder() // if the first argument is a javascript file, load it | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
i -= 2
f = a[--i]
a.splice(i, 1)
a.push(f)
} // arg_reorder()
// if the first argument is a javascript file, load it
if (args[0] && args[0].slice(-3) == '.js') {
abc2svg.loadjs(args[0])
args.shift()
}
if (!args[0]) {
abc2svg.printErr('ABC translator with ' + interp_name +
' and abc2svg-' + abc2svg.version + ' ' +
|
| ︙ | ︙ |
Changes to core/abc2svg.js.
1 2 | // abc2svg - abc2svg.js // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - abc2svg.js // // Copyright (C) 2014-2021 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
46 47 48 49 50 51 52 | // note heads FULL: 0, EMPTY: 1, OVAL: 2, OVALBARS: 3, SQUARE: 4, | | | | > > > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// note heads
FULL: 0,
EMPTY: 1,
OVAL: 2,
OVALBARS: 3,
SQUARE: 4,
// position types
SL_ABOVE: 0x01, // position (3 bits)
SL_BELOW: 0x02,
SL_AUTO: 0x03,
SL_HIDDEN: 0x04,
SL_DOTTED: 0x08, // modifiers
SL_ALI_MSK: 0x70, // align
SL_ALIGN: 0x10,
SL_CENTER: 0x20,
SL_CLOSE: 0x40
};
// !! tied to the symbol types in abc2svg.js !!
abc2svg.sym_name = ['bar', 'clef', 'custos', '', 'grace',
'key', 'meter', 'Zrest', 'note', 'part',
'rest', 'yspace', 'staves', 'Break', 'tempo',
'', 'block', 'remark']
|
| ︙ | ︙ | |||
169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
"min+7": "m+7",
"aug7": "+7",
"7+5": "+7",
"7#5": "+7",
"sus": "sus4",
"7sus": "7sus4"
} // ch_alias
// simplify a rational number n/d
abc2svg.rat = function(n, d) {
var a, t,
n0 = 0,
d1 = 0,
n1 = 1,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
"min+7": "m+7",
"aug7": "+7",
"7+5": "+7",
"7#5": "+7",
"sus": "sus4",
"7sus": "7sus4"
} // ch_alias
// extract one of the chord symbols
// With chords as "xxx(yyy)" or "[yyy];xxx"
// (!sel - default) returns "xxx" and (sel) returns "yyy"
abc2svg.cs_sel0 = /[\[(].*[\])]/g
abc2svg.cs_sel1 = /.*[\[(]|[\])].*/g
abc2svg.cs_filter = function(a_cs, sel) {
var i, cs,
tcs = ""
for (i = 0; i < a_cs.length; i++) {
cs = a_cs[i]
if (cs.type == 'g')
tcs += cs.text
}
return tcs.replace(sel ? abc2svg.cs_sel1 : abc2svg.cs_sel0, '')
} // cs_filter()
// font weight
// reference:
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
abc2svg.ft_w = {
thin: 100,
extralight: 200,
light: 300,
regular: 400,
medium: 500,
semi: 600,
demi: 600,
semibold: 600,
demibold: 600,
bold: 700,
extrabold: 800,
ultrabold: 800,
black: 900,
heavy: 900
}
abc2svg.ft_re = new RegExp('\
-?Thin|-?Extra Light|-?Light|-?Regular|-?Medium|\
-?[DS]emi|-?[DS]emi[ -]?Bold|\
-?Bold|-?Extra[ -]?Bold|-?Ultra[ -]?Bold|-?Black|-?Heavy/',
"i")
// simplify a rational number n/d
abc2svg.rat = function(n, d) {
var a, t,
n0 = 0,
d1 = 0,
n1 = 1,
|
| ︙ | ︙ | |||
230 231 232 233 234 235 236 | CLOSE_BRACE2 = 0x0200, OPEN_BRACKET2 = 0x0400, CLOSE_BRACKET2 = 0x0800, MASTER_VOICE = 0x1000, IN = 96, // resolution 96 PPI CM = 37.8, // 1 inch = 2.54 centimeter | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
CLOSE_BRACE2 = 0x0200,
OPEN_BRACKET2 = 0x0400,
CLOSE_BRACKET2 = 0x0800,
MASTER_VOICE = 0x1000,
IN = 96, // resolution 96 PPI
CM = 37.8, // 1 inch = 2.54 centimeter
YSTEP // number of steps for y offsets
// error texts
var errs = {
bad_char: "Bad character '$1'",
bad_grace: "Bad character in grace note sequence",
bad_transp: "Bad transpose value",
bad_val: "Bad value in $1",
|
| ︙ | ︙ | |||
278 279 280 281 282 283 284 |
// utilities
function clone(obj, lvl) {
if (!obj)
return obj
var tmp = new obj.constructor
for (var k in obj)
if (obj.hasOwnProperty(k)) {
| | | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
// utilities
function clone(obj, lvl) {
if (!obj)
return obj
var tmp = new obj.constructor
for (var k in obj)
if (obj.hasOwnProperty(k)) {
if (lvl && typeof obj[k] == "object")
tmp[k] = clone(obj[k], lvl - 1)
else
tmp[k] = obj[k]
}
return tmp
}
|
| ︙ | ︙ |
Changes to core/deco.js.
1 2 | // abc2svg - deco.js - decorations // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - deco.js - decorations // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
48 49 50 51 52 53 54 |
// up, // above the symbol
// val, // value
// x, // x offset
// y, // y offset
// }
var dd_tb = {}, // definition of the decorations
| | > | | | | < | | < | < | < < | | | | | | | | | | | | > > > > > > > > > > > > > > > > | | | | | | | | > | | | < | | | | | | | | | | | | < < < < < < < < | 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 |
// up, // above the symbol
// val, // value
// x, // x offset
// y, // y offset
// }
var dd_tb = {}, // definition of the decorations
a_de, // array of the decoration elements
cross // cross voice decorations
// decorations - populate with standard decorations
var decos = {
dot: "0 stc 6 1 1",
tenuto: "0 emb 6 3 3",
slide: "1 sld 3 7 0",
arpeggio: "2 arp 12 10 2",
roll: "3 roll 3,3 6 6",
emphasis: "3 accent 3.5,3.5 4 4",
lowermordent: "3 lmrd 4,4 5 5",
uppermordent: "3 umrd 4,4 5 5",
trill: "3 trl 14 5 5",
upbow: "3 upb 10 5 5",
downbow: "3 dnb 9 5 5",
gmark: "3 grm 6 5 5",
wedge: "0 wedge 8 3 3", // (staccatissimo or spiccato)
longphrase: "3 lphr 0 1 1",
mediumphrase: "3 mphr 0 1 1",
shortphrase: "3 sphr 0 1 1",
turnx: "3 turnx 5,5 6 6",
invertedturn: "3 turn 5,5 6 6",
invertedturnx: "3 turnx 5,5 6 6",
"0": "3 fng 5,5 3 3 0",
"1": "3 fng 5,5 3 3 1",
"2": "3 fng 5,5 3 3 2",
"3": "3 fng 5,5 3 3 3",
"4": "3 fng 5,5 3 3 4",
"5": "3 fng 5,5 3 3 5",
plus: "3 dplus 7 3 3",
"+": "3 dplus 7 3 3",
accent: "3 accent 3.5,3.5 4 4",
">": "3 accent 3.5,3.5 4 4",
marcato: "3 marcato 9 3 3",
"^": "3 marcato 9 3 3",
mordent: "3 lmrd 4,4 5 5",
open: "3 opend 10 3 3",
snap: "3 snap 14 3 3",
thumb: "3 thumb 14 3 3",
turn: "3 turn 5,5 6 6",
"trill(": "3 ltr 8 4 0",
"trill)": "3 ltr 8 4 0",
"8va(": "5 8va 12 6 6",
"8va)": "5 8va 12 6 6",
"8vb(": "7 8vb 12 6 6",
"8vb)": "7 8vb 12 6 6",
"15ma(": "5 15ma 12 9 9",
"15ma)": "5 15ma 12 9 9",
"15mb(": "7 15mb 12 9 9",
"15mb)": "7 15mb 12 9 9",
breath: "5 brth 0 1 20",
caesura: "5 caes 0 1 10",
short: "5 short 0 1 4",
tick: "5 tick 0 1 4",
coda: "5 coda 24 10 10",
dacapo: "5 dacs 16 20 20 Da Capo",
dacoda: "5 dacs 16 20 20 Da Coda",
"D.C.": "5 dcap 16 10 10",
"D.S.": "5 dsgn 16 10 10",
"D.C.alcoda": "5 dacs 16 38 38 D.C. al Coda",
"D.S.alcoda": "5 dacs 16 38 38 D.S. al Coda",
"D.C.alfine": "5 dacs 16 38 38 D.C. al Fine",
"D.S.alfine": "5 dacs 16 38 38 D.S. al Fine",
fermata: "5 hld 12 7 7",
fine: "5 dacs 16 10 10 Fine",
invertedfermata: "7 hld 12 7 7",
segno: "5 sgno 22 8 8",
f: "6 f 18 4 4",
ff: "6 ff 18 6 6",
fff: "6 fff 18 9 9",
ffff: "6 ffff 18 12 12",
mf: "6 mf 18 9 9",
mp: "6 mp 18 10 10",
p: "6 p 18 5 5",
pp: "6 pp 18 9 9",
ppp: "6 ppp 18 13 13",
pppp: "6 pppp 18 17 17",
pralltriller: "3 umrd 4,4 5 5",
sfz: "6 sfz 18 8 8",
ped: "4 ped 18 6 10",
"ped-up": "4 pedoff 12 4 4",
"ped(": "4 lped 20 5 5",
"ped)": "4 lped 20 5 5",
"crescendo(": "6 cresc 18 0 0",
"crescendo)": "6 cresc 18 0 0",
"<(": "6 cresc 18 0 0",
"<)": "6 cresc 18 0 0",
"diminuendo(": "6 dim 18 0 0",
"diminuendo)": "6 dim 18 0 0",
">(": "6 dim 18 0 0",
">)": "6 dim 18 0 0",
"-(": "8 gliss 0 0 0",
"-)": "8 gliss 0 0 0",
"~(": "8 glisq 0 0 0",
"~)": "8 glisq 0 0 0",
// internal
// color: "10 0 0 0 0",
invisible: "32 0 0 0 0",
beamon: "33 0 0 0 0",
trem1: "34 0 0 0 0",
trem2: "34 0 0 0 0",
trem3: "34 0 0 0 0",
|
| ︙ | ︙ | |||
166 167 168 169 170 171 172 | editorial: "42 0 0 0 0", "sacc-1": "3 sacc-1 6,4 4 4", sacc3: "3 sacc3 6,5 4 4", sacc1: "3 sacc1 6,4 4 4", courtesy: "43 0 0 0 0", "cacc-1": "3 cacc-1 0 0 0", cacc3: "3 cacc3 0 0 0", | | > > | > > > > | > > > > | > > > > > | | | 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 |
editorial: "42 0 0 0 0",
"sacc-1": "3 sacc-1 6,4 4 4",
sacc3: "3 sacc3 6,5 4 4",
sacc1: "3 sacc1 6,4 4 4",
courtesy: "43 0 0 0 0",
"cacc-1": "3 cacc-1 0 0 0",
cacc3: "3 cacc3 0 0 0",
cacc1: "3 cacc1 0 0 0",
"tie(": "44 0 0 0 0",
"tie)": "44 0 0 0 0"},
// types of decoration per function
f_near = [
d_near, // 0 - near the note
d_slide, // 1
d_arp // 2
],
f_note = [
null, null, null,
d_upstaff, // 3 - tied to note
d_upstaff // 4 (below the staff)
],
f_staff = [
null, null, null, null, null,
d_upstaff, // 5 (above the staff)
d_pf, // 6 - tied to staff (dynamic marks)
d_upstaff // 7 (below the staff)
]
/* -- get the max/min vertical offset -- */
function y_get(st, up, x, w) {
var y,
p_staff = staff_tb[st],
i = (x / 2) | 0,
j = ((x + w) / 2) | 0
if (i < 0)
i = 0
if (j >= YSTEP) {
j = YSTEP - 1
if (i > j)
i = j
|
| ︙ | ︙ | |||
207 208 209 210 211 212 213 |
}
}
return y
}
/* -- adjust the vertical offsets -- */
function y_set(st, up, x, w, y) {
| | | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
}
}
return y
}
/* -- adjust the vertical offsets -- */
function y_set(st, up, x, w, y) {
var p_staff = staff_tb[st],
i = (x / 2) | 0,
j = ((x + w) / 2) | 0
/* (may occur when annotation on 'y' at start of an empty staff) */
if (i < 0)
i = 0
if (j >= YSTEP) {
j = YSTEP - 1
if (i > j)
|
| ︙ | ︙ | |||
234 235 236 237 238 239 240 | if (p_staff.bot[i] > y) p_staff.bot[i] = y; i++ } } } | > > > > > > > > > > > > > > | | | | | | | | | 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 |
if (p_staff.bot[i] > y)
p_staff.bot[i] = y;
i++
}
}
}
// get the staff position
// - of the ornements
function up3(s, pos) {
switch (pos & 0x07) {
case C.SL_ABOVE:
return 1 // true
case C.SL_BELOW:
return 0 // false
}
if (s.multi)
return s.multi > 0
return 1 // true
} // up3()
// - of the dynamic and volume marks
function up6(s, pos) {
switch (pos & 0x07) {
case C.SL_ABOVE:
return true
case C.SL_BELOW:
return false
}
if (s.multi)
return s.multi > 0
if (!s.p_v.have_ly)
return false
/* above if the lyrics are below the staff */
return (s.pos.voc & 0x07) != C.SL_ABOVE
}
/* -- drawing functions -- */
/* 2: special case for arpeggio */
function d_arp(de) {
var m, h, dx,
s = de.s,
dd = de.dd,
xc = dd.wr
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
if (s.notes[m].acc) {
dx = s.notes[m].shac
} else {
dx = 1 - s.notes[m].shhd
switch (s.head) {
case C.SQUARE:
dx += 3.5
break
case C.OVALBARS:
case C.OVAL:
dx += 2
|
| ︙ | ︙ | |||
288 289 290 291 292 293 294 | if (h < m) h = m; de.has_val = true; de.val = h; // de.x = s.x - xc; de.x -= xc; | | | > | | < < | | < < < > > > | | | > > | > > > > > | | > > > | > | > | | > > | | > > > > | | > | > | | | > > | < < > > > > > > | < | < < < < < < | < < | | > | > > | | > | > | 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 |
if (h < m)
h = m;
de.has_val = true;
de.val = h;
// de.x = s.x - xc;
de.x -= xc;
de.y = 3 * ((s.notes[0].pit + s.notes[s.nhd].pit) / 2 - 18) - h / 2 - 3
}
// special case for long dynamic decorations
function d_cresc(de) {
if (de.ldst) // skip start of deco
return
var up, dx, x2, i, de3,
dd = de.dd,
s2 = de.s,
de2 = de.start, // start of the deco
s = de2.s,
x = s.x + 3 // x left
de.st = s2.st;
de.lden = false; /* old behaviour */
de.has_val = true;
if (dd.ty == '^')
up = 1
else if (dd.ty != '_')
up = up6(s2, s2.pos.dyn)
if (up)
de.up = true
// shift the starting point if any dynamic mark on this symbol
i = de2.ix
while (--i >= 0) {
de3 = a_de[i]
if (!de3 || de3.s != s)
break
}
while (1) {
i++
de3 = a_de[i]
if (!de3 || de3.s != s)
break
if (de3 == de || de3 == de2)
continue
if (!(de.up ^ de3.up)
&& f_staff[de3.dd.func]) { // if dynamic mark
// x2 = de3.x + de3.val + 4
x2 = de3.x + de3.dd.wr + 2
if (x2 > x)
x = x2
break
}
}
if (de.defl.noen) { /* if no decoration end */
dx = de.x - x
if (dx < 20) {
x = de.x - 20 - 3;
dx = 20
}
} else {
// shift the ending point if any dynamic mark
x2 = s2.x
i = de.ix
while (--i > 0) {
de3 = a_de[i]
if (!de3 || de3.s != s2)
break
}
while (1) {
i++
de3 = a_de[i]
if (!de3 || de3.s != s2)
break
if (de3 == de || de3 == de2)
continue
if (!(de.up ^ de3.up)
&& f_staff[de3.dd.func]) { // if dynamic mark
x2 -= de3.dd.wl
break
}
}
dx = x2 - x - 4
if (dx < 20) {
x -= (20 - dx) * .5;
dx = 20
}
}
de.val = dx;
de.x = x;
de.y = y_get(de.st, up, x, dx)
if (!up)
de.y -= dd.h
else
de.y += dd.hd
/* (y_set is done later in draw_deco_staff) */
}
/* 0: near the note (dot, tenuto) */
function d_near(de) {
var y, up,
s = de.s,
dd = de.dd
if (dd.str) { // annotation like decoration
// de.x = s.x;
// de.y = s.y;
return
}
if (dd.ty == '^')
up = 1
else if (dd.ty == '_')
up = 0
else if (s.multi)
up = s.multi > 0
else
up = s.stem < 0
y = up ? s.ymx : s.ymn
if (y > -6 && y < 30) {
y = (((y + 9) / 6) | 0) * 6 - 6 // between lines
}
if (up) {
y += dd.hd
s.ymx = y + dd.h
} else if (dd.name[0] == 'w') { // wedge (no descent)
de.inv = true
y -= dd.h
s.ymn = y
} else {
y -= dd.h
s.ymn = y - dd.hd
}
de.y = y
if (s.type == C.NOTE)
de.x += s.notes[s.stem >= 0 ? 0 : s.nhd].shhd
if (dd.name[0] == 'd' /* if dot decoration */
&& s.nflags >= -1) { /* on stem */
if (up) {
if (s.stem > 0)
|
| ︙ | ︙ | |||
420 421 422 423 424 425 426 427 428 429 430 431 432 |
s = de.s,
dd = de.dd,
de_prev;
// don't treat here the long decorations
if (de.ldst) // if long deco start
return
if (de.start) { // if long decoration
d_cresc(de)
return
}
de.val = dd.wl + dd.wr;
| > > > > > > | | > > | 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 |
s = de.s,
dd = de.dd,
de_prev;
// don't treat here the long decorations
if (de.ldst) // if long deco start
return
if ((de.pos & C.SL_ALI_MSK) == C.SL_CLOSE
|| ((de.pos & C.SL_ALI_MSK) == 0
&& s.fmt.dynalign < 0)) { // if no dynalign
d_upstaff(de) // then, do as above/below the staff
return
}
if (de.start) { // if long decoration
d_cresc(de)
return
}
de.val = dd.wl + dd.wr;
up = up6(s, de.pos)
if (up)
de.up = true;
x = s.x
if (de.ix > 0) {
de_prev = a_de[de.ix - 1]
if (de_prev.s == s
&& ((de.up && !de_prev.up)
|| (!de.up && de_prev.up))) {
dd2 = de_prev.dd
if (f_staff[dd2.func]) { /* if dynamic mark */
x2 = de_prev.x + de_prev.val + 4;
if (x2 > x)
x = x2
}
}
}
de.x = x;
de.y = y_get(s.st, up, x, de.val)
if (!up)
de.y -= dd.h
else
de.y += dd.hd
/* (y_set is done later in draw_deco_staff) */
}
/* 1: special case for slide */
function d_slide(de) {
var m, dx,
s = de.s,
|
| ︙ | ︙ | |||
501 502 503 504 505 506 507 | x = de2.s.x + de.dd.wl + 2 de2.val -= de2.dd.wr if (de2.val < 8) de2.val = 8 } de.st = st | < | | < | | > > | > > > | > > | > > > > | < | 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 |
x = de2.s.x + de.dd.wl + 2
de2.val -= de2.dd.wr
if (de2.val < 8)
de2.val = 8
}
de.st = st
switch (dd.func) {
case 5:
up = 1
break
case 4:
case 7:
break
case 3: // tied to note
case 6: // dynamic mark
if (dd.func == 6)
up = up6(s, de.pos)
else
up = up3(s, de.pos)
break
}
if (dd.ty == '^')
up = 1
else if (dd.ty == '_')
up = 0
if (de.defl.noen) { /* if no decoration end */
w = de.x - x
if (w < 20) {
x = de.x - 20 - 3;
w = 20
}
} else {
w = s2.x - x - 6
if (s2.type == C.NOTE)
w -= 6
if (w < 10) {
x -= 10 - w
w = 10
}
}
y = y_get(st, up, x - dd.wl - 5, w)
if (up) {
tmp = staff_tb[s.st].topbar + 2
if (y < tmp)
y = tmp
} else {
tmp = staff_tb[s.st].botbar - 2
|
| ︙ | ︙ | |||
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | } de.lden = false; de.has_val = true; de.val = w; de.x = x; de.y = y if (up) y += dd.h; y_set(st, up, x, w, y) if (up) s.ymx = s2.ymx = y else s.ymn = s2.ymn = y } | > | > | | | < | | | < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < > > > | > > > | | | | | | < > | < | < | > | < | > > | > | | | < < | < < | | < < > | > > > > > > > > > | > > > > > > > | > | < < | < | < < < | < < > | < > > | > > > > > | > > | | > > > > | 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 |
}
de.lden = false;
de.has_val = true;
de.val = w;
de.x = x;
de.y = y
de.up = up
if (up)
y += dd.h;
y_set(st, up, x, w, y)
if (up)
s.ymx = s2.ymx = y
else
s.ymn = s2.ymn = y
}
/* 3, 4, 5, 7: above (or below) the staff */
function d_upstaff(de) {
// don't treat here the long decorations
if (de.ldst) // if long deco start
return
if (de.start) { // if long decoration
d_trill(de)
return
}
var y, up, inv,
s = de.s,
dd = de.dd,
x = de.x,
w = dd.wl + dd.wr,
stafft = staff_tb[s.st].topbar + 2 + dd.hd,
staffb = staff_tb[s.st].botbar - 2 - dd.h
// glyphs inside the staff
switch (dd.glyph) {
case "brth":
case "caes":
case "lphr":
case "mphr":
case "sphr":
case "short":
case "tick":
y = stafft
if (s.type == C.BAR) {
s.invis = 1
} else {
if (dd.glyph == "brth" && y < s.ymx)
y = s.ymx
for (s = s.ts_next; s; s = s.ts_next)
if (s.seqst)
break
x += ((s ? s.x : realwidth) - x) * .45
}
de.x = x
de.y = y
return
}
if (s.nhd)
x += s.notes[s.stem >= 0 ? 0 : s.nhd].shhd;
de.up = up = (dd.func == 4 || dd.func == 7) ? 0
: dd.func == 6 ? up6(s, de.pos)
: up3(s, de.pos)
switch (dd.ty) {
case '@':
case '<':
case '>':
y = de.y
break
}
if (y == undefined) {
if (up) {
y = y_get(s.st, true, x - dd.wl, w)
+ dd.hd
if (y < stafft)
y = stafft
if (de.y > y)
y = de.y
s.ymx = y + dd.h
} else {
y = y_get(s.st, false, x - dd.wl, w)
- dd.h
if (y > staffb)
y = staffb
if (de.y < y)
y = de.y
if (dd.name == "fermata"
|| dd.glyph == "accent"
|| dd.glyph == "roll")
de.inv = 1
s.ymn = y - dd.hd
}
}
if (dd.func != 6) { // if not d_pf
if (y >= stafft)
y_set(s.st, 1, x - dd.wl, w, y + dd.h)
else if (y <= staffb)
y_set(s.st, 0, x - dd.wl, w, y - dd.hd)
}
de.x = x;
de.y = y
}
// add a decoration
/* syntax:
* %%deco <name> <c_func> <glyph> <h> <wl> <wr> [<str>]
* "<h>" may be followed by ",<hd>" (descent)
*/
function deco_add(param) {
var dv = param.match(/(\S*)\s+(.*)/);
decos[dv[1]] = dv[2]
}
// define a decoration
// nm is the name of the decoration
// nmd is the name of the definition in the table 'decos'
function deco_def(nm, nmd) {
if (!nmd)
nmd = nm
var a, dd, dd2, nm2, c, i, elts, str, hd,
text = decos[nmd]
// check if a long decoration with number
if (!text && /\d[()]$/.test(nmd))
text = decos[nmd.replace(/\d/, '')]
if (!text) {
if (cfmt.decoerr)
error(1, null, "Unknown decoration '$1'", nm)
return //undefined
}
|
| ︙ | ︙ | |||
719 720 721 722 723 724 725 |
wr = parseFloat(a[5])
if (isNaN(c_func)) {
error(1, null, "%%deco: bad C function value '$1'", a[1])
return //undefined
}
if (c_func > 10
| | | | | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 |
wr = parseFloat(a[5])
if (isNaN(c_func)) {
error(1, null, "%%deco: bad C function value '$1'", a[1])
return //undefined
}
if (c_func > 10
&& (c_func < 32 || c_func > 44)) {
error(1, null, "%%deco: bad C function index '$1'", c_func)
return //undefined
}
// if (c_func == 5) // old !trill(!
// c_func = 3
// if (c_func == 7) // old !cresc(!
// c_func = 6
if (h.indexOf(',') > 0) {
h = h.split(',')
hd = h[1]
h = h[0]
} else {
hd = 0
|
| ︙ | ︙ | |||
750 751 752 753 754 755 756 |
dd = {
name: nm
}
dd_tb[nm] = dd
}
/* set the values */
| | > > > > > | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | > > > > > > | | | < | | < | > | | | < | < > | < | < | | | | < > | | | < < | | | | | | | | | | | | | | | | | | | | | | | | | < | > > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 |
dd = {
name: nm
}
dd_tb[nm] = dd
}
/* set the values */
dd.func = nm.indexOf("head-") == 0 ? 9 : c_func;
dd.glyph = a[2];
dd.h = Number(h)
dd.hd = Number(hd)
dd.wl = wl;
dd.wr = wr;
str = text.replace(a[0], '').trim()
if (str) { // optional string
if (str[0] == '"')
str = str.slice(1, -1);
if (str[0] == '@'
&& !str.match(/^@([0-9.-]+),([0-9.-]+);?/)) {
error(1, null, "%%deco: bad position '$1'", str)
return
}
dd.str = str
}
/* compatibility */
if (dd.func == 6 && dd.str == undefined)
dd.str = nm
// link the start and end of long decorations
c = nm.slice(-1)
if (c == '(' ||
(c == ')' && nm.indexOf('(') < 0)) { // not (#)
dd.str = null; // (no string)
nm2 = nm.slice(0, -1) + (c == '(' ? ')' : '(');
dd2 = dd_tb[nm2]
if (dd2) {
if (c == '(') {
dd.dd_en = dd2;
dd2.dd_st = dd
} else {
dd.dd_st = dd2;
dd2.dd_en = dd
}
}
}
return dd
}
// define a cross-voice tie
// @nm = decoration name
// @s = note symbol
// @nt1 = note
function do_ctie(nm, s, nt1) {
var nt2 = cross[nm],
nm2 = nm.slice(0, -1) + (nm.slice(-1) == '(' ? ')' : '(')
if (nt2) {
error(1, s, "Conflict on !$1!", nm)
return
}
nt1.s = s
nt2 = cross[nm2]
if (!nt2) {
cross[nm] = nt1 // keep the start/end
return
}
if (nm.slice(-1) == ')') {
nt2 = nt1
nt1 = cross[nm2]
}
cross[nm2] = null
if (nt1.midi != nt2.midi
|| nt1.s.time + nt1.s.dur != nt2.s.time) {
error(1, s, "Bad tie")
} else {
nt1.tie_ty = C.SL_AUTO
nt1.tie_e = nt2
nt2.tie_s = nt1
nt1.s.ti1 = nt2.s.ti2 = true
}
} // do_ctie()
// get/create the definition of a decoration
function get_dd(nm) {
var ty, p,
dd = dd_tb[nm]
if (dd)
return dd
if ("<>^_@".indexOf(nm[0]) >= 0 // if position
&& !/^([>^]|[<>]\d?[()])$/.test(nm)) {
ty = nm[0]
if (ty == '@') {
p = nm.match(/@([-\d]+),([-\d]+)/)
if (!p) {
error(1, s, "Bad position in !$1!", nm)
return
}
ty = p[0]
}
dd = deco_def(nm, nm.replace(ty, ''))
} else {
dd = deco_def(nm)
}
if (!dd)
return
if (ty) {
if (ty[0] == '@') { // if with x,y
dd.x = Number(p[1])
dd.y = Number(p[2])
ty = '@'
}
dd.ty = ty
}
return dd
} // get_dd()
/* -- convert the decorations -- */
function deco_cnv(s, prev) {
var j, dd, nm, note, s1, court
while (1) {
nm = a_dcn.shift()
if (!nm)
break
dd = get_dd(nm)
if (!dd)
continue
/* special decorations */
switch (dd.func) {
case 0: // near
if (s.type == C.BAR && nm == "dot") {
s.bar_dotted = true
continue
}
// fall thru
case 1: // slide
case 2: // arp
// if (s.type != C.NOTE && s.type != C.REST) {
if (!s.notes) {
error(1, s, errs.must_note_rest, nm)
continue
}
break
case 8: // gliss
if (s.type != C.NOTE) {
error(1, s, errs.must_note, nm)
continue
}
note = s.notes[s.nhd] // move to the upper note of the chord
if (!note.a_dd)
note.a_dd = []
note.a_dd.push(dd)
continue
case 9: // alternate head
if (!s.notes) {
error(1, s, errs.must_note_rest, nm)
continue
}
// move the alternate head of the chord to the notes
for (j = 0; j <= s.nhd; j++) {
note = s.notes[j]
note.invis = true
if (!note.a_dd)
note.a_dd = []
note.a_dd.push(dd)
}
continue
case 10: /* color */
if (s.notes) {
for (j = 0; j <= s.nhd; j++)
s.notes[j].color = nm
} else {
s.color = nm
}
break
case 32: /* invisible */
s.invis = true
break
case 33: /* beamon */
if (s.type != C.BAR) {
error(1, s, "!beamon! must be on a bar")
continue
}
s.beam_on = true
break
case 34: /* trem1..trem4 */
if (s.type != C.NOTE
|| !prev
|| prev.type != C.NOTE
|| s.dur != prev.dur) {
error(1, s,
"!$1! must be on the last of a couple of notes",
nm)
continue
}
s.trem2 = true;
s.beam_end = true;
s.beam_st = false;
prev.beam_st = true;
prev.beam_end = false;
s.ntrem = prev.ntrem = Number(nm[4]);
for (j = 0; j <= s.nhd; j++)
s.notes[j].dur *= 2;
for (j = 0; j <= prev.nhd; j++)
prev.notes[j].dur *= 2
break
case 35: /* xstem */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, nm)
continue
}
s.xstem = true;
break
case 36: /* beambr1 / beambr2 */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, nm)
continue
}
if (nm[6] == '1')
s.beam_br1 = true
else
s.beam_br2 = true
break
case 37: /* rbstop */
s.rbstop = 1 // open
break
case 38: /* /, // and /// = tremolo */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, nm)
continue
}
s.trem1 = true;
s.ntrem = nm.length /* 1, 2 or 3 */
break
case 39: /* beam-accel/beam-rall */
if (s.type != C.NOTE) {
error(1, s, errs.must_note, nm)
continue
}
s.feathered_beam = nm[5] == 'a' ? 1 : -1;
break
case 40: /* stemless */
s.stemless = true
break
case 41: /* rbend */
s.rbstop = 2 // with end
break
case 42: // editorial
if (!s.notes[0].acc)
continue
nm = "sacc" + s.notes[0].acc.toString() // small accidental
dd = dd_tb[nm]
if (!dd) {
dd = deco_def(nm)
if (!dd) {
error(1, s, errs.bad_val, "!editorial!")
continue
}
}
delete s.notes[0].acc
curvoice.acc[s.notes[0].pit + 19] = 0 // ignore the accidental
break
case 43: // courtesy
j = curvoice.acc[s.notes[0].pit + 19]
if (s.notes[0].acc || !j)
continue
court = 1 // defer
break
case 44: // cross-voice ties
do_ctie(nm, s, s.notes[0]) // (only one note for now)
continue
// default:
// break
}
// add the decoration in the symbol
if (!s.a_dd)
s.a_dd = []
s.a_dd.push(dd)
}
// handle the possible courtesy accidental
if (court) {
a_dcn.push("cacc" + j)
dh_cnv(s, s.notes[0])
}
}
// -- convert head decorations --
// The decorations are in the global array a_dcn
function dh_cnv(s, nt) {
var k, nm, dd
while (1) {
nm = a_dcn.shift()
if (!nm)
break
dd = get_dd(nm)
if (!dd)
continue
switch (dd.func) {
case 0:
case 1:
case 3:
case 4:
case 8: // gliss
break
default:
// case 2: // arpeggio
// case 5: // trill
// case 7: // d_cresc
error(1, s, "Cannot have !$1! on a head", nm)
continue
case 9: // head replacement
case 32: // invisible
nt.invis = true
break
case 10: // color
nt.color = nm
continue
case 40: // stemless chord (abcm2ps behaviour)
s.stemless = true
continue
case 44: // cross-voice ties
do_ctie(nm, s, nt)
continue
}
// add the decoration in the note
if (!nt.a_dd)
nt.a_dd = []
nt.a_dd.push(dd)
}
} // dh_cnv()
/* -- update the x position of a decoration -- */
// used to center the rests
function deco_update(s, dx) {
var i, de,
nd = a_de.length
for (i = 0; i < nd; i++) {
de = a_de[i]
if (de.s == s)
de.x += dx
}
}
/* -- adjust the symbol width -- */
function deco_width(s) {
var dd, i, w,
wl = 0,
a_dd = s.a_dd,
nd = a_dd.length
for (i = 0; i < nd; i++) {
dd = a_dd[i]
switch (dd.func) {
|
| ︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 | case "lphr": case "mphr": case "sphr": if (s.wr < 20) s.wr = 20 break } break } } | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > | < < | 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 |
case "lphr":
case "mphr":
case "sphr":
if (s.wr < 20)
s.wr = 20
break
}
// fall thru
default:
switch (dd.ty) {
case '<':
w = dd.wl + dd.wr + 6
if (wl < w)
wl = w
break
case '>':
w = dd.wl + dd.wr + 8
if (s.wr < w)
s.wr = w
break
}
break
}
}
if (wl && s.prev && s.prev.type == C.BAR)
wl -= 3
return wl
}
// compute the width of decorations in chord
function deco_wch(nt) {
var i, w, dd,
wl = 0,
n = nt.a_dd.length
for (i = 0; i < n; i++) {
dd = nt.a_dd[i]
if (dd.ty == '<') {
w = dd.wl + dd.wr + 8
if (w > wl)
wl = w
}
}
return wl
} // deco_wch()
/* -- draw the decorations -- */
/* (the staves are defined) */
Abc.prototype.draw_all_deco = function() {
if (!a_de.length)
return
var de, dd, s, note, f, st, x, y, y2, ym, uf, i, str, a,
new_de = [],
ymid = []
st = nstaff;
y = staff_tb[st].y
while (--st >= 0) {
y2 = staff_tb[st].y;
ymid[st] = (y + 24 + y2) * .5;
y = y2
}
while (1) {
de = a_de.shift()
if (!de)
break
dd = de.dd
if (!dd)
|
| ︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 |
if (de.m != undefined) {
note = s.notes[de.m];
if (note.shhd)
x += note.shhd * stv_g.scale;
/* center the dynamic marks between two staves */
/*fixme: KO when deco on other voice and same direction*/
| > > > | | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 |
if (de.m != undefined) {
note = s.notes[de.m];
if (note.shhd)
x += note.shhd * stv_g.scale;
/* center the dynamic marks between two staves */
/*fixme: KO when deco on other voice and same direction*/
} else if (dd.func == 6
&& ((de.pos & C.SL_ALI_MSK) == C.SL_CENTER
|| ((de.pos & C.SL_ALI_MSK) == 0
&& !s.fmt.dynalign))
&& ((de.up && st > 0)
|| (!de.up && st < nstaff))) {
if (de.up)
ym = ymid[--st]
else
ym = ymid[st++];
ym -= dd.h * .5
|
| ︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 |
//fixme: y_set is not used later!
if ((de.up && y2 > ym)
|| (!de.up && y2 < ym)) {
y = ym;
// y_set(st, de.up, de.x, de.val,
// (de.up ? y + dd.h : y)
// - staff_tb[st].y)
}
}
}
// check if user JS decoration
uf = user[f]
if (uf && typeof(uf) == "function") {
| > > | 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 |
//fixme: y_set is not used later!
if ((de.up && y2 > ym)
|| (!de.up && y2 < ym)) {
y = ym;
// y_set(st, de.up, de.x, de.val,
// (de.up ? y + dd.h : y)
// - staff_tb[st].y)
if (stv_g.scale != 1)
y += stv_g.dy / 2
}
}
}
// check if user JS decoration
uf = user[f]
if (uf && typeof(uf) == "function") {
|
| ︙ | ︙ | |||
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 |
anno_start(s, 'deco')
// if (de.flags.grace) {
// g_open(x, y, 0, .7, de.inv ? -.7 : 0);
// x = y = 0
// } else
if (de.inv) {
g_open(x, y, 0, 1, -1);
x = y = 0
}
if (de.has_val) {
if (dd.func != 2 // if not !arpeggio!
|| stv_g.st < 0) // or not staff scale
// || voice_tb[s.v].scale != 1)
out_deco_val(x, y, f, de.val / stv_g.scale, de.defl)
else
out_deco_val(x, y, f, de.val, de.defl)
| > | | 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 |
anno_start(s, 'deco')
// if (de.flags.grace) {
// g_open(x, y, 0, .7, de.inv ? -.7 : 0);
// x = y = 0
// } else
if (de.inv) {
y = y + dd.h - dd.hd
g_open(x, y, 0, 1, -1);
x = y = 0
}
if (de.has_val) {
if (dd.func != 2 // if not !arpeggio!
|| stv_g.st < 0) // or not staff scale
// || voice_tb[s.v].scale != 1)
out_deco_val(x, y, f, de.val / stv_g.scale, de.defl)
else
out_deco_val(x, y, f, de.val, de.defl)
if (de.cont)
new_de.push(de.start) // to be continued next line
} else if (dd.str != undefined) {
str = dd.str
if (str[0] == '@') {
a = str.match(/^@([0-9.-]+),([0-9.-]+);?/);
x += Number(a[1]);
y += Number(a[2]);
|
| ︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 |
de.s.x = de.x = x;
de.defl.nost = true
}
}
/* -- create the deco elements, and treat the near ones -- */
function create_deco(s) {
| | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > > | | < | | | | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > > > > > > > > > > > > > > > > | | 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 |
de.s.x = de.x = x;
de.defl.nost = true
}
}
/* -- create the deco elements, and treat the near ones -- */
function create_deco(s) {
var dd, k, pos, de, x, y, v,
nd = s.a_dd.length
if (s.y == undefined)
s.y = 0 // (no y in measure bars)
/*fixme:pb with decorations above the staff*/
for (k = 0; k < nd; k++) {
dd = s.a_dd[k]
// adjust the position
x = s.x
y = s.y
switch (dd.func) {
default:
if (dd.func >= 10)
continue
pos = 0
break
case 3: /* d_upstaff */
case 4:
case 5: // after slurs
case 7:
pos = s.pos.orn
break
case 6: /* d_pf */
pos = s.pos.vol
break
case 7: /* d_cresc */
pos = s.pos.dyn
break
}
switch (dd.ty) { // explicit position
case '^':
pos = (pos & ~0x07) | C.SL_ABOVE
break
case '_':
pos = (pos & ~0x07) | C.SL_BELOW
break
case '<':
case '>':
pos = (pos & 0x07) | C.SL_CLOSE
if (dd.ty == '<') {
x -= dd.wr + 8
if (s.notes[0].acc)
x -= 5.5
} else {
x += dd.wl + 8
}
y = 3 * (s.notes[0].pit - 18)
- (dd.h - dd.hd) / 2
break
case '@':
x += dd.x
y += dd.y
break
}
if ((pos & 0x07) == C.SL_HIDDEN)
continue
de = {
s: s,
dd: dd,
st: s.st,
ix: a_de.length,
defl: {},
x: x,
y: y,
pos: pos
// dy: 0
}
if (dd.name.indexOf("invert") == 0)
de.inv = 1
if (s.type == C.BAR && !dd.ty)
de.x -= s.wl / 2 - 2
a_de.push(de)
if (dd.dd_en) {
de.ldst = true
} else if (dd.dd_st) {
//fixme: pb with "()"
de.lden = true;
de.defl.nost = true
}
if (f_near[dd.func])
f_near[dd.func](de)
}
} // create_deco()
// create the decorations of note heads
function create_dh(s, m) {
var de, k, dd,
note = s.notes[m],
nd = note.a_dd.length,
x = s.x
for (k = 0; k < nd; k++) {
dd = note.a_dd[k]
//fixme: check if hidden?
de = {
s: s,
dd: dd,
st: s.st,
m: m,
ix: 0,
defl: {},
x: x,
y: 3 * (note.pit - 18)
// dy: 0
}
if (dd.ty) { // if explicit position
if (dd.ty == '@') {
de.x += dd.x
de.y += dd.y
} else {
de.y -= (dd.h - dd.hd) / 2 // center
if (dd.ty == '<')
de.x -= dd.wr + 8
else if (dd.ty == '>')
de.x += dd.wr + 8
}
}
a_de.push(de)
if (dd.dd_en) {
de.ldst = true
} else if (dd.dd_st) {
de.lden = true;
de.defl.nost = true
}
}
} // create_dh()
// create all decorations of a note (chord and heads)
function create_all(s) {
if (s.invis && s.play) // play sequence: no decoration
return
if (s.a_dd)
create_deco(s)
if (s.notes) {
for (var m = 0; m < s.notes.length; m++) {
if (s.notes[m].a_dd)
create_dh(s, m)
}
}
} // create_all()
// link the long decorations
function ll_deco() {
|
| ︙ | ︙ | |||
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 |
de2 = {
s: s,
st: de.st,
dd: dd2,
ix: a_de.length - 1,
x: realwidth - 6,
y: s.y,
lden: true,
defl: {
noen: true
}
}
if (de2.x < s.x + 10)
de2.x = s.x + 10
if (de.m != undefined)
de2.m = de.m;
a_de.push(de2)
}
de2.start = de;
de2.defl.nost = de.defl.nost
| > | > > | | | | 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 1617 1618 1619 |
de2 = {
s: s,
st: de.st,
dd: dd2,
ix: a_de.length - 1,
x: realwidth - 6,
y: s.y,
cont: true, // keep for next line
lden: true,
defl: {
noen: true
}
}
if (de2.x < s.x + 10)
de2.x = s.x + 10
if (de.m != undefined)
de2.m = de.m;
a_de.push(de2)
}
de2.start = de;
de2.defl.nost = de.defl.nost
// handle same numbered decoration at a same time
j = dd.name.slice(-1)
if (j >= '0' && j <= '9'
&& i > 0
&& a_de[i - 1].s.time == de.s.time
&& a_de[i - 1].dd.name.slice(0, -2) ==
dd.name.slice(0, -2))
de2.prev = a_de[i - 1]
}
// add starting decorations
for (i = 0; i < n_de; i++) {
de2 = a_de[i]
if (!de2.lden // not the end of long decoration
|
| ︙ | ︙ | |||
1440 1441 1442 1443 1444 1445 1446 |
for (i = 0; i < nd; i++) {
de = a_de[i];
dd = de.dd;
f = dd.func
if (f_note[f]
&& de.m == undefined)
| | | | 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 |
for (i = 0; i < nd; i++) {
de = a_de[i];
dd = de.dd;
f = dd.func
if (f_note[f]
&& de.m == undefined)
f_note[f](de)
}
}
// -- define the music elements tied to the staff --
// - decoration tied to the staves
// - chord symbols
// - repeat brackets
/* (the staves are not yet defined) */
/* (unscaled delayed output) */
function draw_deco_staff() {
var s, p_voice, y, i, v, de, dd,
minmax = new Array(nstaff + 1),
nd = a_de.length
/* draw the repeat brackets */
function draw_repbra(p_voice) {
var s, s1, x, y, y2, i, p, w, wh, first_repeat;
// search the max y offset of the line
y = staff_tb[p_voice.st].topbar + 25 // 20 (vert bar) + 5 (room)
for (s = p_voice.sym; s; s = s.next) {
if (s.type != C.BAR)
continue
if (!s.rbstart || s.norepbra)
continue
/*fixme: line cut on repeat!*/
|
| ︙ | ︙ | |||
1481 1482 1483 1484 1485 1486 1487 |
for (;;) {
if (!s.next)
break
s = s.next
if (s.rbstop)
break
}
| | | > > > > > > > > > > | 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 |
for (;;) {
if (!s.next)
break
s = s.next
if (s.rbstop)
break
}
y2 = y_get(p_voice.st, true, s1.x, s.x - s1.x) + 2
if (y < y2)
y = y2
// have room for the vertical lines and the repeat numbers
if (s1.rbstart == 2) {
y2 = y_get(p_voice.st, true, s1.x, 3) + 20
if (y < y2)
y = y2
}
if (s.rbstop == 2) {
y2 = y_get(p_voice.st, true, s.x - 3, 3) + 20
if (y < y2)
y = y2
}
if (s1.text) {
wh = strwh(s1.text);
y2 = y_get(p_voice.st, true, s1.x + 4, wh[0]) +
wh[1]
if (y < y2)
y = y2
}
|
| ︙ | ︙ | |||
1546 1547 1548 1549 1550 1551 1552 |
w = s.rbstop ? 0 : 8
}
w = (s.x - x - w) // / staff_tb[p_voice.st].staffscale;
if (!s.next // 2nd ending at end of line
&& !s.rbstop
&& !p_voice.bar_start) { // continue on next line
| | < < < | 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 |
w = s.rbstop ? 0 : 8
}
w = (s.x - x - w) // / staff_tb[p_voice.st].staffscale;
if (!s.next // 2nd ending at end of line
&& !s.rbstop
&& !p_voice.bar_start) { // continue on next line
p_voice.bar_start = _bar(s)
p_voice.bar_start.bar_type = ""
p_voice.bar_start.rbstart = 1
}
if (s1.text)
xy_str(x + 4, y2 - gene.curfont.size - 3,
s1.text);
xypath(x, y2);
if (s1.rbstart == 2)
output += 'm0 20v-20';
|
| ︙ | ︙ | |||
1584 1585 1586 1587 1588 1589 1590 | de = a_de[i]; dd = de.dd if (!dd) // if error continue if (!f_staff[dd.func] /* if not tied to the staff */ || de.m != undefined) // or head decoration continue | | > > | > > > | | 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 |
de = a_de[i];
dd = de.dd
if (!dd) // if error
continue
if (!f_staff[dd.func] /* if not tied to the staff */
|| de.m != undefined) // or head decoration
continue
f_staff[dd.func](de)
if (dd.dd_en) // if start
continue
if ((de.pos & C.SL_ALI_MSK) == C.SL_ALIGN
|| ((de.pos & C.SL_ALI_MSK) == 0
&& de.s.fmt.dynalign > 0)) { // if align
if (de.up) {
if (de.y > minmax[de.st].ymax)
minmax[de.st].ymax = de.y
} else {
if (de.y < minmax[de.st].ymin)
minmax[de.st].ymin = de.y
}
}
}
/* and, if wanted, set them at a same vertical offset */
for (i = 0; i < nd; i++) {
de = a_de[i];
dd = de.dd
if (!dd) // if error
continue
if (dd.dd_en // if start
|| !f_staff[dd.func])
continue
if (dd.func == 6
&&((de.pos & C.SL_ALI_MSK) == C.SL_ALIGN
|| ((de.pos & C.SL_ALI_MSK) == 0
&& de.s.fmt.dynalign > 0))) { // if align
if (de.up)
y = minmax[de.st].ymax
else
y = minmax[de.st].ymin;
de.y = y
} else {
y = de.y
|
| ︙ | ︙ | |||
1680 1681 1682 1683 1684 1685 1686 |
continue
}
break
}
// don't display the number twice
if (s.type != C.BAR || !s.bar_num) {
| < < | | 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 |
continue
}
break
}
// don't display the number twice
if (s.type != C.BAR || !s.bar_num) {
any_nb = true;
w = w0
if (bar_num >= 10)
w *= bar_num >= 100 ? 3 : 2
if (gene.curfont.pad)
w += gene.curfont.pad * 2
x = s.x - s.wl + 2 // if clef, shift a bit
y = y_get(st, true, x, w)
if (y < staff_tb[st].topbar + 6)
y = staff_tb[st].topbar + 6;
y += 2 + gene.curfont.pad
xy_str(x, y, bar_num.toString())
y += gene.curfont.size + gene.curfont.pad
y_set(st, true, x, w, y);
|
| ︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 | if (!any_nb) any_nb = true; w = w0 if (bar_num >= 10) w *= bar_num >= 100 ? 3 : 2 if (gene.curfont.pad) w += gene.curfont.pad * 2 | | | | | 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 |
if (!any_nb)
any_nb = true;
w = w0
if (bar_num >= 10)
w *= bar_num >= 100 ? 3 : 2
if (gene.curfont.pad)
w += gene.curfont.pad * 2
x = s.x
y = y_get(st, true, x, w)
if (y < staff_tb[st].topbar + 6)
y = staff_tb[st].topbar + 6
if (s.next.type == C.NOTE) {
if (s.next.stem > 0) {
if (y < s.next.ys - gene.curfont.size)
y = s.next.ys - gene.curfont.size
} else {
if (y < s.next.y)
y = s.next.y
|
| ︙ | ︙ | |||
1760 1761 1762 1763 1764 1765 1766 |
if (font_size)
param_set_font("measurefont", "* " + font_size.toString());
}
/* -- draw the parts and the tempo information -- */
/* (the staves are being defined) */
function draw_partempo(st, top) {
| | | 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 |
if (font_size)
param_set_font("measurefont", "* " + font_size.toString());
}
/* -- draw the parts and the tempo information -- */
/* (the staves are being defined) */
function draw_partempo(st, top) {
var s, s2, some_part, some_tempo, h, w, y,
dy = 0, /* put the tempo indication at top */
ht = 0
/* get the minimal y offset */
var ymin = staff_tb[st].topbar + 8,
dosh = 0,
shift = 1,
|
| ︙ | ︙ | |||
1821 1822 1823 1824 1825 1826 1827 |
}
}
/* then, put the parts */
/*fixme: should reduce vertical space if parts don't overlap tempo...*/
ymin = staff_tb[st].topbar + 6
for (s = tsfirst; s; s = s.ts_next) {
| > | > > | | > | | > | < > > | | | | | | | | < < | | 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 |
}
}
/* then, put the parts */
/*fixme: should reduce vertical space if parts don't overlap tempo...*/
ymin = staff_tb[st].topbar + 6
for (s = tsfirst; s; s = s.ts_next) {
s2 = s.part
if (!s2 || s2.invis)
continue
if (!some_part) {
some_part = s;
set_font("parts");
h = gene.curfont.size + 2 +
gene.curfont.pad * 2
}
if (s2.x == undefined)
s2.x = s.x - 10
w = strwh(s2.text)[0]
y = y_get(st, true, s2.x, w + 3)
if (ymin < y)
ymin = y
}
if (some_part) {
set_sscale(-1)
ht += h
if (top + dy < ymin + ht)
dy = ymin + ht - top
for (s = some_part; s; s = s.ts_next) {
s2 = s.part
if (!s2 || s2.invis)
continue
if (user.anno_start || user.anno_stop) {
s2.type = C.PART
s2.p_v = s.p_v
s2.v = s.v
s2.st = s2.wl = 0
s2.wr = strwh(s2.text)[0]
s2.ymn = -ht
s2.ymx = s2.ymn + h
anno_start(s2)
}
xy_str(s2.x, 2 - ht, s2.text)
anno_stop(s2)
}
}
return dy /= staff_tb[0].staffscale
}
|
Changes to core/draw.js.
1 2 | // abc2svg - draw.js - draw functions // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - draw.js - draw functions // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
77 78 79 80 81 82 83 |
delete s.a_gch
delete s.a_ly
delete s.a_dd;
delete s.tp
s.notes = clone(s.notes)
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m] = clone(s.notes[m])
| | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
delete s.a_gch
delete s.a_ly
delete s.a_dd;
delete s.tp
s.notes = clone(s.notes)
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m] = clone(s.notes[m])
delete note.a_dd
}
return s
}
/* -- calculate a beam -- */
/* (the staves may be defined or not) */
var min_tb = [
|
| ︙ | ︙ | |||
210 211 212 213 214 215 216 | } s.xs = s.x + x * scale; if (s == s2) break } // have flat beams on grace notes when asked | | | | | > > > | 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 |
}
s.xs = s.x + x * scale;
if (s == s2)
break
}
// have flat beams on grace notes when asked
if (s.grace && s1.fmt.flatbeams)
a = 0
// if a note inside the beam is the closest to the beam, the beam is flat
else if (!two_dir
&& notes >= 3
&& s_closest != s1 && s_closest != s2)
a = 0
y = s1.ys + staff_tb[st].y
if (a == undefined)
a = (s2.ys + staff_tb[s2.st].y - y) / (s2.xs - s1.xs)
if (a != 0) {
a = s1.fmt.beamslope * a /
(s1.fmt.beamslope + Math.abs(a)) // max steepness for beam
if (a > -.04 && a < .04)
a = 0 // slope too low
}
// pivot around the middle of the beam
b = (y + s2.ys + staff_tb[s2.st].y) / 2 - a * (s2.xs + s1.xs) / 2
/*fixme: have a look again*/
/* have room for the symbols in the staff */
max_stem_err = 0; /* check stem lengths */
|
| ︙ | ︙ | |||
622 623 624 625 626 627 628 |
else if (s2.tmp)
unlksym(s2)
anno_stop(s1, 'beam')
}
/* -- draw the left side of the staves -- */
function draw_lstaff(x) {
| < < | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
else if (s2.tmp)
unlksym(s2)
anno_stop(s1, 'beam')
}
/* -- draw the left side of the staves -- */
function draw_lstaff(x) {
var i, j, yb, h, fl,
nst = cur_sy.nstaff,
l = 0
/* -- draw a system brace or bracket -- */
function draw_sysbra(x, st, flag) {
var i, st_end, yt, yb
|
| ︙ | ︙ | |||
724 725 726 727 728 729 730 |
}
}
var acc_nd = {} // cache of the microtonal accidentals
/* -- draw an accidental -- */
function draw_acc(x, y, a) {
| | | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 |
}
}
var acc_nd = {} // cache of the microtonal accidentals
/* -- draw an accidental -- */
function draw_acc(x, y, a) {
if (typeof a == "object") { // if microtone
var c,
n = a[0],
d = a[1]
c = n + '_' + d
a = acc_nd[c]
if (!a) {
|
| ︙ | ︙ | |||
782 783 784 785 786 787 788 |
Abc.prototype.draw_hl = function(s) {
var i, j, n, note,
hla = [],
st = s.st,
p_staff = staff_tb[st]
// check if any helper line
| | > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 |
Abc.prototype.draw_hl = function(s) {
var i, j, n, note,
hla = [],
st = s.st,
p_staff = staff_tb[st]
// check if any helper line
if (!p_staff.hll
|| s.invis)
return // no helper line (no line)
for (i = 0; i <= s.nhd; i++) {
note = s.notes[i]
if (!p_staff.hlmap[note.pit - p_staff.hll])
hla.push([note.pit - 18,
note.shhd * stv_g.scale])
}
|
| ︙ | ︙ | |||
856 857 858 859 860 861 862 |
flat_cl = new Int8Array([12, 18, 24, 9, 15, 21, 6]),
sharp1 = new Int8Array([-9, 12, -9, -9, 12, -9]),
sharp2 = new Int8Array([12, -9, 12, -9, 12, -9]),
flat1 = new Int8Array([9, -12, 9, -12, 9, -12]),
flat2 = new Int8Array([-12, 9, -12, 9, -12, 9])
Abc.prototype.draw_keysig = function(x, s) {
| < < | | 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 |
flat_cl = new Int8Array([12, 18, 24, 9, 15, 21, 6]),
sharp1 = new Int8Array([-9, 12, -9, -9, 12, -9]),
sharp2 = new Int8Array([12, -9, 12, -9, 12, -9]),
flat1 = new Int8Array([9, -12, 9, -12, 9, -12]),
flat2 = new Int8Array([-12, 9, -12, 9, -12, 9])
Abc.prototype.draw_keysig = function(x, s) {
var old_sf = s.k_old_sf,
st = s.st,
staffb = staff_tb[st].y,
i, shift, p_seq,
clef_ix = s.k_y_clef
if (clef_ix & 1)
clef_ix += 7;
clef_ix /= 2
while (clef_ix < 0)
clef_ix += 7;
clef_ix %= 7
/* normal accidentals */
if (!s.k_a_acc) {
/* put neutrals if 'accidental cancel' */
if (s.fmt.cancelkey || s.k_sf == 0) {
/* when flats to sharps, or sharps to flats, */
if (s.k_sf == 0
|| old_sf * s.k_sf < 0) {
/* old sharps */
shift = sharp_cl[clef_ix];
|
| ︙ | ︙ | |||
912 913 914 915 916 917 918 |
shift = sharp_cl[clef_ix];
p_seq = shift > 9 ? sharp1 : sharp2
for (i = 0; i < s.k_sf; i++) {
xygl(x, staffb + shift, "acc1");
shift += p_seq[i];
x += 5.5
}
| | | | 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 |
shift = sharp_cl[clef_ix];
p_seq = shift > 9 ? sharp1 : sharp2
for (i = 0; i < s.k_sf; i++) {
xygl(x, staffb + shift, "acc1");
shift += p_seq[i];
x += 5.5
}
if (s.fmt.cancelkey && i < old_sf) {
x += 2
for (; i < old_sf; i++) {
xygl(x, staffb + shift, "acc3");
shift += p_seq[i];
x += 5.5
}
}
}
/* new flats */
if (s.k_sf < 0) {
shift = flat_cl[clef_ix];
p_seq = shift < 18 ? flat1 : flat2
for (i = 0; i > s.k_sf; i--) {
xygl(x, staffb + shift, "acc-1");
shift += p_seq[-i];
x += 5.5
}
if (s.fmt.cancelkey && i > old_sf) {
x += 2
for (; i > old_sf; i--) {
xygl(x, staffb + shift, "acc3");
shift += p_seq[-i];
x += 5.5
}
}
|
| ︙ | ︙ | |||
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 |
notes: [{}]
}
for (i = 0; i < s.k_a_acc.length; i++) {
acc = s.k_a_acc[i];
shift = (s.k_y_clef // clef shift
+ acc.pit - 18) * 3
if (i != 0
&& (shift > last_shift + 18
|| shift < last_shift - 18))
x -= 5.5 // no clash
else if (acc.acc != last_acc)
x += 3;
last_acc = acc.acc;
s2.x = x
s2.notes[0].pit = shift / 3 + 18;
| > > > > > > > | < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < < < < < < < < < < < < < < < < < | < < < < < < < < < < | | < < < < < | | | 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 |
notes: [{}]
}
for (i = 0; i < s.k_a_acc.length; i++) {
acc = s.k_a_acc[i];
shift = (s.k_y_clef // clef shift
+ acc.pit - 18) * 3
while (shift < -3) // let the accidentals inside the staff
shift += 21
while (shift > 27)
shift -= 21
if (i != 0
&& (shift > last_shift + 18
|| shift < last_shift - 18))
x -= 5.5 // no clash
else if (acc.acc != last_acc)
x += 3;
last_acc = acc.acc;
s2.x = x
s2.notes[0].pit = shift / 3 + 18;
// is this useful?
// s2.head = C.FULL
// s2.notes[0].shhd = 0
// self.draw_hl(s2)
last_shift = shift;
draw_acc(x, staffb + shift, acc.acc)
x += 5.5
}
}
}
// output the measure repeat number
function nrep_out(x, y, n) {
y -= 3
if (n < 10) {
xygl(x - 4, y, "mtr" + n)
} else {
xygl(x - 10, y, "mtr" + ((n / 10) | 0))
xygl(x - 2, y, "mtr" + (n % 10))
}
} // nrep_out()
// if rest alone in the measure or measure repeat,
// change the head and center
function center_rest(s) {
var s2, x
if (s.dur < C.BLEN * 2)
s.nflags = -2 // semibreve / whole
else if (s.dur < C.BLEN * 4)
s.nflags = -3
else
s.nflags = -4
s.dots = 0
/* don't use next/prev: there is no bar in voice overlay */
s2 = s.ts_next
while (s2.time != s.time + s.dur
&& s2.ts_next)
s2 = s2.ts_next
x = s2.x - s2.wl
s2 = s
while (!s2.seqst)
s2 = s2.ts_prev
s2 = s2.ts_prev
x = (x + s2.x + s2.wr) / 2
/* center the associated decorations */
if (s.a_dd)
deco_update(s, x - s.x)
s.x = x
} // center_rest()
/* -- draw a rest -- */
/* (the staves are defined) */
var rest_tb = [
"r128", "r64", "r32", "r16", "r8",
"r4",
"r2", "r1", "r0", "r00"]
function draw_rest(s) {
var s2, i, j, y, bx,
p_staff = staff_tb[s.st],
yb = p_staff.y, // bottom of staff
x = s.x
if (s.notes[0].shhd)
x += s.notes[0].shhd * stv_g.scale
if (s.rep_nb) {
set_sscale(s.st);
anno_start(s);
if (p_staff.stafflines == '|||||')
yb += 12
else
yb += (p_staff.topbar + p_staff.botbar) / 2
if (s.rep_nb < 0) {
xygl(x, yb, "srep")
} else {
xygl(x, yb, "mrep")
if (s.rep_nb > 2 && s.v == cur_sy.top_voice
&& s.fmt.measrepnb > 0
&& !(s.rep_nb % s.fmt.measrepnb))
nrep_out(x, yb + p_staff.topbar, s.rep_nb)
}
anno_a.push(s)
return
}
set_scale(s);
|
| ︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | && p_staff.stafflines.length <= 2) y -= 6 /* semibreve a bit lower */ // draw the rest if (!s.notes[0].invis) // if not head replacement xygl(x, y + yb, rest_tb[i]) | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | > | < < | < < > | | > > > > | < > > | < > > > | > | > > | > > > < < < < | < < < < < < < < < < | | < < | < < < < < < < < < < < | | > | 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 |
&& p_staff.stafflines.length <= 2)
y -= 6 /* semibreve a bit lower */
// draw the rest
if (!s.notes[0].invis) // if not head replacement
xygl(x, y + yb, rest_tb[i])
if (s.dots) {
x += 8;
y += yb + 3
j = s.dots
i = (s.dur_orig / 12) >> ((5 - s.nflags) - j)
while (j-- > 0) {
xygl(x, y, (i & (1 << j)) ? "dot" : "dot+")
x += 3.5
}
}
set_color();
anno_a.push(s)
}
// -- draw a multi-measure rest --
// (the staves are defined)
function draw_mrest(s) {
var x1, x2,
p_st = staff_tb[s.st],
y = p_st.y + (p_st.topbar + p_st.botbar) / 2,
p = s.nmes.toString()
if (!s.next) {
error(1, s, "Lack of bar after multi-measure rest")
return
}
set_scale(s)
x1 = s.prev.x + 20
x2 = s.next.x - 20
s.x = (x1 + x2) / 2
anno_start(s)
out_XYAB('<path d="mX Y', x1 + .6, y - 2.7)
output += 'v2.7h-1.4v-10.8h1.4v2.7h'
+ (x2 - x1 - 2.8).toFixed(1)
+ 'v-2.7h1.4v10.8h-1.4v-2.7z"/>\n'
out_XYAB('<text x ="X" y="Y" text-anchor="middle">A</text>\n',
s.x, y + 22, m_gl(p))
anno_a.push(s)
} // draw_mrest()
function grace_slur(s) {
var yy, x0, y0, x3, y3, bet1, bet2, dy1, dy2, last, below,
so = s,
g = s.extra
while (1) {
if (!g.next)
break /* (keep the last note) */
g = g.next
}
last = g
below = ((g.stem >= 0 || s.multi < 0) && g.notes[0].pit <= 28)
|| g.notes[0].pit < 16
if (below) {
yy = 127
for (g = s.extra; g; g = g.next) {
if (g.y < yy) {
yy = g.y;
last = g
}
}
|
| ︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 |
} else if (y3 < y0 - 4) {
y3 = y0 - 4;
x0 = last.x + 2;
y0 = last.y + 4
}
}
| > > > | | | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | > | 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 |
} else if (y3 < y0 - 4) {
y3 = y0 - 4;
x0 = last.x + 2;
y0 = last.y + 4
}
}
so.slur = {
x0: x0,
y0: y0,
x1: bet1 * x3 + (1 - bet1) * x0 - x0,
y1: y0 - bet1 * y3 - (1 - bet1) * y0 + dy1,
x2: bet2 * x3 + (1 - bet2) * x0 - x0,
y2: y0 - bet2 * y3 - (1 - bet2) * y0 + dy2,
x3: x3 - x0,
y3: y0 - y3
}
y0 -= so.slur.y1
g = so.extra
//fixme: useless?
// y_set(s.st, !below, x0, x3 - x0, y0)
if (below) {
if (y0 < g.ymn)
g.ymn = y0
} else {
if (y0 > g.ymx)
g.ymx = y0
}
} // grace_slur()
/* -- draw grace notes -- */
/* (the staves are defined) */
function draw_gracenotes(s) {
var x1, y1,
last, note,
bm = {},
g = s.extra
/* draw the notes */
// bm.s2 = undefined /* (draw flags) */
while (1) {
if (g.beam_st && !g.beam_end) {
if (self.calculate_beam(bm, g))
draw_beams(bm)
}
anno_start(g)
draw_note(g, !bm.s2)
if (g == bm.s2)
bm.s2 = null /* (draw flags again) */
anno_a.push(s)
// if (g.sls || g.sl2)
// slur = true
if (!g.next)
break /* (keep the last note) */
g = g.next
}
last = g
// if an acciaccatura, draw a bar
if (s.sappo) {
g = s.extra
if (!g.next) { /* if one note */
x1 = 9
y1 = g.stem > 0 ? 5 : -5
} else { /* many notes */
x1 = (g.next.x - g.x) * .5 + 4
y1 = (g.ys + g.next.ys) * .5 - g.y
if (g.stem > 0)
y1 -= 1
else
y1 += 1
}
note = g.notes[g.stem < 0 ? 0 : g.nhd]
out_acciac(x_head(g, note), y_head(g, note),
x1, y1, g.stem > 0)
}
/* slur */
g = s.slur
if (g) {
anno_start(s, 'slur')
xypath(g.x0, g.y0 + staff_tb[s.st].y)
output += 'c' + g.x1.toFixed(1) + ' ' + g.y1.toFixed(1) +
' ' + g.x2.toFixed(1) + ' ' + g.y2.toFixed(1) +
' ' + g.x3.toFixed(1) + ' ' + g.y3.toFixed(1) + '"/>\n'
anno_stop(s, 'slur')
}
}
/* -- set the y offset of the dots -- */
function setdoty(s, y_tb) {
var m, m1, y
/* set the normal offsets */
|
| ︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 |
function y_head(s, note) {
return staff_tb[s.st].y + 3 * (note.pit - 18)
}
/* -- draw m-th head with accidentals and dots -- */
/* (the staves are defined) */
// sets {x,y}_note
| | > | 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 |
function y_head(s, note) {
return staff_tb[s.st].y + 3 * (note.pit - 18)
}
/* -- draw m-th head with accidentals and dots -- */
/* (the staves are defined) */
// sets {x,y}_note
function draw_basic_note(s, m, y_tb) {
var i, p, yy, dotx, doty, inv,
old_color = false,
note = s.notes[m],
staffb = staff_tb[s.st].y, /* bottom of staff */
x = s.x,
y = 3 * (note.pit - 18), /* note height on staff */
shhd = note.shhd * stv_g.scale,
x_note = x + shhd,
y_note = y + staffb
// /* special case for voice unison */
// if (s.nohdi1 != undefined
|
| ︙ | ︙ | |||
1452 1453 1454 1455 1456 1457 1458 |
set_color(old_color)
}
/* -- draw a note or a chord -- */
/* (the staves are defined) */
function draw_note(s,
fl) { // draw flags
| | < | > > > > < < < < < < < | | 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 |
set_color(old_color)
}
/* -- draw a note or a chord -- */
/* (the staves are defined) */
function draw_note(s,
fl) { // draw flags
var s2, i, m, y, slen, c, nflags,
y_tb = new Array(s.nhd + 1),
note = s.notes[s.stem < 0 ? s.nhd : 0], // master note head
x = x_head(s, note),
y = y_head(s, note),
staffb = staff_tb[s.st].y
if (s.dots)
setdoty(s, y_tb)
/* draw the stem and flags */
if (!s.stemless) {
slen = s.ys - s.y;
nflags = s.nflags
if (s.ntrem)
nflags -= s.ntrem
if (!fl || nflags <= 0) { /* stem only */
if (s.nflags > 0) { /* (fix for PS low resolution) */
if (s.stem >= 0)
slen -= 1
else
slen += 1
}
out_stem(x, y, slen, s.grace)
} else { /* stem and flags */
out_stem(x, y, slen, s.grace,
nflags, s.fmt.straightflags)
}
} else if (s.xstem) { /* cross-staff stem */
s2 = s.ts_prev;
slen = (s2.stem > 0 ? s2.y : s2.ys) - s.y;
slen += staff_tb[s2.st].y - staffb;
out_stem(x, y, slen)
}
|
| ︙ | ︙ | |||
1513 1514 1515 1516 1517 1518 1519 | slen -= 5 + 5.4 } slen /= s.p_v.scale; out_trem(x1, staffb + slen, ntrem) } /* draw the note heads */ | < | | 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 |
slen -= 5 + 5.4
}
slen /= s.p_v.scale;
out_trem(x1, staffb + slen, ntrem)
}
/* draw the note heads */
for (m = 0; m <= s.nhd; m++)
draw_basic_note(s, m, y_tb)
}
// find where to start a long decoration
function prev_scut(s) {
while (s.prev) {
s = s.prev
if (s.rbstart)
|
| ︙ | ︙ | |||
1723 1724 1725 1726 1727 1728 1729 |
if (dir > 0) {
if (k1.stem > 0) {
x1 += 5
if (k1.beam_end
&& k1.nflags >= -1 /* if with a stem */
//fixme: check if at end of tuplet
&& !k1.in_tuplet) {
| < < | | | | | | | | < | | | | | | | | | 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 |
if (dir > 0) {
if (k1.stem > 0) {
x1 += 5
if (k1.beam_end
&& k1.nflags >= -1 /* if with a stem */
//fixme: check if at end of tuplet
&& !k1.in_tuplet) {
if (k1.nflags > 0) {
x1 += 2;
y1 = k1.ys - 3
} else {
y1 = k1.ys - 6
}
} else {
y1 = k1.ys + 3
}
} else {
y1 = k1.y + 8
}
} else {
if (k1.stem < 0) {
x1 -= 1
if (k2.grace) {
y1 = k1.y - 8
} else if (k1.beam_end
&& k1.nflags >= -1
&& (!k1.in_tuplet
|| k1.ys < y1 + 3)) {
if (k1.nflags > 0) {
x1 += 2;
y1 = k1.ys + 3
} else {
y1 = k1.ys + 6
}
} else {
y1 = k1.ys - 3
}
} else {
y1 = k1.y - 8
}
}
}
}
if (sl.is_note) { // end on a note
y2 = 3 * (sl.note.pit - 18) + 2 * dir
x2 -= 3
} else { // end on a chord
y2 = dir > 0 ? k2.ymx + 2 : k2.ymn - 2
if (k2.type == C.NOTE) {
if (dir > 0) {
if (k2.stem > 0) {
x2 += 1
if (k2.beam_st
&& k2.nflags >= -1
&& !k2.in_tuplet)
y2 = k2.ys - 6
else
y2 = k2.ys + 3
} else {
y2 = k2.y + 8
}
} else {
if (k2.stem < 0) {
x2 -= 5
if (k2.beam_st
&& k2.nflags >= -1
&& !k2.in_tuplet)
// || k2.ys < y2 + 3))
y2 = k2.ys + 6
else
y2 = k2.ys - 3
} else {
y2 = k2.y - 8
}
}
}
}
if (k1.type != C.NOTE) {
y1 = y2 + 1.2 * dir;
|
| ︙ | ︙ | |||
1957 1958 1959 1960 1961 1962 1963 |
if (dir > 0) {
if (height < .8 * y)
height = .8 * y
} else {
if (height > -.8 * y)
height = -.8 * y
}
| | | | 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 |
if (dir > 0) {
if (height < .8 * y)
height = .8 * y
} else {
if (height > -.8 * y)
height = -.8 * y
}
height *= k1.fmt.slurheight;
// anno_start(k1_o, 'slur');
slur_out(x1, y1, x2, y2, dir, height, ty & C.SL_DOTTED);
// anno_stop(k1_o, 'slur');
/* have room for other symbols */
dx = x2 - x1;
a = (y2 - y1) / dx;
/*fixme: it seems to work with .4, but why?*/
// addy = y1 - a * x1 + .4 * height
//fixme: the following code seems better!
addy = y1 - a * x1
if (height > 0)
addy += 4 * Math.sqrt(height) - 2
else
addy -= 4 * Math.sqrt(-height) - 2
for (i = 0; i < i2; i++) {
k = path[i]
if (k.st != upstaff || k.type == C.BAR)
continue
y = a * k.x + addy
if (k.ymx < y)
k.ymx = y
else if (k.ymn > y)
k.ymn = y
if (i == i2 - 1) {
|
| ︙ | ︙ | |||
2168 2169 2170 2171 2172 2173 2174 | s = s.next } } /* -- draw a tuplet -- */ /* (the staves are not yet defined) */ /* (delayed output) */ | | | | | 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 |
s = s.next
}
}
/* -- draw a tuplet -- */
/* (the staves are not yet defined) */
/* (delayed output) */
/* See http://moinejf.free.fr/abcm2ps-doc/tuplets.html
* for the value of 'tp.f' */
function draw_tuplet(s1) {
var s2, s3, g, upstaff, nb_only,
x1, x2, y1, y2, xm, ym, a, s0, yy, yx, dy, a, dir, r, w,
tp = s1.tp.shift() // tuplet parameters
if (!s1.tp.length)
delete s1.tp // last tuplet
// treat the slurs and the nested tuplets
upstaff = s1.st
|
| ︙ | ︙ | |||
2428 2429 2430 2431 2432 2433 2434 |
/* shift the slurs / decorations */
ym += 6
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
yy = ym + (s3.x - xm) * a
if (s3.ymx < yy)
s3.ymx = yy
| | < | > | < | 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 |
/* shift the slurs / decorations */
ym += 6
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
yy = ym + (s3.x - xm) * a
if (s3.ymx < yy)
s3.ymx = yy
w = s3.next.x - s3.x - 10
y_set(upstaff, true, s3.x - w, w * 2, yy)
}
if (s3 == s2)
break
}
// below
} else { /* lower voice of the staff: the bracket is below the staff */
/*fixme: think to all of that again..*/
if (s1.stem < 0)
x1 -= 2
|
| ︙ | ︙ | |||
2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 |
a = (y2 - y1) / (x2 - x1);
s0 = 3 * (s2.notes[0].pit - s1.notes[0].pit) / (x2 - x1)
if (s0 > 0) {
if (a < 0)
a = 0
else if (a > s0)
a = s0
} else {
if (a > 0)
a = 0
else if (a < s0)
a = s0
}
if (a * a < .1 * .1)
a = 0
/* shift down the bracket if needed */
dy = 0
for (s3 = s1; ; s3 = s3.next) {
| > > > > | 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 |
a = (y2 - y1) / (x2 - x1);
s0 = 3 * (s2.notes[0].pit - s1.notes[0].pit) / (x2 - x1)
if (s0 > 0) {
if (a < 0)
a = 0
else if (a > s0)
a = s0
if (a > .35)
a = .35
} else {
if (a > 0)
a = 0
else if (a < s0)
a = s0
if (a < -.35)
a = -.35
}
if (a * a < .1 * .1)
a = 0
/* shift down the bracket if needed */
dy = 0
for (s3 = s1; ; s3 = s3.next) {
|
| ︙ | ︙ | |||
2501 2502 2503 2504 2505 2506 2507 |
y1 = ym + a * (x1 - xm);
y2 = ym + a * (x2 - xm);
/* shift the slurs / decorations */
ym -= 2
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
| < < > > | | | > > > > | < | 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 |
y1 = ym + a * (x1 - xm);
y2 = ym + a * (x2 - xm);
/* shift the slurs / decorations */
ym -= 2
for (s3 = s1; ; s3 = s3.next) {
if (s3.st == upstaff) {
yy = ym + (s3.x - xm) * a
if (s3.ymn > yy)
s3.ymn = yy;
w = s3.next.x - s3.x - 10
if (s3.next)
y_set(upstaff, false, s3.x - w, w * 2, yy)
}
if (s3 == s2)
break
}
} /* lower voice */
if (tp.f[2] == 1) { /* if 'which' == none */
out_tubr(x1, y1 + 4, x2 - x1, y2 - y1, dir == C.SL_ABOVE);
return
}
out_tubrn(x1, y1, x2 - x1, y2 - y1, dir == C.SL_ABOVE,
tp.f[2] == 0 ? tp.p.toString() : tp.p + ':' + tp.q);
if (dir == C.SL_ABOVE)
y_set(upstaff, true, xm - 3, 6, yy + 2)
else
y_set(upstaff, false, xm - 3, 6, yy)
}
// -- draw a ties --
function draw_tie(not1, not2,
job) { // -: start and end
// 1: no starting note
// 2: no ending note
// 3: no start for clef or staff change
var m, x1, s, y, h, time,
p = job == 2 ? not1.pit : not2.pit,
dir = (not1.tie_ty & 0x07) == C.SL_ABOVE ? 1 : -1,
s1 = not1.s,
st = s1.st,
s2 = not2.s,
x2 = s2.x,
sh = not1.shhd // head shift
|
| ︙ | ︙ | |||
2570 2571 2572 2573 2574 2575 2576 |
if (s2.notes[m - 1].shhd < sh)
sh = s2.notes[m - 1].shhd
}
x2 += sh // * .6
}
switch (job) {
| | > | | < > > | > < < | < > | | < < < < < < < < < < | < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < < < < < < | | < | | < | | | | | | | | < < < | < > | > | | | | < | > > | > > | > < | | < < < < | | | | > | < | < < < < < | < < < < | < | < > > | < < < > > | < | < < < < < < < < < | < < < > > | | | | | 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 |
if (s2.notes[m - 1].shhd < sh)
sh = s2.notes[m - 1].shhd
}
x2 += sh // * .6
}
switch (job) {
default:
if (p < not2.pit || dir < 0)
p = not1.pit
break
case 3:
dir = -dir
case 1: /* no starting note */
x1 = s2.prev ? (s2.prev.x + s2.wr) : s1.x
if (s1.st != s2.st)
st = s2.st
x1 += (x2 - x1) * .4
if (x1 > x2 - 20)
x1 = x2 - 20
break
case 2: // no ending note
x2 = s1.next ? s1.next.x : realwidth
if (x2 != realwidth)
x2 -= (x2 - x1) * .4
if (x2 < x1 + 16)
x2 = x1 + 16
break
}
if (x2 - x1 > 20) {
x1 += 3.5
x2 -= 3.5
} else {
x1 += 1.5
x2 -= 1.5
}
if (s1.dots && !(not1.pit & 1)
&& ((dir > 0 && !s1.dot_low)
|| (dir < 0 && s1.dot_low)))
x1 += 5
y = staff_tb[st].y + 3 * (p - 18) + /* 1.0 * */ dir
h = (.03 * (x2 - x1) + 16) * dir * s1.fmt.tieheight
// anno_start(k1, 'slur')
slur_out(x1, y, x2, y, dir, h, not1.tie_ty & C.SL_DOTTED)
// anno_stop(k1, 'slur')
} // draw_tie()
/* -- draw all ties between neighboring notes -- */
function draw_all_ties(p_voice) {
var s, s1, s2, clef_chg, x, dx, m, not1, not2,
tim2 = 0
/* search the start of ties */
// clef_chg = false
s1 = p_voice.sym
set_color(s1.color)
for ( ; s1; s1 = s1.next) {
if (s1.ti2 // if end of tie
&& s1.time != tim2) { // and new end
for (m = 0; m <= s1.nhd; m++) {
not2 = s1.notes[m]
not1 = not2.tie_s
if (!not1
|| not1.s.v != s1.v) // (already done)
continue
draw_tie(not1, not2, 1)
}
}
if (!s1.ti1) // if not start of tie
continue
// get the end of the tie(s)
if (s1.type == C.GRACE) {
for (s = s1.extra; s; s = s.next) {
for (m = 0; m <= s1.nhd; m++) {
not1 = s.notes[m]
not2 = not1.tie_e
if (!not2)
continue
draw_tie(not1, not2)
tim2 = not2.s.time
}
}
continue
}
for (m = 0; m <= s1.nhd; m++) {
not1 = s1.notes[m]
not2 = not1.tie_e
if (!not2) {
if (not1.tie_ty)
draw_tie(not1, not1, 2)
continue
}
s2 = not2.s
if (tsnext && s2.time >= tsnext.time) { // if end in next line
draw_tie(not1, not2, 2)
continue
}
tim2 = s2.time
// check if some clef changes (can occur in an other voice)
for (s = s1.ts_next; s != s2; s = s.ts_next) {
if (s.st != s1.st)
continue
if (s.type == C.CLEF) {
clef_chg = true
break
}
}
/* ties with clef or staff change */
if (clef_chg || s1.st != s2.st) {
draw_tie(not1, not2, 2)
draw_tie(not1, not2, 3)
clef_chg = false
} else {
draw_tie(not1, not2)
}
}
}
}
/* -- draw the symbols near the notes -- */
/* (the staves are not yet defined) */
/* order:
* - scaled
* - beams
* - decorations near the notes
* - measure bar numbers
* - decorations tied to the notes
* - tuplets and slurs
* - not scaled
* - measure numbers
* - lyrics
* - staff decorations
* - chord symbols
* - repeat brackets
* The buffer output is delayed until the definition of the staff system
*/
function draw_sym_near() {
var p_voice, p_st, s, v, st, y, g, w, i, st, dx, top, bot, ymn, slur,
output_sav = output;
// set the staff offsets of a beam
function set_yab(s1, s2) {
var y,
k = realwidth / YSTEP,
i = (s1.x / k) | 0,
|
| ︙ | ︙ | |||
2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 |
p_st.bot[i] = y
i++
}
}
} // set_yab()
output = ""
// initialize the min/max vertical offsets in the staves
for (st = 0; st <= nstaff; st++) {
p_st = staff_tb[st]
| > < | | < > > > > > > > > > > > > > > > | 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 |
p_st.bot[i] = y
i++
}
}
} // set_yab()
output = ""
YSTEP = Math.ceil(realwidth / 2)
// initialize the min/max vertical offsets in the staves
for (st = 0; st <= nstaff; st++) {
p_st = staff_tb[st]
p_st.top = new Float32Array(YSTEP)
p_st.bot = new Float32Array(YSTEP)
for (i = 0; i < YSTEP; i++) {
p_st.top[i] = 0
p_st.bot[i] = 24
}
// p_st.top.fill(0.)
// p_st.bot.fill(24.)
}
/* calculate the beams but don't draw them (the staves are not yet defined) */
for (v = 0; v < voice_tb.length; v++) {
var bm = {},
first_note = true;
p_voice = voice_tb[v]
for (s = p_voice.sym; s; s = s.next) {
switch (s.type) {
case C.GRACE:
slur = 0
for (g = s.extra; g; g = g.next) {
if (g.beam_st && !g.beam_end) {
self.calculate_beam(bm, g)
if (bm.s2)
set_yab(g, bm.s2)
}
if (g.sls || g.sl1)
slur++
}
if (!s.p_v.ckey.k_bagpipe // no slur when bagpipe
&& s.fmt.graceslurs
&& !s.gr_shift // tied to previous note
&& !slur // explicit slur
&& !s.ti1 // some tie
&& s.next
&& s.next.type == C.NOTE)
grace_slur(s)
break
}
}
for (s = p_voice.sym; s; s = s.next) {
switch (s.type) {
case C.NOTE:
if ((s.beam_st && !s.beam_end)
|| (first_note && !s.beam_st)) {
first_note = false;
self.calculate_beam(bm, s)
if (bm.s2)
set_yab(s, bm.s2)
|
| ︙ | ︙ | |||
3032 3033 3034 3035 3036 3037 3038 | if (bot < p_st.bot[i]) p_st.bot[i] = bot } } if (cfmt.measurenb >= 0) draw_measnb(); | < > > | 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 |
if (bot < p_st.bot[i])
p_st.bot[i] = bot
}
}
if (cfmt.measurenb >= 0)
draw_measnb();
/* if any lyric, draw them now as unscaled */
set_dscale(-1)
// set_sscale(-1)
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (p_voice.have_ly) {
draw_all_lyrics()
break
}
}
draw_deco_staff()
set_dscale(-1);
output = output_sav
}
/* -- draw the name/subname of the voices -- */
function draw_vname(indent, stl) {
|
| ︙ | ︙ | |||
3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 |
y = staff_tb[st].y
+ staff_tb[st].topbar * .5
* staff_tb[st].staffscale
+ h2 * (a_p.length - 2)
// if instrument with 2 staves, center the voice name
if ((cur_sy.staves[st].flags & OPEN_BRACE)
&& (cur_sy.staves[st + 1].flags & CLOSE_BRACE)
&& !staff_d[st + 1])
y -= (staff_tb[st].y - staff_tb[st + 1].y) * .5
for (n = 0; n < a_p.length; n++) {
p = a_p[n];
xy_str(indent, y, p, "c");
y -= h
}
}
}
// -- set the y offset of the staves and return the height of the whole system --
function set_staff() {
| > | > | 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 |
y = staff_tb[st].y
+ staff_tb[st].topbar * .5
* staff_tb[st].staffscale
+ h2 * (a_p.length - 2)
// if instrument with 2 staves, center the voice name
if ((cur_sy.staves[st].flags & OPEN_BRACE)
&& st + 1 < staff_tb.length
&& (cur_sy.staves[st + 1].flags & CLOSE_BRACE)
&& !staff_d[st + 1])
y -= (staff_tb[st].y - staff_tb[st + 1].y) * .5
for (n = 0; n < a_p.length; n++) {
p = a_p[n];
xy_str(indent, y, p, "c");
y -= h
}
}
}
// -- set the y offset of the staves and return the height of the whole system --
function set_staff() {
var i, st, prev_staff, v,
y, staffsep, dy, maxsep, mbot, val, p_voice, p_staff,
fmt = tsfirst.fmt,
sy = cur_sy
/* set the scale of the voices */
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (p_voice.scale != 1)
p_voice.scale_str =
|
| ︙ | ︙ | |||
3166 3167 3168 3169 3170 3171 3172 |
if (!gene.st_print[st]) {
p_staff.y = -y
return y
}
/* set the vertical offset of the 1st staff */
y *= p_staff.staffscale;
| | | 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 |
if (!gene.st_print[st]) {
p_staff.y = -y
return y
}
/* set the vertical offset of the 1st staff */
y *= p_staff.staffscale;
staffsep = fmt.staffsep * .5 +
p_staff.topbar * p_staff.staffscale
if (y < staffsep)
y = staffsep
if (y < p_staff.ann_top) // absolute annotation
y = p_staff.ann_top;
p_staff.y = -y;
|
| ︙ | ︙ | |||
3250 3251 3252 3253 3254 3255 3256 | if (gene.st_print[st]) break } if (st < 0) /* no symbol in this system ! */ return y } dy = -mbot; | | | | | | 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 |
if (gene.st_print[st])
break
}
if (st < 0) /* no symbol in this system ! */
return y
}
dy = -mbot;
staffsep = fmt.staffsep * .5
if (dy < staffsep)
dy = staffsep;
maxsep = fmt.maxstaffsep * .5
if (dy > maxsep)
dy = maxsep;
// return the height of the whole staff system
return y + dy
}
/* -- draw the staff systems and the measure bars -- */
function draw_systems(indent) {
var s, s2, st, x, x2, res, sy,
staves_bar, bar_force,
xstaff = [],
stl = [], // all staves in the line
bar_bot = [],
bar_height = [],
ba = [], // bars [symbol, bottom, height]
sb = "",
thb = ""
/* -- set the bottom and height of the measure bars -- */
function bar_set() {
var st, staffscale, top, bot,
dy = 0
for (st = 0; st <= cur_sy.nstaff; st++) {
|
| ︙ | ︙ | |||
3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 | //fixme: 's.ts_prev.st != st - 1' when floating voice in lower staff // && (s.ts_prev.type != C.BAR || s.ts_prev.st != st - 1)) && s.ts_prev.type != C.BAR) h = p_staff.topbar * p_staff.staffscale; s.ymx = s.ymn + h; anno_start(s) if (s.color) set_color(s.color); // compute the middle vertical offset of the staff yb = p_staff.y + 12; if (p_staff.stafflines != '|||||') | > | 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 | //fixme: 's.ts_prev.st != st - 1' when floating voice in lower staff // && (s.ts_prev.type != C.BAR || s.ts_prev.st != st - 1)) && s.ts_prev.type != C.BAR) h = p_staff.topbar * p_staff.staffscale; s.ymx = s.ymn + h; set_sscale(-1) anno_start(s) if (s.color) set_color(s.color); // compute the middle vertical offset of the staff yb = p_staff.y + 12; if (p_staff.stafflines != '|||||') |
| ︙ | ︙ | |||
3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 |
;
xygl(s2.x, yb, "mrep")
} else {
xygl(x, yb, "mrep2")
if (s.v == cur_sy.top_voice)
nrep_out(x, yb + p_staff.topbar, s.bar_mrep)
}
}
if (bar_type == '||:')
bar_type = '[|:'
for (i = bar_type.length; --i >= 0; ) {
switch (bar_type[i]) {
case "|":
if (s.bar_dotted) {
| > < | > > | > > > | 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 |
;
xygl(s2.x, yb, "mrep")
} else {
xygl(x, yb, "mrep2")
if (s.v == cur_sy.top_voice)
nrep_out(x, yb + p_staff.topbar, s.bar_mrep)
}
set_sscale(-1)
}
if (bar_type == '||:')
bar_type = '[|:'
for (i = bar_type.length; --i >= 0; ) {
switch (bar_type[i]) {
case "|":
if (s.bar_dotted) {
w = (5 * p_staff.staffscale).toFixed(1);
out_XYAB(
'<path class="bW" stroke-dasharray="A,A" d="MX Yv-G"/>\n',
x, bot, w, h)
} else if (s.color) {
out_XYAB('<path class="bW" d="MX Yv-F"/>\n',
x, bot, h)
} else {
sb += 'M' + sx(x).toFixed(1)
+ ' ' + self.sy(bot).toFixed(1)
+ 'v-' + h.toFixed(1)
}
break
default:
// case "[":
// case "]":
x -= 3;
if (s.color)
out_XYAB('<path class="bthW" d="MX Yv-F"/>\n',
x + 1.5, bot, h)
else
thb += 'M' + sx(x + 1.5).toFixed(1)
+ ' ' + self.sy(bot).toFixed(1)
+ 'v-' + h.toFixed(1)
break
case ":":
x -= 2;
set_sscale(st);
xygl(x + 1, yb - 12, "rdots")
set_sscale(-1)
break
}
x -= 3
}
set_color();
anno_stop(s)
} // draw_bar()
|
| ︙ | ︙ | |||
3458 3459 3460 3461 3462 3463 3464 | b = ba[i]; // symbol, bottom, height draw_bar(b[0], b[1], b[2]) } if (bx) gene.curfont.box = bx set_sscale(-1) | < | < | < > | > | > > > | > > > > > > > > > | > > | | > > > > > > > > > > > | | < > > > | > > > > > > > > > > > | | 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 |
b = ba[i]; // symbol, bottom, height
draw_bar(b[0], b[1], b[2])
}
if (bx)
gene.curfont.box = bx
set_sscale(-1)
if (sb) // single bars
output += '<path class="bW" d="'
+ sb
+ '"/>\n'
if (thb) // thick bars [x, y, h]
output += '<path class="bthW" d="'
+ thb
+ '"/>\n'
} // out_bars()
// set the helper lines of rests
function hl_rest(s) {
var j,
p_st = staff_tb[s.st],
i = 5 - s.nflags, // rest_tb index (5 = C_XFLAGS)
x = s.x,
y = s.y
if (i < 6) // no ledger line if rest smaller than minim
return
if (i == 7 && y == 12
&& p_st.stafflines.length <= 2)
y -= 6 // semibreve a bit lower
j = y / 6
switch (i) {
default:
switch (p_st.stafflines[j + 1]) {
case '|':
case '[':
break
default:
set_hl(p_st, j + 1, x, -7, 7)
break
}
if (i == 9) { // longa
y -= 6
j--
}
break
case 7: // semibreve
y += 6
j++
case 6: // minim
break
}
switch (p_st.stafflines[j]) {
case '|':
case '[':
break
default:
set_hl(p_st, j, x, -7, 7)
break
}
} // hl_rest()
// ---- draw_systems() ----
/* draw the staff, skipping the staff breaks */
for (st = 0; st <= nstaff; st++) {
xstaff[st] = !cur_sy.st_print[st] ? -1 : 0;
stl[st] = cur_sy.st_print[st] // staff in the line
|
| ︙ | ︙ | |||
3547 3548 3549 3550 3551 3552 3553 | if (sy.st_print[st]) xstaff[st] = x2 } cur_sy = sy; bar_set() continue case C.BAR: // display the bars after the staves | > > > | > > > | 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 |
if (sy.st_print[st])
xstaff[st] = x2
}
cur_sy = sy;
bar_set()
continue
case C.BAR: // display the bars after the staves
if (s.invis || !s.bar_type
|| !cur_sy.st_print[s.st])
break
if (s.second
&& (!s.ts_prev
|| (s.ts_prev.type == C.BAR
&& s.ts_prev.st == s.st)))
break
ba.push([s, bar_bot[s.st], bar_height[s.st]])
break
case C.STBRK:
if (cur_sy.voices[s.v]
&& cur_sy.voices[s.v].range == 0) {
if (s.xmx > 14) {
|
| ︙ | ︙ | |||
3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 |
s.x - s.xmx
if (x >= x2)
break
draw_staff(st, x, x2)
xstaff[st] = s.x
}
break
// default:
//fixme:does not work for "%%staves K: M: $" */
//removed for K:/M: in empty staves
// if (!cur_sy.st_print[st])
// s.invis = true
// break
}
}
// draw the end of the staves
for (st = 0; st <= nstaff; st++) {
if (bar_force && !cur_sy.st_print[st])
continue
x = xstaff[st]
if (x < 0 || x >= realwidth)
continue
draw_staff(st, x, realwidth)
}
// and the bars
out_bars()
draw_vname(indent, stl)
// set_sscale(-1)
}
/* -- draw remaining symbols when the staves are defined -- */
// (possible hook)
Abc.prototype.draw_symbols = function(p_voice) {
var bm = {},
| > > > > > > > > > > > > > > > > > > | | 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 |
s.x - s.xmx
if (x >= x2)
break
draw_staff(st, x, x2)
xstaff[st] = s.x
}
break
case C.GRACE:
for (s2 = s.extra; s2; s2 = s2.next)
self.draw_hl(s2)
break
case C.NOTE:
if (!s.invis)
self.draw_hl(s)
break
case C.REST:
if (s.fmr // if full measure rest
|| (s.rep_nb && s.rep_nb >= 0))
center_rest(s)
if (!s.invis)
hl_rest(s)
break
// default:
//fixme:does not work for "%%staves K: M: $" */
//removed for K:/M: in empty staves
// if (!cur_sy.st_print[st])
// s.invis = true
// break
}
}
// draw the end of the staves
for (st = 0; st <= nstaff; st++) {
if (bar_force && !cur_sy.st_print[st])
continue
x = xstaff[st]
if (x < 0 || x >= realwidth)
continue
draw_staff(st, x, realwidth)
}
// the ledger lines
draw_all_hl()
// and the bars
out_bars()
draw_vname(indent, stl)
// set_sscale(-1)
}
/* -- draw remaining symbols when the staves are defined -- */
// (possible hook)
Abc.prototype.draw_symbols = function(p_voice) {
var bm = {},
s, x, y, st;
// bm.s2 = undefined
for (s = p_voice.sym; s; s = s.next) {
if (s.invis) {
switch (s.type) {
case C.KEY:
p_voice.ckey = s
|
| ︙ | ︙ | |||
3685 3686 3687 3688 3689 3690 3691 |
if (s.clef_small)
y -= 1
} else {
y += s.ymn + 6
if (s.clef_small)
y += 1
}
| | > > | 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 |
if (s.clef_small)
y -= 1
} else {
y += s.ymn + 6
if (s.clef_small)
y += 1
}
xygl(x - 2, y, (s.clef_octave == 7
|| s.clef_octave == -7)
? "oct" : "oct2")
}
anno_a.push(s)
break
case C.METER:
p_voice.meter = s
if (s.second
|| !staff_tb[s.st].topbar)
|
| ︙ | ︙ | |||
3712 3713 3714 3715 3716 3717 3718 | set_color(); set_sscale(s.st); anno_start(s); self.draw_keysig(x, s); anno_a.push(s) break case C.MREST: | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > > > > > > > > > > > > | > > > | > > > > > < < < < < < < < < < < < | | 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 |
set_color();
set_sscale(s.st);
anno_start(s);
self.draw_keysig(x, s);
anno_a.push(s)
break
case C.MREST:
draw_mrest(s)
break
case C.GRACE:
set_scale(s);
draw_gracenotes(s)
break
case C.SPACE:
case C.STBRK:
break /* nothing */
case C.CUSTOS:
set_scale(s);
draw_note(s, 0)
break
case C.BLOCK: // no width
case C.REMARK:
case C.STAVES:
case C.TEMPO:
break
default:
error(2, s, "draw_symbols - Cannot draw symbol " + s.type)
break
}
}
set_scale(p_voice.sym);
}
/* -- draw all symbols -- */
function draw_all_sym() {
var p_voice, v,
n = voice_tb.length
for (v = 0; v < n; v++) {
p_voice = voice_tb[v]
if (p_voice.sym
&& p_voice.sym.x != undefined) {
self.draw_symbols(p_voice)
draw_all_ties(p_voice);
// no need to reset the scale as in abcm2ps
set_color()
}
}
self.draw_all_deco()
glout() // output the symbols
anno_put() // before outputting the symbol annotations
set_sscale(-1) /* restore the scale */
}
/* -- set the tie directions for one voice -- */
function set_tie_dir(s) {
var i, ntie, dir, sec, pit, ty, s2
for ( ; s; s = s.next) {
if (!s.ti1)
continue
sec = ntie = 0;
pit = 128
for (i = 0; i <= s.nhd; i++) {
if (s.notes[i].tie_ty) {
ntie++
if (pit < 128
&& s.notes[i].pit <= pit + 1)
sec++;
pit = s.notes[i].pit
s2 = s.notes[i].tie_e
}
}
if (s2 && s.stem * s2.stem < 0)
dir = pit >= 22 // up if above middle staff
? C.SL_ABOVE : C.SL_BELOW
else if (s.multi)
dir = s.multi > 0 ? C.SL_ABOVE : C.SL_BELOW
else
dir = s.stem < 0 ? C.SL_ABOVE : C.SL_BELOW
// if other voice, set the ties in opposite direction
if (s.multi) {
for (i = 0; i <= s.nhd; i++) {
ty = s.notes[i].tie_ty
if (!((ty & 0x07) == C.SL_AUTO))
continue
s.notes[i].tie_ty = (ty & C.SL_DOTTED) | dir
}
continue
}
/* if one note, set the direction according to the stem */
if (ntie <= 1) {
for (i = 0; i <= s.nhd; i++) {
ty = s.notes[i].tie_ty
if (ty) {
if ((ty & 0x07) == C.SL_AUTO)
s.notes[i].tie_ty =
(ty & C.SL_DOTTED) | dir
break
}
}
continue
}
if (!sec) {
if (ntie & 1) {
/* in chords with an odd number of notes, the outer noteheads are paired off
* center notes are tied according to their position in relation to the
* center line */
ntie = (ntie - 1) / 2;
dir = C.SL_BELOW
for (i = 0; i <= s.nhd; i++) {
|
| ︙ | ︙ | |||
3946 3947 3948 3949 3950 3951 3952 |
if (!s)
continue
s = s.next
if (!s)
continue
set_tie_dir(s)
for ( ; s; s = s.next) {
| | | 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 |
if (!s)
continue
s = s.next
if (!s)
continue
set_tie_dir(s)
for ( ; s; s = s.next) {
if (!s.ti1)
continue
if (s.notes[0].pit < 20
&& s.notes[0].tie_ty
&& (s.notes[0].tie_ty & 0x07) == C.SL_BELOW)
;
else if (s.notes[s.nhd].pit > 24
&& s.notes[s.nhd].tie_ty
|
| ︙ | ︙ |
Changes to core/format.js.
| ︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 |
serif: 1,
serifBold: 1,
'sans-serif': 1,
'sans-serifBold': 1,
Palatino: 1.1,
monospace: 1.35
},
fmt_lock = {}
var cfmt = {
| > > | > > > > > > > > > > > | < | | | | | | | | | < | > > > > > | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 |
serif: 1,
serifBold: 1,
'sans-serif': 1,
'sans-serifBold': 1,
Palatino: 1.1,
monospace: 1.35
},
txt_ff = "text,serif", // text font-family (serif for compatibility)
fmt_lock = {}
var cfmt = {
"abc-version": "1", // default: old version
annotationfont: {name: "text,sans-serif", size: 12},
aligncomposer: 1,
beamslope: .4, // max slope of a beam
// botmargin: .7 * IN, // != 1.8 * CM,
bardef: {
"[": "", // invisible
"[]": "",
"|:": "[|:",
"|::": "[|::",
"|:::": "[|:::",
":|": ":|]",
"::|": "::|]",
":::|": ":::|]",
"::": ":][:"
},
breaklimit: .7,
breakoneoln: true,
cancelkey: true,
composerfont: { name: txt_ff, style: "italic", size: 14 },
composerspace: 6,
// contbarnb: false,
decoerr: true,
dynalign: true,
footerfont: { name: txt_ff, size: 16 },
fullsvg: '',
gchordfont: { name: "text,sans-serif", size: 12 },
gracespace: new Float32Array([6, 8, 11]), // left, inside, right
graceslurs: true,
headerfont: { name: txt_ff, size: 16 },
historyfont: { name: txt_ff, size: 16 },
hyphencont: true,
indent: 0,
infofont: {name: txt_ff, style: "italic", size: 14 },
infoname: 'R "Rhythm: "\n\
B "Book: "\n\
S "Source: "\n\
D "Discography: "\n\
N "Notes: "\n\
Z "Transcription: "\n\
H "History: "',
infospace: 0,
keywarn: true,
leftmargin: 1.4 * CM,
lineskipfac: 1.1,
linewarn: true,
maxshrink: .65, // nice scores
maxstaffsep: 2000,
maxsysstaffsep: 2000,
measrepnb: 1,
measurefont: {name: txt_ff, style: "italic", size: 10},
measurenb: -1,
musicfont: {name: "music", src: musicfont, size: 24},
musicspace: 6,
// notespacingfactor: "1.3, 38",
partsfont: {name: txt_ff, size: 15},
parskipfac: .4,
partsspace: 8,
// pageheight: 29.7 * CM,
pagewidth: 21 * CM,
printmargin: 0,
rightmargin: 1.4 * CM,
rbmax: 4,
rbmin: 2,
repeatfont: {name: txt_ff, size: 13},
scale: 1,
slurheight: 1.0,
spatab: // spacing table (see "notespacingfactor" and set_space())
new Float32Array([ // default = "1.3, 38"
10.2, 13.3, 17.3, 22.48, 29.2,
38,
49.4, 64.2, 83.5, 108.5]),
staffsep: 46,
stemheight: 21, // one octave
stretchlast: .25,
stretchstaff: true,
subtitlefont: {name: txt_ff, size: 16},
subtitlespace: 3,
sysstaffsep: 34,
tempofont: {name: txt_ff, weight: "bold", size: 12},
textfont: {name: txt_ff, size: 16},
// textoption: undefined,
textspace: 14,
tieheight: 1.0,
titlefont: {name: txt_ff, size: 20},
// titleleft: false,
titlespace: 6,
titletrim: true,
// transp: 0, // global transpose
// topmargin: .7 * IN,
topspace: 22,
tuplets: [0, 0, 0, 0],
tupletfont: {name: txt_ff, style: "italic", size: 12},
vocalfont: {name: txt_ff, weight: "bold", size: 13},
vocalspace: 10,
voicefont: {name: txt_ff, weight: "bold", size: 13},
// voicescale: 1,
writefields: "CMOPQsTWw",
wordsfont: {name: txt_ff, size: 16},
wordsspace: 5
}
// parameters that are used in the symbols
var sfmt = {
bardef: true,
barsperstaff: true,
beamslope: true,
breaklimit: true,
bstemdown: true,
cancelkey: true,
dynalign: true,
flatbeams: true,
gracespace: true,
hyphencont: true,
keywarn: true,
maxshrink: true,
maxstaffsep: true,
measrepnb: true,
rbmax: true,
rbmin: true,
shiftunison: true,
slurheight: true,
squarebreve: true,
staffsep: true,
stemheight: true,
stretchlast: true,
stretchstaff: true,
tieheight: true,
timewarn: true,
vocalspace: true
} // sfmt
function get_bool(param) {
return !param || !/^(0|n|f)/i.test(param) // accept void as true !
}
// %%font <font> [<encoding>] [<scale>]
function get_font_scale(param) {
var i, font,
a = info_split(param) // a[0] = font name
if (a.length <= 1)
return
var scale = +a[a.length - 1]
if (isNaN(scale) || scale <= 0.5) {
syntax(1, "Bad scale value in %%font")
return
}
font_scale_tb[a[0]] = scale
}
|
| ︙ | ︙ | |||
165 166 167 168 169 170 171 |
pad: 0
}
} else {
font = {
name: font.name,
size: font.size,
box: font.box,
| | | | 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 |
pad: 0
}
} else {
font = {
name: font.name,
size: font.size,
box: font.box,
pad: font.pad || 0
}
}
cfmt[xxxfont] = font;
// fill the values
a = p.match(/\s+(no)?box(\s|$)/)
if (a) { // if box
if (a[1]) {
font.box = false // nobox
font.pad = 0
} else {
font.box = true
font.pad = font.size * .4 - 3
}
p = p.replace(a[0], a[2])
}
a = p.match(/\s+padding=([\d.]+)(\s|$)/)
if (a) { // if padding
font.pad = a[1] ? +a[1] : 0
p = p.replace(a[0], a[2])
}
a = p.match(/\s+class=(.*?)(\s|$)/)
if (a) {
font.class = a[1];
p = p.replace(a[0], a[2])
|
| ︙ | ︙ | |||
217 218 219 220 221 222 223 |
p = p.replace(a[0], a[2])
}
// the font size is the last item
a = p.match(/\s+([0-9.]+|\*)$/)
if (a) {
if (a[1] != "*")
| | > > | | > > > > > > > > > > > > > > > > > > > > > > > | | > | | | > | | > | | | | | | | | | > > > > > > > > > > > > > > > > > > > < < < < < < < | < < < < < < < < | | 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 |
p = p.replace(a[0], a[2])
}
// the font size is the last item
a = p.match(/\s+([0-9.]+|\*)$/)
if (a) {
if (a[1] != "*")
font.size = +a[1]
p = p.replace(a[0], "")
}
// accept url(...) as the font name
if (p[0] == 'u' && p.slice(0, 4) == "url(") {
n = p.indexOf(')', 1)
if (n < 0) {
syntax(1, "No end of url in font family")
return
}
p = p.slice(0, n + 1)
font.src = p
font.fid = font_tb.length
font_tb.push(font)
font.normal = true
p = 'ft' + font.fid
} else {
if (p[0] == '"') {
n = p.indexOf('"', 1)
if (n < 0) {
syntax(1, "No end of string in font family")
return
}
p = p.slice(1, n)
}
// extract the font attributes
a = p.match(/[- ]?[nN]ormal/)
if (a) {
font.normal = true
p = p.replace(a[0], '')
}
// font weight
a = p.match(abc2svg.ft_re)
if (a) {
font.weight = abc2svg.ft_w[a[0].replace(/[ -]/, '')
.toLowerCase()]
p = p.replace(a[0], '')
}
a = p.match(/[- ]?[iI]talic/)
if (a) {
font.style = "italic"
p = p.replace(a[0], '')
}
a = p.match(/[- ]?[oO]blique/)
if (a) {
font.style = "oblique"
p = p.replace(a[0], '')
}
// here is the font family
p = p.trim()
switch (p) {
case "":
case "*": return
case "Times-Roman":
case "Times": p = "serif"; break
case "Helvetica": p = "sans-serif"; break
case "Courier": p = "monospace"; break
case "music": p = cfmt.musicfont.name; break
default:
//hack: the font "Figurato" is used for figured bass
if (p.indexOf("Fig") > 0)
font.figb = true
break
}
}
if (font.size)
set_font_fac(font)
else
font.swfac = 0
font.name = p
}
// get a length with a unit - return the number of pixels
function get_unit(param) {
var v = param.toLowerCase().match(/([\d.]+)(.*)/)
if (!v)
return NaN
v[1] = +v[1]
switch (v[2]) {
case "cm":
return v[1] * CM
case "in":
return v[1] * IN
case "pt": // paper point in 1/72 inch
return v[1] * .75
|
| ︙ | ︙ | |||
312 313 314 315 316 317 318 319 320 321 322 |
// get the text option
var textopt = {
align: 'j',
center: 'c',
fill: 'f',
justify: 'j',
ragged: 'f',
right: 'r',
skip: 's'
}
| > | > > > | | | 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 |
// get the text option
var textopt = {
align: 'j',
center: 'c',
fill: 'f',
justify: 'j',
obeylines: 'l',
ragged: 'f',
right: 'r',
skip: 's'
}
function get_textopt(v) {
var i = v.indexOf(' ')
if (i > 0)
v = v.slice(0, i)
return textopt[v]
}
/* -- position of a voice element -- */
var posval = {
above: C.SL_ABOVE,
auto: 0, // !! not C.SL_AUTO !!
below: C.SL_BELOW,
down: C.SL_BELOW,
hidden: C.SL_HIDDEN,
opposite: C.SL_HIDDEN,
under: C.SL_BELOW,
up: C.SL_ABOVE
}
/* -- set the position of elements in a voice -- */
function set_pos(k, v) { // keyword, value
k = k.slice(0, 3)
if (k == "ste")
k = "stm"
set_v_param("pos", '"' + k + ' ' + v + '"')
}
// set/unset the fields to write
function set_writefields(parm) {
var c, i,
a = parm.split(/\s+/)
|
| ︙ | ︙ | |||
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 |
if (cmd == "soundfont")
cfmt.soundfont = param
else
param_set_font(cmd, param)
return
}
switch (cmd) {
case "aligncomposer":
case "barsperstaff":
case "infoline":
case "measurenb":
case "rbmax":
case "rbmin":
case "measrepnb":
case "shiftunison":
v = parseInt(param)
if (isNaN(v)) {
syntax(1, "Bad integer value");
break
}
cfmt[cmd] = v
break
case "bgcolor":
case "fgcolor":
| > > > > > < < | | 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 |
if (cmd == "soundfont")
cfmt.soundfont = param
else
param_set_font(cmd, param)
return
}
// duplicate the global parameters if already used by symbols
if (sfmt[cmd] && parse.ufmt)
cfmt = Object.create(cfmt)
switch (cmd) {
case "aligncomposer":
case "barsperstaff":
case "infoline":
case "measurenb":
case "rbmax":
case "rbmin":
case "measrepnb":
case "shiftunison":
v = parseInt(param)
if (isNaN(v)) {
syntax(1, "Bad integer value");
break
}
cfmt[cmd] = v
break
case "abc-version":
case "bgcolor":
case "fgcolor":
case "titleformat":
cfmt[cmd] = param
break
case "beamslope":
case "breaklimit": // float values
case "lineskipfac":
case "maxshrink":
case "pagescale":
case "parskipfac":
case "scale":
case "slurheight":
case "stemheight":
case "tieheight":
f = +param
if (isNaN(f)) {
syntax(1, errs.bad_val, '%%' + cmd)
break
}
switch (cmd) {
case "scale": // old scale
f /= .75
|
| ︙ | ︙ | |||
458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
case "annotationbox":
case "gchordbox":
case "measurebox":
case "partsbox":
param_set_font(cmd.replace("box", "font"), // font
"* * " + (get_bool(param) ? "box" : "nobox"))
break
case "bstemdown":
case "breakoneoln":
case "cancelkey":
case "checkbars":
case "contbarnb":
case "custos":
case "decoerr":
| > < < > > > > > > > > > > > > > | 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 |
case "annotationbox":
case "gchordbox":
case "measurebox":
case "partsbox":
param_set_font(cmd.replace("box", "font"), // font
"* * " + (get_bool(param) ? "box" : "nobox"))
break
case "altchord":
case "bstemdown":
case "breakoneoln":
case "cancelkey":
case "checkbars":
case "contbarnb":
case "custos":
case "decoerr":
case "flatbeams":
case "graceslurs":
case "graceword":
case "hyphencont":
case "keywarn":
case "linewarn":
case "quiet":
case "singleline":
case "squarebreve":
case "splittune":
case "straightflags":
case "stretchstaff":
case "timewarn":
case "titlecaps":
case "titleleft":
cfmt[cmd] = get_bool(param)
break
case "dblrepbar":
param = ":: " + param
// fall thru
case "bardef": // %%bardef oldbar newbar
v = param.split(/\s+/)
if (v.length != 2) {
syntax(1, errs.bad_val, "%%bardef")
} else {
if (parse.ufmt)
cfmt.bardef = Object.create(cfmt.bardef) // new object
cfmt.bardef[v[0]] = v[1]
}
break
case "chordalias":
v = param.split(/\s+/)
if (!v.length)
syntax(1, errs.bad_val, "%%chordalias")
else
abc2svg.ch_alias[v[0]] = v[1] || ""
|
| ︙ | ︙ | |||
564 565 566 567 568 569 570 | } //fixme: should check only alpha, num and '_' characters cfmt[cmd] = param break case "gracespace": v = param.split(/\s+/) for (i = 0; i < 3; i++) | | > > | > > | | > > > > > > > > > > > > > > > > | < | | < | | | | > > > > | | 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 |
}
//fixme: should check only alpha, num and '_' characters
cfmt[cmd] = param
break
case "gracespace":
v = param.split(/\s+/)
for (i = 0; i < 3; i++)
if (isNaN(+v[i])) {
syntax(1, errs.bad_val, "%%gracespace")
break
}
if (parse.ufmt)
cfmt[cmd] = new Float32Array(3)
for (i = 0; i < 3; i++)
cfmt[cmd][i] = +v[i]
break
case "tuplets":
cfmt[cmd] = param.split(/\s+/);
v = cfmt[cmd][3]
if (v // if 'where'
&& (posval[v])) // translate the keyword
cfmt[cmd][3] = posval[v]
break
case "infoname":
set_infoname(param)
break
case "notespacingfactor":
v = param.match(/([.\d]+)[,\s]*(\d+)?/)
if (v) {
f = +v[1]
if (isNaN(f) || f < 1 || f > 2) {
f = 0
} else if (v[2]) {
f2 = +v[2]
if (isNaN(f))
f = 0
} else {
f2 = cfmt.spatab[5]
}
}
if (!f) {
syntax(1, errs.bad_val, "%%" + cmd)
break
}
cfmt[cmd] = param // (for dump)
// in the table 'spatab',
// the width of notes is indexed by log2(note_length)
cfmt.spatab = new Float32Array(10)
i = 5; // index of crotchet
do {
cfmt.spatab[i] = f2
f2 /= f
} while (--i >= 0)
i = 5;
f2 = cfmt.spatab[i]
for ( ; ++i < cfmt.spatab.length; ) {
f2 *= f;
cfmt.spatab[i] = f2
}
break
case "play":
cfmt.sound = "play" // without clef
break
case "pos":
cmd = param.match(/(\w*)\s+(.*)/)
if (!cmd || !cmd[2]) {
syntax(1, "Error in %%pos")
break
}
set_pos(cmd[1], cmd[2])
break
case "sounding-score":
if (cfmt.sound != "play")
cfmt.sound = "sounding"
break
case "staffwidth":
v = get_unit(param)
|
| ︙ | ︙ | |||
632 633 634 635 636 637 638 639 | } cfmt.rightmargin = v; img.chg = true break case "textoption": cfmt[cmd] = get_textopt(param) break case "titletrim": | > > | | > > > | > > | > > > > > > > > | > > > > > > | 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 |
}
cfmt.rightmargin = v;
img.chg = true
break
case "textoption":
cfmt[cmd] = get_textopt(param)
break
case "dynalign":
case "stretchlast":
case "titletrim":
v = +param
if (isNaN(v))
v = get_bool(param) ? 0 : 1
if (cmd[0] == 's') { // stretchlast
if (v < 0 || v > 1) {
syntax(1, errs.bad_val, '%%' + cmd)
break
}
}
cfmt[cmd] = v
break
case "combinevoices":
syntax(1, "%%combinevoices is deprecated - use %%voicecombine instead")
break
case "voicemap":
set_v_param("map", param)
break
case "voicescale":
set_v_param("scale", param)
break
// deprecated
case "rbdbstop":
v = get_bool(param)
if (v && cfmt["abc-version"] >= "2.2")
cfmt["abc-version"] = "1"
else if (!v && cfmt["abc-version"] < "2.2")
cfmt["abc-version"] = "2.2"
break
default: // memorize all global commands
if (!parse.state) // (needed for modules)
cfmt[cmd] = param
break
}
// check if already a same format
if (sfmt[cmd] && parse.ufmt) {
// to do...
parse.ufmt = false
}
}
// font stuff
// build a font style
function st_font(font) {
var n = font.name,
|
| ︙ | ︙ | |||
698 699 700 701 702 703 704 |
font_tb.push(font)
if (!font.swfac)
set_font_fac(font)
if (!font.pad)
font.pad = 0
}
add_fstyle(".f" + font.fid +
| | > > > > | | | | 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 |
font_tb.push(font)
if (!font.swfac)
set_font_fac(font)
if (!font.pad)
font.pad = 0
}
add_fstyle(".f" + font.fid +
(cfmt.fullsvg || "") +
"{" + style_font(font) + "}")
if (font.src)
add_fstyle("@font-face{\n\
font-family:" + font.name + ";\n\
src:" + font.src + "}")
if (font == cfmt.musicfont) // add more music font style
add_fstyle(".f" + font.fid
+ (cfmt.fullsvg || "")
+ ' text,tspan{fill:currentColor;white-space:pre}')
}
}
// get the font of the 'xxxfont' parameter
function get_font(fn) {
var font, font2, fid, st
fn += "font"
font = cfmt[fn]
if (!font) {
syntax(1, "Unknown font $1", '$' + fn[1]);
return gene.curfont
}
if (!font.name || !font.size) { // if incomplete user font
font2 = Object.create(gene.deffont)
if (font.name)
font2.name = font.name
if (font.normal) {
if (font2.weight) // !! don't use delete !!
font2.weight = null
if (font2.style)
font2.style = null
} else {
if (font.weight)
font2.weight = font.weight
if (font.style)
font2.style = font.style
}
if (font.src)
font2.src = font.src
if (font.size)
font2.size = font.size
st = st_font(font2)
if (font.class) {
font2.class = font.class
st += ' '+ font.class
}
|
| ︙ | ︙ |
Changes to core/front.js.
1 2 | // abc2svg - front.js - ABC parsing front-end // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - front.js - ABC parsing front-end // // Copyright (C) 2014-2021 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
100 101 102 103 104 105 106 | i += 4 break } dst += c j = i + 5 continue case 't': // TAB | | > > | 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 |
i += 4
break
}
dst += c
j = i + 5
continue
case 't': // TAB
dst += '\t';
j = i + 1
continue
case 'n': // new line (voice name)
dst += '\n';
j = i + 1
continue
default:
c2 = abc_utf[src.slice(i, i + 2)]
if (c2) {
dst += c2;
j = i + 2
continue
}
// try unicode combine characters
c2 = src[i + 1]
if (!c2)
break // !! the next test is true if c2 is undefined !!
if (!/[A-Za-z]/.test(c2))
break
switch (c) {
case '`':
dst += c2 + "\u0300" // grave
j = i + 2
continue
|
| ︙ | ︙ | |||
179 180 181 182 183 184 185 | case ';': dst += c2 + "\u0328" // ogonek j = i + 2 continue } break } | | | | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | case ';': dst += c2 + "\u0328" // ogonek j = i + 2 continue } break } if (flag == 'w') // if lyrics line (w:) dst += '\\' // keep the backslash dst += c j = i + 1 } return dst + src.slice(j) } // ABC include |
| ︙ | ︙ | |||
282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
char_tb = sav.char_tb;
glovar = sav.glovar;
maps = sav.maps;
mac = sav.mac;
maci = sav.maci;
parse.tune_v_opts = null;
parse.scores = null;
init_tune()
img.chg = true;
set_page();
} // end_tune()
// get %%voice
function do_voice(select, in_tune) {
| > > | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
char_tb = sav.char_tb;
glovar = sav.glovar;
maps = sav.maps;
mac = sav.mac;
maci = sav.maci;
parse.tune_v_opts = null;
parse.scores = null;
parse.ufmt = false
delete parse.part
init_tune()
img.chg = true;
set_page();
} // end_tune()
// get %%voice
function do_voice(select, in_tune) {
|
| ︙ | ︙ | |||
393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
parse.fname = in_fname
// scan the file
if (bol == undefined)
bol = 0
if (!eof)
eof = file.length
for ( ; bol < eof; bol = parse.eol + 1) {
eol = file.indexOf('\n', bol) // get a line
if (eol < 0 || eol > eof)
eol = eof;
parse.eol = eol
// remove the ending white spaces
| > > | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
parse.fname = in_fname
// scan the file
if (bol == undefined)
bol = 0
if (!eof)
eof = file.length
if (file.slice(bol, bol + 5) == "%abc-")
cfmt["abc-version"] = /[1-9.]+/.exec(file.slice(bol + 5, bol + 10))
for ( ; bol < eof; bol = parse.eol + 1) {
eol = file.indexOf('\n', bol) // get a line
if (eol < 0 || eol > eof)
eol = eof;
parse.eol = eol
// remove the ending white spaces
|
| ︙ | ︙ | |||
481 482 483 484 485 486 487 |
if (i < 0) {
syntax(1, "No $1 after %%$2",
end.slice(1), a[1]);
parse.eol = eof
continue
}
self.do_begin_end(b, uncomment(a[2]),
| | < | | 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
if (i < 0) {
syntax(1, "No $1 after %%$2",
end.slice(1), a[1]);
parse.eol = eof
continue
}
self.do_begin_end(b, uncomment(a[2]),
file.slice(eol + 1, i)
.replace(/^%%/gm,''))
parse.eol = file.indexOf('\n', i + 6)
if (parse.eol < 0)
parse.eol = eof
continue
}
switch (a[1]) {
case "select":
|
| ︙ | ︙ | |||
705 706 707 708 709 710 711 | get_sym(text, txt_add == ' ') break case 'w': if (parse.state != 3 || cfmt.writefields.indexOf(line0) < 0) break get_lyrics(text, txt_add == ' ') | < < < < < | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 | get_sym(text, txt_add == ' ') break case 'w': if (parse.state != 3 || cfmt.writefields.indexOf(line0) < 0) break get_lyrics(text, txt_add == ' ') break case '|': // "|:" starts a music line if (parse.state < 2) continue parse.line.buffer = text parse_music_line() continue |
| ︙ | ︙ |
Changes to core/gchord.js.
1 2 | // abc2svg - gchord.js - chord symbols // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - gchord.js - chord symbols // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
text = type.slice(1, -1);
iend = istart + 1
} else {
i = ++line.index // search the ending double quote
while (1) {
j = line.buffer.indexOf('"', i)
if (j < 0) {
| | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
text = type.slice(1, -1);
iend = istart + 1
} else {
i = ++line.index // search the ending double quote
while (1) {
j = line.buffer.indexOf('"', i)
if (j < 0) {
syntax(1, "No end of chord symbol/annotation")
return
}
if (line.buffer[j - 1] != '\\')
break
i = j + 1
}
text = cnv_escape(line.buffer.slice(line.index, j))
|
| ︙ | ︙ | |||
83 84 85 86 87 88 89 |
y_abs = 0
} else {
y_abs = get_float()
if (c != ' ')
i--
}
gch.x = x_abs;
| > | > > > > > > > > > > > > | | 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 |
y_abs = 0
} else {
y_abs = get_float()
if (c != ' ')
i--
}
gch.x = x_abs;
y_abs -= h_ann * .3 // center vertically
gch.y = y_abs
break
case '^':
gch.pos = C.SL_ABOVE
// fall thru
case '_':
if (c == '_')
gch.pos = C.SL_BELOW
// fall thru
case '<':
case '>':
i++;
type = c
break
default:
switch (type) {
case 'g':
gch.font = get_font("gchord")
gch.pos = curvoice.pos.gch || C.SL_ABOVE
break
case '^':
gch.pos = C.SL_ABOVE
break
case '_':
gch.pos = C.SL_BELOW
break
case '@':
gch.x = x_abs;
y_abs -= h_ann;
gch.y = y_abs
break
}
break
}
gch.type = type
while (1) {
c = text[i]
|
| ︙ | ︙ | |||
201 202 203 204 205 206 207 |
gch.text = gch_tr1(gch.text, curvoice.vtransp)
}
}
// parser: add the parsed list of chord symbols and annotations
// to the symbol (note, rest or bar)
function csan_add(s) {
| > > > > > > > > > > > > > > > > | < < | < | 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 |
gch.text = gch_tr1(gch.text, curvoice.vtransp)
}
}
// parser: add the parsed list of chord symbols and annotations
// to the symbol (note, rest or bar)
function csan_add(s) {
var i, gch
// there cannot be chord symbols on measure bars
if (s.type == C.BAR) {
for (i = 0; i < a_gch.length; i++) {
if (a_gch[i].type == 'g') {
syntax(1,
"There cannot be chord symbols on measure bars")
a_gch.splice(i)
}
}
}
if (s.a_gch)
s.a_gch = s.a_gch.concat(a_gch)
else
s.a_gch = a_gch
a_gch = null
if (curvoice.vtransp)
gch_transp(s)
} // csan_add
// generator: build the chord symbols / annotations
// (possible hook)
Abc.prototype.gch_build = function(s) {
/* split the chord symbols / annotations
* and initialize their vertical offsets */
var gch, wh, xspc, ix,
y_left = 0,
y_right = 0,
GCHPRE = .4; // portion of chord before note
// change the accidentals in the chord symbols,
// convert the escape sequences in annotations, and
// set the offsets
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
if (gch.type == 'g') {
gch.text = gch.text.replace(/##|#|=|bb|b/g,
function(x) {
switch (x) {
case '##': return "𝄪"
case '#': return "\u266f"
case '=': return "\u266e"
case 'b': return "\u266d"
}
return "𝄫"
});
} else {
if (gch.type == '@'
&& !user.anno_start && !user.anno_stop) {
set_font(gch.font)
|
| ︙ | ︙ | |||
257 258 259 260 261 262 263 |
gch.text = str2svg(gch.text)
wh = gch.text.wh
wh[1] += gch.font.pad * 2
switch (gch.type) {
case '@':
break
case '^': /* above */
| < < < < < | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
gch.text = str2svg(gch.text)
wh = gch.text.wh
wh[1] += gch.font.pad * 2
switch (gch.type) {
case '@':
break
case '^': /* above */
case '_': /* below */
xspc = wh[0] * GCHPRE
if (xspc > 8)
xspc = 8;
gch.x = -xspc;
break
case '<': /* left */
|
| ︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 |
}
// -- draw the chord symbols and annotations
// (the staves are not yet defined)
// (unscaled delayed output)
// (possible hook)
Abc.prototype.draw_gchord = function(i, s, x, y) {
var y2,
an = s.a_gch[i],
h = an.text.wh[1],
pad = an.font.pad,
| > > | > > > > > > | 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 |
}
// -- draw the chord symbols and annotations
// (the staves are not yet defined)
// (unscaled delayed output)
// (possible hook)
Abc.prototype.draw_gchord = function(i, s, x, y) {
if (s.invis && s.play) // play sequence: no chord nor annotation
return
var y2,
an = s.a_gch[i],
h = an.text.wh[1],
pad = an.font.pad,
w = an.text.wh[0] + pad * 2,
dy = 0
if (an.font.figb) {
h *= 2.4
dy = an.font.size * 1.3
}
switch (an.type) {
case '_': // below
y -= h + pad
y_set(s.st, 0, x, w, y - pad)
break
case '^': // above
|
| ︙ | ︙ | |||
343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
x += pad
}
y += (s.type == C.NOTE ?
(((s.notes[s.nhd].pit + s.notes[0].pit) >> 1) -
18) * 3 :
12) // fixed offset on rests and bars
- h / 2
break
default: // chord symbol
if (y >= 0) {
y += pad
y_set(s.st, 1, x, w, y + h + pad)
} else {
y -= h + pad
| > > > > | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
x += pad
}
y += (s.type == C.NOTE ?
(((s.notes[s.nhd].pit + s.notes[0].pit) >> 1) -
18) * 3 :
12) // fixed offset on rests and bars
- h / 2
if (y > 24)
y_set(s.st, 1, x, w, y + h + pad)
if (y < 0)
y_set(s.st, 0, x, w, y - pad)
break
default: // chord symbol
if (y >= 0) {
y += pad
y_set(s.st, 1, x, w, y + h + pad)
} else {
y -= h + pad
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 |
}
use_font(an.font)
set_font(an.font)
set_dscale(s.st)
if (user.anno_start)
user.anno_start("annot", an.istart, an.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
| | < < < < | < | | < | | 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 |
}
use_font(an.font)
set_font(an.font)
set_dscale(s.st)
if (user.anno_start)
user.anno_start("annot", an.istart, an.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
xy_str(x, y + dy, an.text)
if (user.anno_stop)
user.anno_stop("annot", an.istart, an.iend,
x - 2, y + h + 2, w + 4, h + 4, s)
} // draw_gchord()
// draw all chord symbols
function draw_all_chsy() {
var s, san1, an, i, y, w,
n_an = 0, // max number of annotations
minmax = new Array(nstaff + 1)
// set a vertical offset to all the chord symbols/annotations
function set_an_yu(j) {
var an, i, s, x, y, w
for (s = san1 ; s; s = s.ts_next) {
an = s.a_gch
if (!an)
continue
i = an.length - j - 1
an = an[i]
if (!an)
continue
if (an.pos == C.SL_ABOVE) {
x = s.x + an.x
w = an.text.wh[0]
if (w && x + w > realwidth)
x = realwidth - w // let the text in the page
y = y_get(s.st, 1, x, w) // y / staff
if (an.type == 'g' && y < minmax[s.st].yup)
y = minmax[s.st].yup
} else if (an.pos == C.SL_BELOW
|| an.pos == C.SL_HIDDEN) {
continue
} else {
x = s.x + an.x
y = an.y
}
self.draw_gchord(i, s, x, y)
}
} // set_an_yu()
function set_an_yl(i) {
var an, x, y, w
for (var s = san1 ; s; s = s.ts_next) {
an = s.a_gch
if (!an)
continue
an = an[i]
if (!an
|| an.pos != C.SL_BELOW)
continue
x = s.x + an.x
w = an.text.wh[0]
if (w && x + w > realwidth) // let the text inside the page
x = realwidth - w
y = y_get(s.st, 0, x, w) // y / staff
if (an.type == 'g' && y > minmax[s.st].ydn)
|
| ︙ | ︙ | |||
467 468 469 470 471 472 473 |
i = an.length
if (i > n_an)
n_an = i
while (--i >= 0) {
if (an[i].type == 'g') {
an = an[i]
w = an.text.wh[0]
| | | | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
i = an.length
if (i > n_an)
n_an = i
while (--i >= 0) {
if (an[i].type == 'g') {
an = an[i]
w = an.text.wh[0]
if (an.pos == C.SL_ABOVE) {
y = y_get(s.st, true, s.x, w)
if (y > minmax[s.st].yup)
minmax[s.st].yup = y
} else if (an.pos == C.SL_BELOW) {
y = y_get(s.st, false, s.x, w)
if (y < minmax[s.st].ydn)
minmax[s.st].ydn = y
}
break
}
}
|
| ︙ | ︙ |
Changes to core/license.
1 2 | // abc2svg - ABC to SVG translator // @source: https://chiselapp.com/user/moinejf/repository/abc2svg | | | 1 2 3 | // abc2svg - ABC to SVG translator // @source: https://chiselapp.com/user/moinejf/repository/abc2svg // Copyright (C) 2014-2021 Jean-Francois Moine - LGPL3+ |
Changes to core/lyrics.js.
1 2 | // abc2svg - lyrics.js - lyrics // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - lyrics.js - lyrics // // Copyright (C) 2014-2021 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
29 30 31 32 33 34 35 |
s = curvoice.sym_cont
if (!s) {
syntax(1, "+: symbol line without music")
return
}
} else {
if (curvoice.sym_restart) { // new music
| | < < > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
s = curvoice.sym_cont
if (!s) {
syntax(1, "+: symbol line without music")
return
}
} else {
if (curvoice.sym_restart) { // new music
curvoice.sym_start = curvoice.sym_restart;
curvoice.sym_restart = null
}
s = curvoice.sym_start
if (!s)
s = curvoice.sym
if (!s) {
syntax(1, "s: without music")
return
}
}
|
| ︙ | ︙ | |||
68 69 70 71 72 73 74 |
case '!':
case '"':
j = ++i
i = p.indexOf(c, j)
if (i < 0) {
syntax(1, c == '!' ?
"No end of decoration" :
| | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
case '!':
case '"':
j = ++i
i = p.indexOf(c, j)
if (i < 0) {
syntax(1, c == '!' ?
"No end of decoration" :
"No end of chord symbol/annotation");
i = p.length
continue
}
d = p.slice(j - 1, i + 1)
break
case '*':
break
|
| ︙ | ︙ | |||
91 92 93 94 95 96 97 | } } syntax(1, errs.bad_char, c) break } /* store the element in the next note */ | | | > | | | > > > > > > < > > < < | > < < < < < | > > | < > > > > > > > > | | < < < < < < | < > > > | | | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > | > | < | | | | | | > | | | | | | | | | < < | | | > | | | > > > > > > > | > | | | | | < | < | < < < > | < < > | > | < | < < | | < < | | 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 |
}
}
syntax(1, errs.bad_char, c)
break
}
/* store the element in the next note */
while (s && s.type != C.NOTE)
s = s.next
if (!s) {
syntax(1, "Too many elements in symbol line")
return
}
switch (c) {
default:
// case '*':
break
case '!':
a_dcn.push(d.slice(1, -1))
deco_cnv(s, s.prev)
break
case '"':
parse_gchord(d)
if (a_gch) // if no error
csan_add(s)
break
}
s = s.next;
i++
}
curvoice.sym_cont = s
}
/* -- parse a lyric (vocal) line (w:) -- */
function get_lyrics(text, cont) {
var s, word, p, i, j, ly, dfnt, ln, c, cf
if (curvoice.ignore)
return
if ((curvoice.pos.voc & 0x07) != C.SL_HIDDEN)
curvoice.have_ly = true
// get the starting symbol of the lyrics
if (cont) { // +:
s = curvoice.lyric_cont
if (!s) {
syntax(1, "+: lyric without music")
return
}
dfnt = get_font("vocal")
if (gene.deffont != dfnt) { // if vocalfont change
if (gene.curfont == gene.deffont)
gene.curfont = dfnt
gene.deffont = dfnt
}
} else {
set_font("vocal")
if (curvoice.lyric_restart) { // new music
curvoice.lyric_start = s = curvoice.lyric_restart;
curvoice.lyric_restart = null;
curvoice.lyric_line = 0
} else {
curvoice.lyric_line++;
s = curvoice.lyric_start
}
if (!s)
s = curvoice.sym
if (!s) {
syntax(1, "w: without music")
return
}
}
/* scan the lyric line */
p = text;
i = 0
cf = gene.curfont
while (1) {
while (p[i] == ' ' || p[i] == '\t')
i++
if (!p[i])
break
ln = 0
j = parse.istart + i + 2 // start index
switch (p[i]) {
case '|':
while (s && s.type != C.BAR)
s = s.next
if (!s) {
syntax(1, "Not enough measure bars for lyric line")
return
}
s = s.next;
i++
continue
case '-':
case '_':
word = p[i]
ln = 2 // line continuation
break
case '*':
word = ""
break
default:
word = "";
while (1) {
if (!p[i])
break
switch (p[i]) {
case '_':
case '*':
case '|':
i--
case ' ':
case '\t':
break
case '~':
word += ' '; // ( )
i++
continue
case '-':
ln = 1 // start of line
break
case '\\':
if (!p[++i])
continue
word += p[i++]
continue
case '$':
word += p[i++]
c = p[i]
if (c == '0')
gene.curfont = gene.deffont
else if (c >= '1' && c <= '9')
gene.curfont = get_font("u" + c)
// fall thru
default:
word += p[i++]
continue
}
break
}
break
}
/* store the word in the next note */
while (s && s.type != C.NOTE)
s = s.next
if (!s) {
syntax(1, "Too many words in lyric line")
return
}
if (word
&& (s.pos.voc & 0x07) != C.SL_HIDDEN) {
ly = {
t: word,
font: cf,
istart: j,
iend: j + word.length
}
if (ln)
ly.ln = ln
if (!s.a_ly)
s.a_ly = []
s.a_ly[curvoice.lyric_line] = ly
cf = gene.curfont
}
s = s.next;
i++
}
curvoice.lyric_cont = s
}
// install the words under a note
// (this function is called during the generation)
function ly_set(s) {
var i, j, ly, d, s1, s2, p, w, spw, xx, sz, shift, dw,
s3 = s, // start of the current time sequence
wx = 0,
wl = 0,
n = 0,
dx = 0,
a_ly = s.a_ly,
align = 0
// get the available horizontal space before the next lyric words
for (s2 = s.ts_next; s2; s2 = s2.ts_next) {
if (s2.shrink) {
dx += s2.shrink
n++ // number of symbols without word
}
if (s2.bar_type) { // stop on a bar
dx += 3 // and take some of its spacing
break
}
if (!s2.a_ly)
continue
i = s2.a_ly.length
while (--i >= 0) {
ly = s2.a_ly[i]
if (!ly)
continue
if (ly.ln != 2)
break
}
if (i >= 0)
break
}
// define the offset of the words
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (!ly)
continue
gene.curfont = ly.font
ly.t = p = str2svg(ly.t)
if (ly.ln == 2) {
ly.shift = 0
continue
}
spw = cwid(' ') * ly.font.swfac
w = p.wh[0] + spw * 1.5
if (s.type == C.GRACE) { // %%graceword
shift = s.wl
} else if ((p[0] >= '0' && p[0] <= '9' && p.length > 2)
|| p[1] == ':'
|| p[0] == '(' || p[0] == ')') {
if (p[0] == '(') {
sz = spw
} else {
j = p.indexOf(' '); // ( )
set_font(ly.font)
if (j > 0)
sz = strwh(p.slice(0, j))[0]
else
sz = w * .2
}
w -= sz
shift = w * .4
if (shift > 14)
shift = 14
shift += sz
if (p[0] >= '0' && p[0] <= '9') {
if (shift > align)
align = shift
}
} else {
shift = w * .4
if (shift > 14)
shift = 14
}
ly.shift = shift
if (shift > wl)
wl = shift // max left space
w -= shift // right width
if (w > wx)
wx = w // max width
}
// set the left space
while (!s3.seqst)
s3 = s3.ts_prev
if (s3.ts_prev && s3.ts_prev.bar_type)
wl -= 4 // don't move too much the measure bar
if (s3.wl < wl) {
s3.shrink += wl - s3.wl
s3.wl = wl
}
// if not room enough, shift the following notes to the right
dx -= 6
if (dx < wx) {
dx = (wx - dx) / n
s1 = s.ts_next
while (1) {
if (s1.shrink) {
s1.shrink += dx
s3.wr += dx // (needed for end of line)
s3 = s1
}
if (s1 == s2)
break
s1 = s1.ts_next
}
}
if (align > 0) {
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (ly && ly.t[0] >= '0' && ly.t[0] <= '9')
ly.shift = align
}
}
} // ly_set()
/* -- draw the lyrics under (or above) notes -- */
/* (the staves are not yet defined) */
function draw_lyric_line(p_voice, j, y) {
var p, lastx, w, s, s2, ly, lyl, ln,
hyflag, lflag, x0, font, shift
if (p_voice.hy_st & (1 << j)) {
hyflag = true;
p_voice.hy_st &= ~(1 << j)
}
for (s = p_voice.sym; /*s*/; s = s.next)
|
| ︙ | ︙ | |||
379 380 381 382 383 384 385 | } } continue } if (ly.font != gene.curfont) /* font change */ gene.curfont = font = ly.font; p = ly.t; | | | | | | < | | < | < | | | | | 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 |
}
}
continue
}
if (ly.font != gene.curfont) /* font change */
gene.curfont = font = ly.font;
p = ly.t;
w = p.wh[0]
shift = ly.shift
if (hyflag) {
if (ly.ln == 2 && p == "_") { // '_'
p = "-"
} else if (ly.ln != 2) { // not '-'
out_hyph(lastx, y, s.x - shift - lastx);
hyflag = false;
lastx = s.x + s.wr
}
}
if (lflag
&& (ly.ln != 2 || p != "_")) { // not '_'
out_wln(lastx + 3, y, x0 - lastx + 3);
lflag = false;
lastx = s.x + s.wr
}
if (ly.ln == 2) { // '-' or '_'
if (x0 == 0 && lastx > s.x - 18)
lastx = s.x - 18
if (p == '-')
hyflag = true
else
lflag = true;
x0 = s.x - shift
continue
}
x0 = s.x - shift;
if (ly.ln) // '-' at end
hyflag = true
if (user.anno_start || user.anno_stop) {
s2 = {
st: s.st,
istart: ly.istart,
iend: ly.iend,
x: x0,
y: y,
ymn: y,
ymx: y + gene.curfont.size,
wl: 0,
wr: w
}
anno_start(s2, 'lyrics')
}
xy_str(x0, y, p)
anno_stop(s2, 'lyrics')
lastx = x0 + w
}
if (hyflag) {
hyflag = false;
x0 = realwidth - 10
if (x0 < lastx + 10)
x0 = lastx + 10;
out_hyph(lastx, y, x0 - lastx)
if (p_voice.s_next && p_voice.s_next.fmt.hyphencont)
p_voice.hy_st |= (1 << j)
}
/* see if any underscore in the next line */
for (p_voice.s_next; s; s = s.next) {
if (s.type == C.NOTE) {
if (!s.a_ly)
break
ly = s.a_ly[j]
if (ly && ly.ln && ly.t == "_") {
lflag = true;
x0 = realwidth - 15
if (x0 < lastx + 12)
x0 = lastx + 12
}
break
}
|
| ︙ | ︙ | |||
468 469 470 471 472 473 474 |
function draw_lyrics(p_voice, nly, a_h, y,
incr) { /* 1: below, -1: above */
var j, top,
sc = staff_tb[p_voice.st].staffscale;
set_font("vocal")
if (incr > 0) { /* under the staff */
| | | | | | 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 |
function draw_lyrics(p_voice, nly, a_h, y,
incr) { /* 1: below, -1: above */
var j, top,
sc = staff_tb[p_voice.st].staffscale;
set_font("vocal")
if (incr > 0) { /* under the staff */
if (y > -tsfirst.fmt.vocalspace)
y = -tsfirst.fmt.vocalspace;
y *= sc
for (j = 0; j < nly; j++) {
y -= a_h[j] * 1.1;
draw_lyric_line(p_voice, j, y)
}
return (y - a_h[j - 1] / 6) / sc
}
/* above the staff */
top = staff_tb[p_voice.st].topbar + tsfirst.fmt.vocalspace
if (y < top)
y = top;
y *= sc
for (j = nly; --j >= 0;) {
draw_lyric_line(p_voice, j, y);
y += a_h[j] * 1.1
}
return y / sc
}
// -- draw all the lyrics --
/* (the staves are not yet defined) */
function draw_all_lyrics() {
var p_voice, s, v, nly, i, x, y, w, a_ly, ly,
lyst_tb = new Array(nstaff + 1),
nv = voice_tb.length,
h_tb = new Array(nv),
nly_tb = new Array(nv),
above_tb = new Array(nv),
rv_tb = new Array(nv),
top = 0,
bot = 0,
|
| ︙ | ︙ | |||
530 531 532 533 534 535 536 |
/*fixme:should get the real width*/
x = s.x;
w = 10
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (ly) {
x -= ly.shift;
| | | | | | 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 |
/*fixme:should get the real width*/
x = s.x;
w = 10
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (ly) {
x -= ly.shift;
w = ly.t.wh[0]
break
}
}
y = y_get(p_voice.st, 1, x, w)
if (top < y)
top = y;
y = y_get(p_voice.st, 0, x, w)
if (bot > y)
bot = y
while (nly < a_ly.length)
h_tb[v][nly++] = 0
for (i = 0; i < a_ly.length; i++) {
ly = a_ly[i]
if (!ly)
continue
if (!h_tb[v][i]
|| ly.t.wh[1] > h_tb[v][i])
h_tb[v][i] = ly.t.wh[1]
}
}
} else {
y = y_get(p_voice.st, 1, 0, realwidth)
if (top < y)
top = y;
y = y_get(p_voice.st, 0, 0, realwidth)
if (bot > y)
bot = y
}
if (!lyst_tb[st])
lyst_tb[st] = {}
lyst_tb[st].top = top;
lyst_tb[st].bot = bot;
nly_tb[v] = nly
if (nly == 0)
continue
if (p_voice.pos.voc)
above_tb[v] = (p_voice.pos.voc & 0x07) == C.SL_ABOVE
else if (voice_tb[v + 1]
/*fixme:%%staves:KO - find an other way..*/
&& voice_tb[v + 1].st == st
&& voice_tb[v + 1].have_ly)
above_tb[v] = true
else
above_tb[v] = false
|
| ︙ | ︙ |
Changes to core/mei.js.
1 2 | // abc2svg - mei.js - MEI front-end // | | | | 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 |
// abc2svg - mei.js - MEI front-end
//
// Copyright (C) 2019-2021 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>.
// convert the xml source into a tree
function xml2tree(xml) {
var i, j, item, n, no,
e = 0,
stack = [],
root = {
name: "root"
},
o = root
|
| ︙ | ︙ | |||
64 65 66 67 68 69 70 | continue } o = stack.pop() if (!o) error(1, null, 'No start tag "' + item + '"') continue } | | < | | | > | | | > | > > > | | 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 |
continue
}
o = stack.pop()
if (!o)
error(1, null, 'No start tag "' + item + '"')
continue
}
item = xml.slice(i + 1, e).trim()
no = {
name: item.match(/[\w-]+/)[0],
ix: i
}
if (!o.children)
o.children = []
o.children.push(no)
if (item.slice(-1) != '/') { // if some content
stack.push(o)
o = no
} else {
item = item.slice(0, -1).trim()
}
item = item.replace(/[^\s]*\s*/, '')
if (!item)
continue
n = item.match(/=|[^\s"=]+|".*?"/g) // "
for (j = 0; j < n.length; j += 3) {
if (n[j + 1] != '='
|| !n[j + 2]) {
mus.error(1, null, 'Bad key=value in "' + item + '"')
break
}
no[n[j]] = n[j + 2].slice(1, -1)
}
}
return root
}
// convert MEI to music suitable to the abc2svg generator
Abc.prototype.mei2mus = function(mei) {
|
| ︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 |
text: function(tag) {
if (curr.text != undefined)
curr.text += tag.content.replace(/[ \t\n]+/g, ' ')
},
// tie
tie: function(tag) {
| > | | | < | | | < | | | < | > | < | | < | | | | | | > > | 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 |
text: function(tag) {
if (curr.text != undefined)
curr.text += tag.content.replace(/[ \t\n]+/g, ' ')
},
// tie
tie: function(tag) {
var m1, m2, not1, not2,
s1 = get_ref(tag),
s2 = get_ref(tag, s1),
ty = C.SL_AUTO
if (!s1 || !s2)
return
switch (tag.curvedir) {
case "above": ty = C.SL_ABOVE; break
case "below": ty = C.SL_BELOW; break
}
switch (tag.lform) {
case "dashed":
case "dotted": ty |= C.SL_DOTTED; break
}
if (s1.s) { // note - note
not1 = s1
s1 = s1.s
not2 = s2
s2 = s2.s
not1.tie_ty = ty
not1.tie_e = not2
not2.tie_s = not1
} else { // chord - chord
for (m1 = 0; m1 <= s1.nhd; m1++) {
not1 = s1.notes[m1]
for (m2 = 0; m2 <= s2.nhd; m2++) {
not2 = s2.notes[m2]
if (not1.pit == not2.pit) {
not1.tie_ty = ty
not1.tie_e = not2
not2.tie_s = not1
}
}
}
s1.ti1 = s2.ti2 = true
}, // tie()
trill: function(tag) {
var s2,
s = get_ref(tag)
if (!s)
|
| ︙ | ︙ |
Changes to core/modules.js.
| ︙ | ︙ | |||
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
gamelan: {},
grid: {},
grid2: {},
jazzchord: {},
jianpu: {},
mdnn: {},
MIDI: {},
pageheight: { fn: 'page' },
pedline: {},
percmap: { fn: 'perc' },
soloffs: {},
sth: {},
strtab: {},
temperament: { fn: 'temper' },
nreq: 0,
hooks: [],
| > > | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
gamelan: {},
grid: {},
grid2: {},
jazzchord: {},
jianpu: {},
mdnn: {},
MIDI: {},
nns: {},
pageheight: { fn: 'page' },
pedline: {},
percmap: { fn: 'perc' },
roman: {},
soloffs: {},
sth: {},
strtab: {},
temperament: { fn: 'temper' },
nreq: 0,
hooks: [],
|
| ︙ | ︙ |
Changes to core/music.js.
1 2 | // abc2svg - music.js - music generation // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - music.js - music generation // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | // along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>. var gene, staff_tb, nstaff, // current number of staves tsnext, // next line when cut realwidth, // real staff width while generating | | < < < < < < < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>. var gene, staff_tb, nstaff, // current number of staves tsnext, // next line when cut realwidth, // real staff width while generating insert_meter, // insert the time signature spf_last, // spacing for last short line smallest_duration /* -- decide whether to shift heads to other side of stem on chords -- */ /* this routine is called only once per tune */ // distance for no overlap - index: [prev acc][cur acc] //var dt_tb = [ |
| ︙ | ︙ | |||
81 82 83 84 85 86 87 | dur = dur_o if (dur % 12 != 0) error(1, s, "Invalid note duration $1", dur); dur /= 12 /* see C.BLEN for values */ if (!dur) error(1, s, "Note too short") | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
dur = dur_o
if (dur % 12 != 0)
error(1, s, "Invalid note duration $1", dur);
dur /= 12 /* see C.BLEN for values */
if (!dur)
error(1, s, "Note too short")
for (flags = 5; dur; dur >>= 1, flags--) {
if (dur & 1)
break
}
dur >>= 1
if ((dur + 1) & dur) {
if (s.type != C.REST || dur_o != s.p_v.wmeasure)
error(0, s, "Non standard note duration $1", dur_o)
|
| ︙ | ︙ | |||
105 106 107 108 109 110 111 | error(1, s, "Note too long") flags = -4 /* fall thru */ case -4: head = C.SQUARE break case -3: | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | error(1, s, "Note too long") flags = -4 /* fall thru */ case -4: head = C.SQUARE break case -3: head = s.fmt.squarebreve ? C.SQUARE : C.OVALBARS break case -2: head = C.OVAL break case -1: head = C.EMPTY break |
| ︙ | ︙ | |||
127 128 129 130 131 132 133 | dir = s.stem, n = s.nhd if (!n) return // single note /* set the head shifts */ | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
dir = s.stem,
n = s.nhd
if (!n)
return // single note
/* set the head shifts */
dx = dx_head * .74
if (s.grace)
dx *= .6
if (dir >= 0) {
i1 = 1;
i2 = n + 1;
ps = s.notes[0].pit
} else {
dx = -dx;
i1 = n - 1;
|
| ︙ | ︙ | |||
245 246 247 248 249 250 251 |
if (p1 > ps + 4) { // if interval greater than a sixth
if (dx1 > dx2)
dx2 = dx1 // align the accidentals
notes[i1].shac = notes[i2].shac = dx2
} else {
notes[i1].shac = dx1
| > > | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
if (p1 > ps + 4) { // if interval greater than a sixth
if (dx1 > dx2)
dx2 = dx1 // align the accidentals
notes[i1].shac = notes[i2].shac = dx2
} else {
notes[i1].shac = dx1
if (p1 != ps)
dx1 += 7 // (there is a shift of a head when unison)
notes[i2].shac = dx2 = dx1
}
dx2 += 7
// shift the remaining accidentals
for (i = i1; --i > i2; ) { // from top to bottom
acc = notes[i].acc
if (!acc)
|
| ︙ | ︙ | |||
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
if (s.prev)
s.prev.next = s
else
s.p_v.sym = s;
next.prev = s
}
function lktsym(s, next) { // time linkage
s.ts_next = next
if (next) {
s.ts_prev = next.ts_prev
if (s.ts_prev)
s.ts_prev.ts_next = s;
next.ts_prev = s
} else {
//fixme
error(2, s, "Bad linkage")
s.ts_prev = null
}
s.seqst = !s.ts_prev
|| s.time != s.ts_prev.time
| > > | | < | > > > > | | | > > > | 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 |
if (s.prev)
s.prev.next = s
else
s.p_v.sym = s;
next.prev = s
}
function lktsym(s, next) { // time linkage
var old_wl
s.ts_next = next
if (next) {
s.ts_prev = next.ts_prev
if (s.ts_prev)
s.ts_prev.ts_next = s;
next.ts_prev = s
} else {
//fixme
error(2, s, "Bad linkage")
s.ts_prev = null
}
s.seqst = !s.ts_prev
|| s.time != s.ts_prev.time
|| (w_tb[s.ts_prev.type] != w_tb[s.type]
&& w_tb[s.ts_prev.type])
if (!next)
return
next.seqst = next.time != s.time ||
(w_tb[s.type] != w_tb[next.type]
&& w_tb[s.type])
if (next.seqst) {
old_wl = next.wl
self.set_width(next)
if (next.a_ly)
ly_set(next)
if (!next.shrink) {
next.shrink = next.wl
if (next.prev)
next.shrink += next.prev.wr
} else {
next.shrink += next.wl - old_wl
}
next.space = 0
}
}
/* -- unlink a symbol -- */
function unlksym(s) {
if (s.next)
|
| ︙ | ︙ | |||
437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
}
new_s.nhd = 0;
/* link in time */
while (!s.seqst)
s = s.ts_prev;
lktsym(new_s, s)
return new_s
}
/* -- set the staff of the floating voices -- */
/* this function is called only once per tune */
function set_float() {
var p_voice, st, staff_chg, v, s, s1, up, down
| > > > > | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 |
}
new_s.nhd = 0;
/* link in time */
while (!s.seqst)
s = s.ts_prev;
lktsym(new_s, s)
if (s.soln) { // move the start of line
new_s.soln = true
delete s.soln
}
return new_s
}
/* -- set the staff of the floating voices -- */
/* this function is called only once per tune */
function set_float() {
var p_voice, st, staff_chg, v, s, s1, up, down
|
| ︙ | ︙ | |||
530 531 532 533 534 535 536 |
}
}
}
/* -- set the x offset of the grace notes -- */
function set_graceoffs(s) {
var next, m, dx, x,
| | | | | | | | | < < | 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 |
}
}
}
/* -- set the x offset of the grace notes -- */
function set_graceoffs(s) {
var next, m, dx, x,
gspleft = s.fmt.gracespace[0],
gspinside = s.fmt.gracespace[1],
gspright = s.fmt.gracespace[2],
g = s.extra;
if (s.prev && s.prev.type == C.BAR)
gspleft -= 3;
x = gspleft;
g.beam_st = true
for ( ; ; g = g.next) {
set_head_shift(g)
acc_shift(g.notes, 6.5)
dx = 0
for (m = g.nhd; m >= 0; m--) {
if (g.notes[m].shac - 2 > dx)
dx = g.notes[m].shac - 2
}
x += dx;
g.x = x
if (g.nflags <= 0)
g.beam_st = g.beam_end = true
next = g.next
if (!next) {
g.beam_end = true
break
}
if (next.nflags <= 0)
g.beam_end = true
|
| ︙ | ︙ | |||
589 590 591 592 593 594 595 | x += gspright; /* return the whole width */ return x } // Compute the smallest spacing between symbols according to chord symbols | | > > > > > > | 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 |
x += gspright;
/* return the whole width */
return x
}
// Compute the smallest spacing between symbols according to chord symbols
// so that they stay at the same offset
// and, also, adjust the spacing due to the lyric words.
// Constraints:
// - assume the chord symbols are only in the first staff
// - treat only the first chord symbol of each symbol
// - the chord symbols under the staff are ignored
function set_w_chs(s) {
var i, ch, w0, s0, dw,
x = 0,
n = 0
set_font("vocal")
for ( ; s; s = s.ts_next) {
if (s.shrink) {
x += s.shrink;
n++
}
if (s.a_ly) // if some lyric
ly_set(s)
if (!s.a_gch)
continue
for (i = 0; i < s.a_gch.length; i++) {
ch = s.a_gch[i]
if (ch.type != 'g' || ch.y < 0) // upper chord symbol only
continue
if (w0) { // width of the previous chord symbol
if (w0 > x + ch.x) {
if (s.prev // (if not at start of a secondary voice)
&& s.prev.seqst
&& s.prev.type == C.BAR) // don't move away
n-- // the symbol from a bar
dw = (w0 - x - ch.x) / n
while (1) {
s0 = s0.ts_next
if (s0.shrink)
s0.shrink += dw
|
| ︙ | ︙ | |||
668 669 670 671 672 673 674 |
/* -- set the width of a symbol -- */
/* This routine sets the minimal left and right widths wl,wr
* so that successive symbols are still separated when
* no extra glue is put between them */
// (possible hook)
Abc.prototype.set_width = function(s) {
| | | > > > | > | | | > > | 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 |
/* -- set the width of a symbol -- */
/* This routine sets the minimal left and right widths wl,wr
* so that successive symbols are still separated when
* no extra glue is put between them */
// (possible hook)
Abc.prototype.set_width = function(s) {
var s2, i, m, xx, w, wlnote, wlw, acc, nt,
bar_type, meter, last_acc, n1, n2, esp, tmp
if (s.play) { // if play symbol
s.wl = s.wr = 0
return
}
switch (s.type) {
case C.NOTE:
case C.REST:
/* set the note widths */
s.wr = wlnote = hw_tb[s.head]
/* room for shifted heads and accidental signs */
if (s.xmx > 0)
s.wr += s.xmx + 4;
for (s2 = s.prev; s2; s2 = s2.prev) {
if (w_tb[s2.type])
break
}
if (s2) {
switch (s2.type) {
case C.BAR:
case C.CLEF:
case C.KEY:
case C.METER:
wlnote += 3
break
case C.STBRK:
wlnote += 8
break
}
}
for (m = 0; m <= s.nhd; m++) {
nt = s.notes[m]
xx = nt.shhd
if (xx < 0) {
if (wlnote < -xx + 5)
wlnote = -xx + 5
}
acc = nt.acc
if (acc) {
tmp = nt.shac +
(typeof acc == "object" ? 5.5 : 3.5)
if (wlnote < tmp)
wlnote = tmp
}
if (nt.a_dd) // if decoration in chord
wlnote += deco_wch(nt)
}
if (s2) {
switch (s2.type) {
case C.BAR:
case C.CLEF:
case C.KEY:
case C.METER:
|
| ︙ | ︙ | |||
799 800 801 802 803 804 805 | } } /* leave room for guitar chord */ if (s.a_gch) wlw = gchord_width(s, wlnote, wlw) | < | < < | 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 | } } /* leave room for guitar chord */ if (s.a_gch) wlw = gchord_width(s, wlnote, wlw) // ignore the lyrics for now /* if preceeded by a grace note sequence, adjust */ if (s2 && s2.type == C.GRACE) s.wl = wlnote - 4.5 else s.wl = wlw return |
| ︙ | ︙ | |||
824 825 826 827 828 829 830 831 832 833 834 835 836 837 |
s.wl = xx
return
case C.BAR:
bar_type = s.bar_type
switch (bar_type) {
case "|":
w = 5 // 3 + 2
break
default:
w = 2 + 2.8 * bar_type.length
for (i = 0; i < bar_type.length; i++) {
switch (bar_type[i]) {
case "[":
case "]":
| > > > | | | | > > | 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 |
s.wl = xx
return
case C.BAR:
bar_type = s.bar_type
switch (bar_type) {
case "|":
w = 5 // 3 + 2
break
case "[": // repeat number on secondary staff
w = 0
break
default:
w = 2 + 2.8 * bar_type.length
for (i = 0; i < bar_type.length; i++) {
switch (bar_type[i]) {
case "[":
case "]":
w += 1
// fall thru
case ":":
w += 2
break
}
}
break
}
s.wl = w
if (s.next
&& s.next.type != C.METER)
s.wr = 7
else
s.wr = 5
// s.notes[0].shhd = (w - 5) * -.5
/* if preceeded by a grace note sequence, adjust */
for (s2 = s.prev; s2; s2 = s2.prev) {
if (w_tb[s2.type]) {
if (s2.type == C.GRACE)
s.wl -= 6
if (s2.type == C.STBRK)
s.wl -= 12
break
}
}
if (s.a_dd)
s.wl += deco_width(s)
|
| ︙ | ︙ | |||
878 879 880 881 882 883 884 885 886 887 888 |
// (there may be invisible clefs in empty staves)
if (s.invis) {
s.wl = s.wr = 1 // (!! not 0 !!)
return
}
s.wl = s.clef_small ? 11 : 12
s.wr = s.clef_small ? 10 : 12
if (s.next && s.next.type == C.BAR)
s.wr -= 4
return
case C.KEY:
| > > > > | < < | | 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 |
// (there may be invisible clefs in empty staves)
if (s.invis) {
s.wl = s.wr = 1 // (!! not 0 !!)
return
}
s.wl = s.clef_small ? 11 : 12
s.wr = s.clef_small ? 10 : 12
if (s.prev && s.prev.type == C.STBRK) {
s.wl -= 6
delete s.next.clef_small
}
if (s.next && s.next.type == C.BAR)
s.wr -= 4
return
case C.KEY:
if (s.invis) { // if no accidental
s.wl = s.wr = 0 // no width
return
}
s.wl = 3;
esp = 4
if (!s.k_a_acc) {
n1 = s.k_sf /* new key sig */
if (s.k_old_sf && (s.fmt.cancelkey || n1 == 0))
n2 = s.k_old_sf /* old key */
else
n2 = 0
if (n1 * n2 >= 0) { /* if no natural */
if (n1 < 0)
n1 = -n1
if (n2 < 0)
|
| ︙ | ︙ | |||
979 980 981 982 983 984 985 | return case C.GRACE: if (s.invis) break s.wl = set_graceoffs(s); s.wr = 0 if (s.a_ly) | | < < < < | < < | 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 | return case C.GRACE: if (s.invis) break s.wl = set_graceoffs(s); s.wr = 0 if (s.a_ly) ly_set(s) return case C.STBRK: s.wl = s.xmx s.wr = 8 return case C.CUSTOS: s.wl = s.wr = 4 return case C.TEMPO: // no width, but build the tempo string tempo_build(s) break case C.BLOCK: // no width case C.REMARK: case C.STAVES: break default: error(2, s, "set_width - Cannot set width for symbol $1", s.type) break } |
| ︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | i = 2 else if (len >= C.BLEN / 64) i = 1 else i = 0 } l = len - ((C.BLEN / 16 / 8) << i) | | | | | 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
i = 2
else if (len >= C.BLEN / 64)
i = 1
else
i = 0
}
l = len - ((C.BLEN / 16 / 8) << i)
space = cfmt.spatab[i]
if (l) {
if (l < 0) {
space = cfmt.spatab[0] * len / (C.BLEN / 16 / 8)
} else {
if (i >= 9)
i = 8
space += (cfmt.spatab[i + 1] - cfmt.spatab[i]) *
l / ((C.BLEN / 16 / 8) << i)
}
}
return space
}
// set the natural space
|
| ︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 |
case C.MREST:
return s.wl
///*fixme:do same thing at start of line*/
// case C.NOTE:
// case C.REST:
// if (s.ts_prev.type == C.BAR) {
// if (s.nflags < -2)
| | | > > < | 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 |
case C.MREST:
return s.wl
///*fixme:do same thing at start of line*/
// case C.NOTE:
// case C.REST:
// if (s.ts_prev.type == C.BAR) {
// if (s.nflags < -2)
// return cfmt.spatab[0]
// return cfmt.spatab[2]
// }
// break
}
return 0
}
if (s.ts_prev.type == C.MREST)
// return s.ts_prev.wr + 16
// + 3 // (bar wl=5 wr=8)
return 71 // 66 (mrest.wl) + 5 (bar.wl)
space = time2space(s, len)
while (!s.dur) {
switch (s.type) {
case C.BAR:
// (hack to have quite the same note widths between measures)
if (!s.next)
space *= .9
return space * .9 - 7
case C.CLEF:
return space - s.wl - s.wr
case C.BLOCK: // no space
case C.REMARK:
case C.STAVES:
case C.TEMPO:
s = s.ts_next
if (!s)
return space
continue
|
| ︙ | ︙ | |||
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 |
fname: s.fname,
istart: s.istart,
iend: s.iend,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: 0,
nhd: 0,
notes: [{
pit: s.notes ? s.notes[0].pit : 22
}],
| > > > | > < < < | | | | | > > < < | > > > > > | 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 |
fname: s.fname,
istart: s.istart,
iend: s.iend,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: 0,
time: s.time + (s.dur || 0),
nhd: 0,
notes: [{
pit: s.notes ? s.notes[0].pit : 22
}],
seqst: true,
invis: true,
prev: s,
fmt: s.fmt
}
} // _bar()
// create an invisible bar for end of music lines
function add_end_bar(s) {
var b = _bar(s)
b.wl = 0
b.wr = 0
b.ts_prev = s
b.next = s.next
b.ts_next = s.ts_next
b.shrink = s.wr + 3
if (s.next) // (must not be the end of the voice)
s.next.prev = b
// if (s.ts_next)
s.ts_next.ts_prev = b
s.next = s.ts_next = b
b.space = set_space(b, s.time + s.dur * .4)
return b
}
/* -- set the width and space of all symbols -- */
// this function is called once for the whole tune
function set_allsymwidth() {
var val, st, s_chs, stup,
s = tsfirst,
s2 = s,
xa = 0,
xl = [],
wr = [],
maxx = xa,
tim = s.time
/* loop on all symbols */
while (1) {
do {
if ((s.a_gch || s.a_ly) && !s_chs)
s_chs = s;
self.set_width(s);
st = s.st
if (xl[st] == undefined)
xl[st] = 0
if (wr[st] == undefined)
wr[st] = 0;
val = xl[st] + wr[st] + s.wl
if (val > maxx)
maxx = val
s = s.ts_next
} while (s && !s.seqst);
// set the spaces of the time sequence
s2.shrink = maxx - xa
s2.space = s2.ts_prev ? set_space(s2, tim) : 0
// adjust the spacing when after a spacer (y)
if (s2.space == 0 && s2.ts_prev
&& s2.ts_prev.type == C.SPACE && s2.ts_prev.seqst)
s2.space = s2.ts_prev.space /= 2
if (s2.dur && s2.dur != s2.notes[0].dur) {
if (!stup) {
stup = s2
while (stup.prev
&& stup.prev.dur
&& stup.prev.dur != stup.prev.notes[0].dur)
|
| ︙ | ︙ | |||
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
if (s2.wr > wr[st])
wr[st] = s2.wr
s2 = s2.ts_next
} while (!s2.seqst)
}
// let the chord symbols at the same offset
if (s_chs)
set_w_chs(s_chs)
}
// insert a rest, this one replacing a sequence or a measure
function to_rest(so) {
var s = clone(so)
| > | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 |
if (s2.wr > wr[st])
wr[st] = s2.wr
s2 = s2.ts_next
} while (!s2.seqst)
}
// let the chord symbols at the same offset
// and adjust the spacing due to the lyrics
if (s_chs)
set_w_chs(s_chs)
}
// insert a rest, this one replacing a sequence or a measure
function to_rest(so) {
var s = clone(so)
|
| ︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 | p_voice.last_sym = s.prev; // if (!p_voice.last_sym) // p_voice.sym = null; p_voice.time = s.time; new_s = sym_add(p_voice, C.CUSTOS); new_s.next = s; s.prev = new_s; lktsym(new_s, s); new_s.shrink = s.shrink if (new_s.shrink < 8 + 4) new_s.shrink = 8 + 4; new_s.space = s2.space; | > > < < > > | | < | | > > | | | > > > > > > > > > > > > > | 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 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 |
p_voice.last_sym = s.prev;
// if (!p_voice.last_sym)
// p_voice.sym = null;
p_voice.time = s.time;
new_s = sym_add(p_voice, C.CUSTOS);
new_s.next = s;
s.prev = new_s;
new_s.wl = 0 // (needed here for lktsym)
new_s.wr = 4
lktsym(new_s, s);
new_s.shrink = s.shrink
if (new_s.shrink < 8 + 4)
new_s.shrink = 8 + 4;
new_s.space = s2.space;
new_s.head = C.FULL
new_s.stem = s2.stem
new_s.nhd = s2.nhd;
new_s.notes = []
for (i = 0; i < s2.notes.length; i++) {
new_s.notes[i] = {
pit: s2.notes[i].pit,
shhd: 0,
dur: C.BLEN / 4
}
}
new_s.stemless = true
}
/* -- define the beginning of a new music line -- */
function set_nl(s) { // s = start of line
var p_voice, done, tim, ptyp
// divide the left repeat (|:) or variant bars (|1)
// the new bars go in the next line
function bardiv(so) { // start of next line
var s, s1, s2, t1, t2, i, noseq
function new_type(s) {
var t = s.bar_type.match(/(:*)([^:]*)(:*)/)
// [1] = starting ':'s, [2] = middle, [3] = ending ':'s
if (!t[3]) { // if start of variant
// |1 -> | [1
// :|]1 -> :|] [1
t1 = t[1] + t[2]
t2 = '['
} else if (!t[1]) { // if left repeat only
// x|: -> || [|:
t1 = '||'
t2 = '[|' + t[3]
} else {
// :][: -> :|] [|:
i = (t[2].length / 2) | 0
t1 = t[1] + '|' + t[2].slice(0, i)
t2 = t[2].slice(i) +'|' + t[3]
}
} // new_typ()
s = so // start of sequence
while (s.ts_prev
&& s.ts_prev.time == so.time) {
s = s.ts_prev
if (s.bar_type)
s1 = s // first previous bar
if (s.type == C.GRACE)
so = s // keep the grace notes in the next line
}
if (!s1)
return so
// search the insertion point in the new line
for (s = so; ; s = s.ts_next) {
switch (s.type) {
// default:
// if (w_tb[s.type])
// break
case C.KEY:
case C.METER:
case C.CLEF:
continue
}
break
}
if (s.bar_type)
noseq = 1
while (s1 != so) {
if (s1.bar_type
&& (s1.bar_type.slice(-1) == ':'
|| s1.text)
&& s1.bar_type != ':') {
new_type(s1) // return t1 and t2
s2 = clone(s1)
s1.bar_type = t1
delete s1.rbstop
delete s1.a_gch
s2.bar_type = t2
lkvsym(s2, s1.next) // voice
while (1) {
if (s.type != C.BAR
//fixme: pb if inverted voices
|| s.v > s2.v)
break
s = s.ts_next
}
lktsym(s2, s) // time
if (!noseq) {
noseq = 1
s2.seqst = true
s2.shrink = s2.wl + s2.prev.wr
s2.space = 0
}
if (s == so)
so = s2
if (s1.text) {
s2.invis = true
delete s1.text
delete s1.rbstart
}
delete s1.part
delete s2.a_dd
}
s1 = s1.ts_next
}
return so
} // bardiv()
|
| ︙ | ︙ | |||
1668 1669 1670 1671 1672 1673 1674 |
function do_warn(s) { // start of next line
var s1, s2, s3
// advance in the next line
for (s2 = s; s2; s2 = s2.ts_next) {
switch (s2.type) {
case C.KEY:
| | < | < | | 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 |
function do_warn(s) { // start of next line
var s1, s2, s3
// advance in the next line
for (s2 = s; s2; s2 = s2.ts_next) {
switch (s2.type) {
case C.KEY:
if (!s.fmt.keywarn
|| s2.invis)
continue
for (s1 = s.ts_prev; s1 ;s1 = s1.ts_prev) {
if (s1.type != C.METER)
break
}
// fall thru
case C.METER:
if (s2.type == C.METER) {
if (!s.fmt.timewarn)
continue
s1 = s.ts_prev
}
// fall thru
case C.CLEF:
if (!s2.prev) // start of voice
continue
|
| ︙ | ︙ | |||
1704 1705 1706 1707 1708 1709 1710 | } } // put the warning symbol at end of line s3 = clone(s2) // duplicate the K:/M:/clef lktsym(s3, s1.ts_next) // time link | < < > | | < < < < < < < < | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
}
}
// put the warning symbol at end of line
s3 = clone(s2) // duplicate the K:/M:/clef
lktsym(s3, s1.ts_next) // time link
s1 = s3
while (1) {
s1 = s1.ts_next
if (s1.v == s2.v)
break
}
lkvsym(s3, s1) // voice link
// care with spacing
if (s3.seqst) {
s3.shrink = s3.wl
if (s3.prev) // if not start of voice
s3.shrink += s3.prev.wr
s3.space = set_space(s3, s3.ts_prev.time)
s3.next.shrink = s3.wr + s3.next.wl
}
delete s3.part
continue
}
if (w_tb[s2.type])
break // symbol with a width
}
} // do_warn()
// divide the left repeat and variant bars
s = bardiv(s)
// add the warning symbols at the end of the previous line
do_warn(s)
/* if normal symbol, cut here */
if (s.ts_prev.type != C.STAVES) {
set_eol(s)
return s
}
/* go back to handle the staff breaks at end of line */
for (s = s.ts_prev; s; s = s.ts_prev) {
if (s.seqst && s.type != C.CLEF)
|
| ︙ | ︙ | |||
1772 1773 1774 1775 1776 1777 1778 |
switch (s.type) {
case C.STAVES:
if (!s.ts_prev)
return // null // no music yet
if (s.ts_prev.type == C.BAR)
break
while (s.ts_next) {
| | | 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 |
switch (s.type) {
case C.STAVES:
if (!s.ts_prev)
return // null // no music yet
if (s.ts_prev.type == C.BAR)
break
while (s.ts_next) {
if (w_tb[s.ts_next.type]
&& s.ts_next.type != C.CLEF)
break
s = s.ts_next
}
if (!s.ts_next || s.ts_next.type != C.BAR)
continue
s = s.ts_next
|
| ︙ | ︙ | |||
1830 1831 1832 1833 1834 1835 1836 |
// get the width of the symbols up to the next soln or eof
// also, set a x (nice spacing) to all symbols
// two returned values: width of nice spacing, width with max shrinking
function get_width(s, next) {
var shrink, space,
w = 0,
wmx = 0,
| | | | | < | | 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 |
// get the width of the symbols up to the next soln or eof
// also, set a x (nice spacing) to all symbols
// two returned values: width of nice spacing, width with max shrinking
function get_width(s, next) {
var shrink, space,
w = 0,
wmx = 0,
sp_fac = (1 - s.fmt.maxshrink)
while (s != next) {
if (s.seqst) {
shrink = s.shrink
wmx += shrink
if ((space = s.space) < shrink)
w += shrink
else
w += shrink * s.fmt.maxshrink
+ space * sp_fac
s.x = w
}
s = s.ts_next
}
if (next)
wmx += next.wr // big key signatures may be wide enough
return [w, wmx]
}
/* -- search where to cut the lines according to the staff width -- */
function set_lines( s, /* first symbol */
next, /* symbol of the next line / null */
lwidth, /* w - (clef & key sig) */
indent) { /* for start of tune */
var first, s2, s3, s4, x, xmin, xmid, xmax, wwidth, shrink, space,
nlines,
last = next ? next.ts_prev : null,
ws = get_width(s, next) // 2 widths: nice and shrinked
// take care of big key signatures at end of line
if (s.fmt.keywarn && next
&& next.type == C.KEY && !last.dur) {
ws[0] += next.wr
ws[1] += next.wr
}
// check if the symbols can enter in one line
if (ws[1] + indent < lwidth) {
|
| ︙ | ︙ | |||
1889 1890 1891 1892 1893 1894 1895 | return next || last } s2 = first = s; xmin = s.x - s.shrink - indent; xmax = xmin + lwidth; xmid = xmin + wwidth / nlines; | | > | 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 |
return next || last
}
s2 = first = s;
xmin = s.x - s.shrink - indent;
xmax = xmin + lwidth;
xmid = xmin + wwidth / nlines;
xmin += wwidth / nlines * s.fmt.breaklimit;
for (s = s.ts_next; s != next ; s = s.ts_next) {
if (!s.x)
continue
if (s.type == C.BAR)
s2 = s
if (s.x >= xmin)
break
}
s4 = s // keep first symbol with x greater than xmin
//fixme: can this occur?
if (s == next) {
if (next)
next = set_nl(next)
return next
}
|
| ︙ | ︙ | |||
1928 1929 1930 1931 1932 1933 1934 |
if (!s3 || x - xmid < xmid - s3.x)
s3 = s // closest bar after middle
break
}
// no bar, try to avoid to cut a beam or a tuplet */
if (!s3) {
| > > | | < | | | > | > | > > > | | | < | < < < < < < < < | < < < < | > | < | | > > | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 |
if (!s3 || x - xmid < xmid - s3.x)
s3 = s // closest bar after middle
break
}
// no bar, try to avoid to cut a beam or a tuplet */
if (!s3) {
s = s4 // restart after xmin
var beam = 0,
bar_time = s2.time
xmax -= 8; // (left width of the inserted bar in set_allsymwidth)
for ( ; s != next; s = s.ts_next) {
if (s.dur) {
if (!s.beam_end)
beam |= 1 << s.v
else
beam &= ~(1 << s.v)
}
x = s.x
if (!x)
continue
if (x + s.wr >= xmax)
break
if (beam || s.in_tuplet)
continue
if (s3 && s.x >= xmid) {
if (xmid - s3.x > s.x - xmid
|| (s.dur
&& (s.time + s.dur - bar_time)
% (C.BLEN / 4) == 0))
s3 = s
break
}
s3 = s
}
}
// cut anyhere
if (!s3) {
s3 = s = s4
for ( ; s != next; s = s.ts_next) {
x = s.x
if (!x)
continue
if (x + s.wr >= xmax)
break
if (s3 && s.x >= xmid) {
if (xmid - s3.x > s.x - xmid)
s3 = s
break
}
s3 = s
}
}
s = s3
while (s.ts_next) {
s = s.ts_next
if (s.seqst)
break
|
| ︙ | ︙ | |||
2040 2041 2042 2043 2044 2045 2046 | lwidth -= i[0]; indent += i[1] if (cfmt.custos && voice_tb.length == 1) lwidth -= 12 /* if asked, count the measures and set the EOLNs */ | | | | | 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 |
lwidth -= i[0];
indent += i[1]
if (cfmt.custos && voice_tb.length == 1)
lwidth -= 12
/* if asked, count the measures and set the EOLNs */
i = s.fmt.barsperstaff
if (i) {
for (s2 = s; s2; s2 = s2.ts_next) {
if (s2.type != C.BAR
|| !s2.bar_num
|| --i > 0)
continue
while (s2.ts_next && s2.ts_next.type == C.BAR)
s2 = s2.ts_next
if (s2.ts_next)
s2.ts_next.soln = true
i = s.fmt.barsperstaff
}
}
/* cut at explicit end of line, checking the line width */
s2 = s
for ( ; s; s = s.ts_next) {
//fixme: not usable yet
|
| ︙ | ︙ | |||
2078 2079 2080 2081 2082 2083 2084 2085 |
// }
if (!s.ts_next) {
s = null
} else if (!s.soln) {
continue
} else {
s.soln = false
while (!s.seqst)
| > > < < | 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 |
// }
if (!s.ts_next) {
s = null
} else if (!s.soln) {
continue
} else {
s.soln = false
if (s.time == s2.time)
continue // empty music line!
while (!s.seqst)
s = s.ts_prev
}
s2 = set_lines(s2, s, lwidth, indent)
if (!s2)
break
//--fixme
|
| ︙ | ︙ | |||
2178 2179 2180 2181 2182 2183 2184 |
staff_noo = new Int8Array(new Array(m)) // number of ottava values
// add an ottava decoration
function ottava_add(s, ottava, start) {
var dc_st = ["15mb(", "8vb(", null, "8va(", "15ma("],
dc_en = ["15mb)", "8vb)", null, "8va)", "15ma)"];
| | > | 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 |
staff_noo = new Int8Array(new Array(m)) // number of ottava values
// add an ottava decoration
function ottava_add(s, ottava, start) {
var dc_st = ["15mb(", "8vb(", null, "8va(", "15ma("],
dc_en = ["15mb)", "8vb)", null, "8va)", "15ma)"];
a_dcn.push((start ? dc_st : dc_en)[2 + ottava])
deco_cnv(s)
}
for (st = 0; st <= nstaff; st++) {
staff_d[st] = 0;
staff_noo[st] = 0
}
for (s = tsfirst; s; s = s.ts_next) {
|
| ︙ | ︙ | |||
2242 2243 2244 2245 2246 2247 2248 |
// expand the multi-rests as needed
function mrest_expand() {
var s, s2
// expand a multi-rest into a set of rest + bar
function mexp(s) {
| | | | < < < < < | > | | > > > > > > > > > < | | | | > > > | < < < | | 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 |
// expand the multi-rests as needed
function mrest_expand() {
var s, s2
// expand a multi-rest into a set of rest + bar
function mexp(s) {
var bar, s3, s4, tim, nbar,
nb = s.nmes,
dur = s.dur / nb,
s2 = s.next
// get the bar (there may be some other symbols before the bar)
while (!s2.bar_type)
s2 = s2.next
bar = s2
while (!s2.bar_num) // get the bar number
s2 = s2.ts_prev
nbar = s2.bar_num - s.nmes
// change the multi-rest into a single rest
s.type = C.REST
s.notes[0].dur = s.dur = s.dur_orig = dur
s.nflags = -2
s.head = C.FULL
s.fmr = 1 // full measure rest
/* add the bar(s) and rest(s) */
tim = s.time + dur
s3 = s2 = s
while (--nb > 0) {
// add the bar
s2 = clone(bar)
delete s2.soln
delete s2.a_gch
delete s2.a_dd
delete s2.text
delete s2.rbstart
delete s2.rbstop
lkvsym(s2, bar)
s2.time = tim
while (s3.time < tim)
s3 = s3.ts_next // bar at end of measure
while (s3 && s3.v < s.v && s3.type == C.BAR)
s3 = s3.ts_next // keep in order
if (s3) {
lktsym(s2, s3)
|
| ︙ | ︙ | |||
2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 |
if (s4.bar_num && !s4.seqst)
delete s4.bar_num
// add the rest
s4 = clone(s)
delete s4.a_dd
delete s4.soln
if (s2.next) {
s4.next = s2.next
s4.next.prev = s4
} else {
s4.next = null
}
s2.next = s4
| > > | 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 |
if (s4.bar_num && !s4.seqst)
delete s4.bar_num
// add the rest
s4 = clone(s)
delete s4.a_dd
delete s4.soln
delete s4.a_gch
delete s4.part
if (s2.next) {
s4.next = s2.next
s4.next.prev = s4
} else {
s4.next = null
}
s2.next = s4
|
| ︙ | ︙ | |||
2367 2368 2369 2370 2371 2372 2373 |
}
}
} // mrest_expand()
// set the clefs (treble or bass) in a 'auto clef' sequence
// return the starting clef type
function set_auto_clef(st, s_start, clef_type_start) {
| | > > < < | 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 |
}
}
} // mrest_expand()
// set the clefs (treble or bass) in a 'auto clef' sequence
// return the starting clef type
function set_auto_clef(st, s_start, clef_type_start) {
var s, time, s2, s3,
max = 12, /* "F," */
min = 20 /* "G" */
/* get the max and min pitches in the sequence */
for (s = s_start; s; s = s.ts_next) {
if (s.type == C.STAVES && s != s_start)
break
if (s.st != st)
continue
if (s.type != C.NOTE) {
if (s.type == C.CLEF) {
|
| ︙ | ︙ | |||
2438 2439 2440 2441 2442 2443 2444 |
if (s2
&& s2.st == st
&& s2.time == time
&& s2.type == C.NOTE
&& s2.notes[0].pit >= 19) /* F */
continue
} else {
| | | | 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 |
if (s2
&& s2.st == st
&& s2.time == time
&& s2.type == C.NOTE
&& s2.notes[0].pit >= 19) /* F */
continue
} else {
if (s.notes[0].pit <= 12 /* F, */
|| s.notes[s.nhd].pit < 20) { /* G */
if (s.notes[s.nhd].pit <= 12)
s_last_chg = s
continue
}
s2 = s.ts_prev
if (s2
&& s2.time == time
&& s2.st == st
|
| ︙ | ︙ | |||
2513 2514 2515 2516 2517 2518 2519 |
* global variables:
* - staff_tb[st].clef = clefs at start of line (here, start of tune)
* (created here, updated on clef draw)
* - voice_tb[v].clef = clefs at end of generation
* (created on voice creation, updated here)
*/
function set_clefs() {
| | | | | | 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 |
* global variables:
* - staff_tb[st].clef = clefs at start of line (here, start of tune)
* (created here, updated on clef draw)
* - voice_tb[v].clef = clefs at end of generation
* (created on voice creation, updated here)
*/
function set_clefs() {
var s, s2, st, v, p_voice, g, new_type, new_line, p_staff, pit,
staff_clef = new Array(nstaff + 1), // st -> { clef, autoclef }
sy = cur_sy,
mid = []
// create the staff table
staff_tb = new Array(nstaff + 1)
for (st = 0; st <= nstaff; st++) {
staff_clef[st] = {
autoclef: true
}
|
| ︙ | ︙ | |||
2546 2547 2548 2549 2550 2551 2552 | sy.staves[st].staffscale = p_voice.staffscale if (sy.voices[v].sep) sy.staves[st].sep = sy.voices[v].sep if (sy.voices[v].maxsep) sy.staves[st].maxsep = sy.voices[v].maxsep; if (!p_voice.clef.clef_auto) | | | 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 |
sy.staves[st].staffscale = p_voice.staffscale
if (sy.voices[v].sep)
sy.staves[st].sep = sy.voices[v].sep
if (sy.voices[v].maxsep)
sy.staves[st].maxsep = sy.voices[v].maxsep;
if (!p_voice.clef.clef_auto)
delete staff_clef[st].autoclef
}
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!sy.voices[v]
|| sy.voices[v].second) // main voices
continue
|
| ︙ | ︙ | |||
2573 2574 2575 2576 2577 2578 2579 |
for (s = tsfirst; s; s = s.ts_next) {
if (s.repeat_n)
set_repeat(s)
switch (s.type) {
case C.STAVES:
| | | 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 |
for (s = tsfirst; s; s = s.ts_next) {
if (s.repeat_n)
set_repeat(s)
switch (s.type) {
case C.STAVES:
sy = s.sy // new system
for (st = 0; st <= nstaff; st++)
staff_clef[st].autoclef = true
for (v = 0; v < voice_tb.length; v++) {
if (!sy.voices[v])
continue
p_voice = voice_tb[v];
st = sy.voices[v].st
|
| ︙ | ︙ | |||
3023 3024 3025 3026 3027 3028 3029 |
if (i == st_v.length - 1) {
s.multi = -1 /* last voice */
} else {
s.multi = 1 /* first voice(s) */
/* if 3 voices, and vertical space enough,
* have stems down for the middle voice */
| | | | 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 |
if (i == st_v.length - 1) {
s.multi = -1 /* last voice */
} else {
s.multi = 1 /* first voice(s) */
/* if 3 voices, and vertical space enough,
* have stems down for the middle voice */
if (i && i + 2 == st_v.length) {
if (st_v[i].ymn - s.fmt.stemheight
>= st_v[i + 1].ymx)
s.multi = -1;
/* special case for unison */
t = s.ts_next
//fixme: pb with ../lacerda/evol-7.5.5.abc
if (s.ts_prev
|
| ︙ | ︙ | |||
3220 3221 3222 3223 3224 3225 3226 |
p_v.last_sym = s;
lktsym(s, last_s)
}
/* -- init the symbols at start of a music line -- */
function init_music_line() {
| | | | > > > > > | > < | 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 |
p_v.last_sym = s;
lktsym(s, last_s)
}
/* -- init the symbols at start of a music line -- */
function init_music_line() {
var p_voice, s, s1, s2, s3, last_s, v, st, shr, shrmx, shl, fmt,
shlp, p_st, top,
nv = voice_tb.length
/* initialize the voices */
for (v = 0; v < nv; v++) {
if (!cur_sy.voices[v])
continue
p_voice = voice_tb[v];
p_voice.second = cur_sy.voices[v].second;
p_voice.last_sym = p_voice.sym;
/* move the voice to a printed staff */
st = cur_sy.voices[v].st
while (st <= nstaff && !cur_sy.st_print[st])
st++
if (st > nstaff)
continue // no printed staff
p_voice.st = st
if (!p_voice.second) {
staff_tb[st].key = p_voice.ckey
staff_tb[st].meter = p_voice.meter
}
}
// move the first clefs, key signatures and time signatures
// to the staves
s = tsfirst
fmt = s.fmt
while (s) {
switch (s.type) {
case C.CLEF:
case C.KEY:
case C.METER:
switch (s.type) {
case C.CLEF:
staff_tb[s.st].clef = s
break
case C.KEY:
s.p_v.ckey = s
break
case C.METER:
s.p_v.meter = s
insert_meter = cfmt.writefields.indexOf('M') >= 0
&& s.a_meter.length
if (!insert_meter && s.part)
s.next.part = s.part
break
}
unlksym(s)
// fall thru
case C.TEMPO:
case C.BLOCK:
case C.REMARK:
s = s.ts_next
continue
}
break
|
| ︙ | ︙ | |||
3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 |
delete last_s.seqst
}
delete s.clef_small;
s.second = cur_sy.voices[v].second
// (fixme: needed for sample5 X:3 Fugue & staffnonote.xhtml)
if (!cur_sy.st_print[st])
s.invis = true
}
/* add keysig */
for (v = 0; v < nv; v++) {
if (!cur_sy.voices[v]
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
p_voice = voice_tb[v]
s2 = p_voice.ckey
if (s2.k_sf || s2.k_a_acc) {
s = clone(s2)
new_sym(s, p_voice, last_s)
delete s.invis
s.k_old_sf = s2.k_sf // no key cancel
}
}
/* add time signature (meter) if needed */
| > > | | | > | | > | < | | < < < < | < < < < < > | 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 |
delete last_s.seqst
}
delete s.clef_small;
s.second = cur_sy.voices[v].second
// (fixme: needed for sample5 X:3 Fugue & staffnonote.xhtml)
if (!cur_sy.st_print[st])
s.invis = true
s.fmt = fmt
}
/* add keysig */
for (v = 0; v < nv; v++) {
if (!cur_sy.voices[v]
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
p_voice = voice_tb[v]
s2 = p_voice.ckey
if (s2.k_sf || s2.k_a_acc) {
s = clone(s2)
new_sym(s, p_voice, last_s)
delete s.invis
s.k_old_sf = s2.k_sf // no key cancel
s.fmt = fmt
}
}
/* add time signature (meter) if needed */
if (insert_meter) {
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v];
s2 = p_voice.meter
if (!cur_sy.voices[v]
|| cur_sy.voices[v].second
|| !cur_sy.st_print[cur_sy.voices[v].st])
// || !s2.a_meter.length)
continue
s = clone(s2)
new_sym(s, p_voice, last_s)
s.fmt = fmt
}
insert_meter = false // no meter any more
}
// add an invisible bar for the various continued elements
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (p_voice.sls.length) {
s = {
type: C.BAR,
fname: last_s.fname,
bar_type: "|",
dur: 0,
multi: 0,
invis: true,
sls: p_voice.sls,
fmt: fmt
}
new_sym(s, p_voice, last_s)
p_voice.sls = []
}
}
// add a bar for the continuation of repeat brackets
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v];
s2 = p_voice.bar_start;
p_voice.bar_start = null
// check if bracket stop at this time
for (s = last_s; s && s.time == last_s.time; s = s.ts_next) {
if (s.rbstop) {
s2 = null
break
}
}
if (!s2)
continue
if (!cur_sy.voices[v]
|| !cur_sy.st_print[cur_sy.voices[v].st])
continue
if (p_voice.last_sym.type == C.BAR) {
if (!p_voice.last_sym.rbstop)
p_voice.last_sym.rbstart = 1
} else {
new_sym(s2, p_voice, last_s)
s2.fmt = fmt
}
}
// compute the spacing of the added symbols
self.set_pitch(last_s);
s = tsfirst
|
| ︙ | ︙ | |||
3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 |
if (s == last_s)
break
shlp = shl
}
// update the spacing before the first old time sequence
shr = 0
do {
self.set_width(s)
if (shr < s.wl)
shr = s.wl;
s = s.ts_next
} while (s && !s.seqst);
last_s.shrink = shl + shr
last_s.space = 0
} // init_music_line()
// check if the tune ends on a measure bar
function check_end_bar() {
var s2,
s = tsfirst
while (s.ts_next)
s = s.ts_next
if (s.type != C.BAR) {
s2 = _bar(s)
| > > > > < < < | 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 |
if (s == last_s)
break
shlp = shl
}
// update the spacing before the first old time sequence
shr = 0
if (last_s.type == C.BAR && s2.type == C.CLEF)
shl += 4 // (see set_width)
do {
self.set_width(s)
if (s.a_ly)
ly_set(s)
if (shr < s.wl)
shr = s.wl;
s = s.ts_next
} while (s && !s.seqst);
last_s.shrink = shl + shr
last_s.space = 0
} // init_music_line()
// check if the tune ends on a measure bar
function check_end_bar() {
var s2,
s = tsfirst
while (s.ts_next)
s = s.ts_next
if (s.type != C.BAR) {
s2 = _bar(s)
s2.ts_prev = s
s.next = s.ts_next = s2
}
} // check_end_bar()
/* -- set a pitch in all symbols and the start/stop of the beams -- */
|
| ︙ | ︙ | |||
3487 3488 3489 3490 3491 3492 3493 |
if (s.a_gch)
self.gch_build(s)
switch (s.type) {
case C.MREST:
start_flag = true
break
case C.BAR:
| > > | | 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 |
if (s.a_gch)
self.gch_build(s)
switch (s.type) {
case C.MREST:
start_flag = true
break
case C.BAR:
res = s.fmt.bardef[s.bar_type]
if (res)
s.bar_type = res
if (!s.beam_on)
start_flag = true
if (!s.next && s.prev
&& !s.invis
&& s.prev.head == C.OVALBARS)
s.prev.head = C.SQUARE
break
|
| ︙ | ︙ | |||
3551 3552 3553 3554 3555 3556 3557 |
if (start_flag
|| nflags <= 0) {
if (lastnote) {
lastnote.beam_end = true;
lastnote = null
}
if (nflags <= 0) {
| | < | 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 |
if (start_flag
|| nflags <= 0) {
if (lastnote) {
lastnote.beam_end = true;
lastnote = null
}
if (nflags <= 0) {
s.beam_st = s.beam_end = true
} else if (s.type == C.NOTE || s.beam_on) {
s.beam_st = true;
start_flag = false
}
}
if (s.beam_end)
start_flag = true
|
| ︙ | ︙ | |||
3605 3606 3607 3608 3609 3610 3611 |
continue
}
n = 0;
s2 = null
for (s = s.next; s; s = s.next) {
if (s.type != C.BAR)
continue
| < > | | > > | 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 |
continue
}
n = 0;
s2 = null
for (s = s.next; s; s = s.next) {
if (s.type != C.BAR)
continue
if (s.rbstop)
break
if (!s.next) {
s.rbstop = 2 // right repeat with end
break
}
n++
if (n == s.fmt.rbmin)
s2 = s
if (n == s.fmt.rbmax) {
if (s2)
s = s2;
s.rbstop = 1 // right repeat without end
break
}
}
}
}
/* -- initialize the generator -- */
// this function is called only once per tune
var delpit = [0, -7, -14, 0]
function set_global() {
var p_voice, v,
nv = voice_tb.length,
sy = cur_sy,
st = sy.nstaff
insert_meter = cfmt.writefields.indexOf('M') >= 0
/* get the max number of staves */
while (1) {
sy = sy.next
if (!sy)
break
if (sy.nstaff > st)
|
| ︙ | ︙ | |||
3766 3767 3768 3769 3770 3771 3772 |
/* notes in a beam have the same stem direction */
if (beam) {
s.stem = laststem
} else if (s.beam_st && !s.beam_end) { // beam start
beam = true;
| < < < < < < < < < < < < < < < < < < < < | < < < < < < | < < < | < < < > > | < | < < | | | < < | 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 |
/* notes in a beam have the same stem direction */
if (beam) {
s.stem = laststem
} else if (s.beam_st && !s.beam_end) { // beam start
beam = true;
// the stem direction is the one of the note
// farthest from the middle line
pu = s.notes[s.nhd].pit;
pd = s.notes[0].pit
for (g = s.next; g; g = g.next) {
if (g.type != C.NOTE)
continue
if (g.stem || g.multi) // if forced direction
s.stem = g.stem || g.multi
if (g.notes[g.nhd].pit > pu)
pu = g.notes[g.nhd].pit
if (g.notes[0].pit < pd)
pd = g.notes[0].pit
if (g.beam_end)
break
}
if (!s.stem && g.beam_end) {
if (pu + pd < mid_p * 2) {
s.stem = 1
} else if (pu + pd > mid_p * 2) {
s.stem = -1
} else {
if (s.fmt.bstemdown)
s.stem = -1
}
}
if (!s.stem)
s.stem = laststem
} else { // no beam
n = (s.notes[s.nhd].pit + s.notes[0].pit) / 2
if (n == mid_p && s.nhd > 1) {
for (m = 0; m < s.nhd; m++) {
if (s.notes[m].pit >= mid_p)
break
}
n = m * 2 < s.nhd ? mid_p - 1 : mid_p + 1
}
if (n < mid_p)
s.stem = 1
else if (n > mid_p || s.fmt.bstemdown)
s.stem = -1
else
s.stem = laststem
}
} else { /* stem set by set_stem_dir */
if (s.beam_st && !s.beam_end)
beam = true
|
| ︙ | ︙ | |||
3864 3865 3866 3867 3868 3869 3870 |
s_opp = null
}
}
}
// check if there may be one head for unison when voice overlap
function same_head(s1, s2) {
| | > | | | 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 |
s_opp = null
}
}
}
// check if there may be one head for unison when voice overlap
function same_head(s1, s2) {
var i1, i2, l1, l2, head, i11, i12, i21, i22, sh1, sh2,
shu = s1.fmt.shiftunison || 0
if (shu >= 3)
return false
if ((l1 = s1.dur) >= C.BLEN)
return false
if ((l2 = s2.dur) >= C.BLEN)
return false
if (s1.stemless && s2.stemless)
return false
if (s1.dots != s2.dots) {
if (shu & 1
|| s1.dots * s2.dots != 0)
return false
}
if (s1.stem * s2.stem > 0)
return false
/* check if a common unison */
|
| ︙ | ︙ | |||
3955 3956 3957 3958 3959 3960 3961 |
}
if (l1 < C.BLEN / 2) {
if (s2.dots)
head = 2
else if (s1.dots)
head = 1
} else if (l2 < C.BLEN / 4) { /* (l1 >= C.BLEN / 2) */
| | | | 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 |
}
if (l1 < C.BLEN / 2) {
if (s2.dots)
head = 2
else if (s1.dots)
head = 1
} else if (l2 < C.BLEN / 4) { /* (l1 >= C.BLEN / 2) */
// if (shu == 2)
// || s1.dots != s2.dots)
if (shu & 2)
return false
head = s2.dur >= C.BLEN / 2 ? 2 : 1
} else {
return false
}
}
if (!head)
|
| ︙ | ︙ | |||
3992 3993 3994 3995 3996 3997 3998 |
function unison_acc(s1, s2, i1, i2) {
var m, d, acc
acc = s2.notes[i2].acc
if (!acc) {
d = w_note[s2.head] * 2 + s2.xmx + s1.notes[i1].shac + 2
acc = s1.notes[i1].acc
| | | | 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 |
function unison_acc(s1, s2, i1, i2) {
var m, d, acc
acc = s2.notes[i2].acc
if (!acc) {
d = w_note[s2.head] * 2 + s2.xmx + s1.notes[i1].shac + 2
acc = s1.notes[i1].acc
if (typeof acc == "object") // microtone
d += 2
if (s2.dots)
d += 6
for (m = 0; m <= s1.nhd; m++) {
s1.notes[m].shhd += d;
s1.notes[m].shac -= d
}
s1.xmx += d
} else {
d = w_note[s1.head] * 2 + s1.xmx + s2.notes[i2].shac + 2
if (typeof acc == "object") // microtone
d += 2
if (s1.dots)
d += 6
for (m = 0; m <= s2.nhd; m++) {
s2.notes[m].shhd += d;
s2.notes[m].shac -= d
}
|
| ︙ | ︙ | |||
4293 4294 4295 4296 4297 4298 4299 | case 1: if (s1.notes[i1].pit & 1) s2.dot_low = true else s1.dot_low = false break case 0: | | < | 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 |
case 1:
if (s1.notes[i1].pit & 1)
s2.dot_low = true
else
s1.dot_low = false
break
case 0:
if (s1.notes[i1].acc != s2.notes[i2].acc) {
t = -1
break
}
if (s2.notes[i2].acc) {
if (!s1.notes[i1].acc)
s1.notes[i1].acc = s2.notes[i2].acc
s2.notes[i2].acc = 0
|
| ︙ | ︙ | |||
4512 4513 4514 4515 4516 4517 4518 | } /* if (s2) */ if (s2.nflags > nflags) nflags = s2.nflags } /* set height of stem end */ | | | 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 |
}
/* if (s2) */
if (s2.nflags > nflags)
nflags = s2.nflags
}
/* set height of stem end */
slen = s.fmt.stemheight
switch (nflags) {
case 2: slen += 0; break
case 3: slen += 4; break
case 4: slen += 8; break
case 5: slen += 12; break
}
if ((scale = s.p_v.scale) != 1)
|
| ︙ | ︙ | |||
4603 4604 4605 4606 4607 4608 4609 |
switch (s.subtype) {
case "leftmargin":
case "rightmargin":
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
| < | 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 |
switch (s.subtype) {
case "leftmargin":
case "rightmargin":
case "pagescale":
case "pagewidth":
case "scale":
case "staffwidth":
self.set_format(s.subtype, s.param)
break
case "mc_start": // multicol start
multicol = {
posy: posy,
maxy: posy,
lmarg: cfmt.leftmargin,
|
| ︙ | ︙ | |||
4646 4647 4648 4649 4650 4651 4652 | set_page() break case "ml": blk_flush() user.img_out(s.text) break case "newpage": | < > > | 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 |
set_page()
break
case "ml":
blk_flush()
user.img_out(s.text)
break
case "newpage":
if (!user.page_format)
break
blk_flush()
if (blkdiv < 0) // split the tune
user.img_out('</div>')
blkdiv = 2 // start the next SVG in a new page
break
case "sep":
set_page();
vskip(s.sk1);
output += '<path class="stroke"\n\td="M';
out_sxsy((img.width -s.l) / 2 - img.lm, ' ', 0)
output += 'h' + s.l.toFixed(1) + '"/>\n';
vskip(s.sk2);
break
case "text":
set_font(s.font)
use_font(s.font)
write_text(s.text, s.opt)
break
case "title":
write_title(s.text, true)
break
case "vskip":
vskip(s.sk);
|
| ︙ | ︙ | |||
4761 4762 4763 4764 4765 4766 4767 | p_staff.botbar -= 12; p_staff.topbar += 12 continue // no helper line } } // define the helper lines | | | 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 |
p_staff.botbar -= 12;
p_staff.topbar += 12
continue // no helper line
}
}
// define the helper lines
p_staff.hll = 17 + i * 2 // pitch of lowest note
// without helper line
// ('D' when standard staff)
p_staff.hlmap = new Int8Array(new Array((l - i + 1) * 2))
for (j = 1; i < l; i++, j += 2) {
switch (p_staff.stafflines[i]) {
case '|':
case '[':
|
| ︙ | ︙ | |||
4817 4818 4819 4820 4821 4822 4823 |
continue
// the block symbols will be treated after music line generation
case C.BLOCK:
if (!s.play) {
blocks.push(s)
unlksym(s)
| | > | 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 |
continue
// the block symbols will be treated after music line generation
case C.BLOCK:
if (!s.play) {
blocks.push(s)
unlksym(s)
} else if (s.ts_next && s.ts_next.shrink)
s.ts_next.shrink = 0
continue
}
st = s.st
if (st > nstaff) {
switch (s.type) {
case C.CLEF:
staff_tb[st].clef = s // clef warning/change for new staff
|
| ︙ | ︙ | |||
4922 4923 4924 4925 4926 4927 4928 |
}
}
}
/* -- position the symbols along the staff -- */
// (possible hook)
Abc.prototype.set_sym_glue = function(width) {
| | < | 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 |
}
}
}
/* -- position the symbols along the staff -- */
// (possible hook)
Abc.prototype.set_sym_glue = function(width) {
var s, g, ll, x,
some_grace,
spf, // spacing factor
xmin = 0, // sigma shrink = minimum spacing
xx = 0, // sigma natural spacing
xs = 0, // sigma unexpandable elements with no space
xse = 0 // sigma unexpandable elements with space
/* calculate the whole space of the symbols */
for (s = tsfirst; s; s = s.ts_next) {
if (s.type == C.GRACE && !some_grace)
some_grace = s
|
| ︙ | ︙ | |||
4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 |
// last line?
ll = !tsnext || // yes
(tsnext.type == C.BLOCK // no, but followed by %%command
&& !tsnext.play)
|| blocks.length // (abcm2ps compatibility)
// strong shrink
if (xmin >= width) {
if (xmin > width)
error(1, s, "Line too much shrunk $1 $2 $3",
xmin.toFixed(1),
xx.toFixed(1),
width.toFixed(1));
x = 0
| > | | | | 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 |
// last line?
ll = !tsnext || // yes
(tsnext.type == C.BLOCK // no, but followed by %%command
&& !tsnext.play)
|| blocks.length // (abcm2ps compatibility)
// strong shrink
s = tsfirst
if (xmin >= width) {
if (xmin > width)
error(1, s, "Line too much shrunk $1 $2 $3",
xmin.toFixed(1),
xx.toFixed(1),
width.toFixed(1));
x = 0
for ( ; s; s = s.ts_next) {
if (s.seqst)
x += s.shrink;
s.x = x
}
// realwidth = width
spf_last = 0
} else if ((ll && xx + xs > width * (1 - s.fmt.stretchlast))
|| (!ll && (xx + xs > width || s.fmt.stretchstaff))) {
if (xx == xse) // if no space
xx += 5
for (var cnt = 4; --cnt >= 0; ) {
spf = (width - xs - xse) / (xx - xse);
xx = 0;
xse = 0;
x = 0
|
| ︙ | ︙ | |||
5008 5009 5010 5011 5012 5013 5014 |
s.x = x
}
if (Math.abs(x - width) < 0.1)
break
}
spf_last = spf
} else { // shorter line
| | | > | | | > | 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 |
s.x = x
}
if (Math.abs(x - width) < 0.1)
break
}
spf_last = spf
} else { // shorter line
spf = 1 - s.fmt.maxshrink
if (spf_last && xx * spf_last + xs < width)
spf = spf_last
x = 0
for ( ; s; s = s.ts_next) {
if (s.seqst)
x += s.space <= s.shrink ?
s.shrink :
s.shrink * (1 - spf) + s.space * spf
s.x = x
}
}
realwidth = x
/* set the x offsets of the grace notes */
for (s = some_grace; s; s = s.ts_next) {
|
| ︙ | ︙ | |||
5104 5105 5106 5107 5108 5109 5110 |
/* -- generate the music -- */
// (possible hook)
Abc.prototype.output_music = function() {
var v, lwidth, indent, line_height, ts1st, tslast, p_v,
nv = voice_tb.length
| < < < > > > > > > < < < | 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 |
/* -- generate the music -- */
// (possible hook)
Abc.prototype.output_music = function() {
var v, lwidth, indent, line_height, ts1st, tslast, p_v,
nv = voice_tb.length
set_global()
if (nv > 1) // if many voices
self.set_stem_dir() // set the stems direction in 'multi'
for (v = 0; v < nv; v++)
set_beams(voice_tb[v].sym); /* decide on beams */
self.set_stems() // set the stem lengths
gen_init() // output the blocks and define the page layout
if (!tsfirst)
return
set_acc_shft() // set the horizontal offset of accidentals
if (nv > 1) { // if many voices
set_rest_offset(); /* set the vertical offset of rests */
set_overlap(); /* shift the notes on voice overlap */
}
set_allsymwidth(); /* set the width of all symbols */
indent = set_indent(true)
/* if single line, adjust the page width */
if (cfmt.singleline) {
v = get_ck_width();
|
| ︙ | ︙ | |||
5144 5145 5146 5147 5148 5149 5150 | // save symbol pointers for play ts1st = tsfirst v = nv while (--v >= 0) voice_tb[v].osym = voice_tb[v].sym | | | < < | 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 |
// save symbol pointers for play
ts1st = tsfirst
v = nv
while (--v >= 0)
voice_tb[v].osym = voice_tb[v].sym
spf_last = 0 // last spacing factor
while (1) { /* loop per music line */
set_piece();
self.set_sym_glue(lwidth - indent)
if (realwidth) {
if (indent)
posx += indent;
draw_sym_near(); // delayed output
line_height = set_staff();
draw_systems(indent);
draw_all_sym();
delayed_update();
vskip(line_height)
if (indent)
posx -= indent;
while (blocks.length)
self.block_gen(blocks.shift())
}
blk_flush()
if (tslast)
tslast.ts_next.ts_prev = tslast
|
| ︙ | ︙ | |||
5194 5195 5196 5197 5198 5199 5200 |
while (--v >= 0) {
p_v = voice_tb[v]
if (p_v.sym && p_v.s_prev)
p_v.sym.prev = p_v.s_prev
p_v.sym = p_v.osym
}
}
| < < < < < < < | 5192 5193 5194 5195 5196 5197 5198 |
while (--v >= 0) {
p_v = voice_tb[v]
if (p_v.sym && p_v.s_prev)
p_v.sym.prev = p_v.s_prev
p_v.sym = p_v.osym
}
}
|
Changes to core/parse.js.
1 2 | // abc2svg - parse.js - ABC parse // | | | | 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 |
// abc2svg - parse.js - ABC parse
//
// Copyright (C) 2014-2021 Jean-Francois Moine
//
// This file is part of abc2svg-core.
//
// abc2svg-core is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg-core is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>.
var a_gch, // array of parsed guitar chords
a_dcn = [], // array of parsed decoration names
multicol, // multi column object
maps = {} // maps object - see set_map()
var qplet_tb = new Int8Array([ 0, 1, 3, 2, 3, 0, 2, 0, 3, 0 ]),
ntb = "CDEFGABcdefgab"
// set the source references of a symbol
function set_ref(s) {
|
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
curvoice.ckey.k_drum = true // no transpose
break
default:
syntax(1, "Unknown clef '$1'", clef_def)
return //undefined
}
if (clef_def[i] >= '1' && clef_def[i] <= '9') {
| | > > > | > | | | | | | | 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 |
curvoice.ckey.k_drum = true // no transpose
break
default:
syntax(1, "Unknown clef '$1'", clef_def)
return //undefined
}
if (clef_def[i] >= '1' && clef_def[i] <= '9') {
s.clef_line = +clef_def[i]
i++
}
// handle the octave (+/-8 - ^/_8)
delete curvoice.snd_oct
if (clef_def[i + 1] != '8'
&& clef_def[i + 1] != '1')
return s
switch (clef_def[i]) { // octave
case '^':
s.clef_oct_transp = true
case '+':
s.clef_octave = clef_def[i + 1] == '8' ? 7 : 14
if (!s.clef_oct_transp) // MIDI higher octave
curvoice.snd_oct = clef_def[i + 1] == 8 ? 12 : 24
break
case '_':
s.clef_oct_transp = true
case '-':
s.clef_octave = clef_def[i + 1] == '8' ? -7 : -14
if (!s.clef_oct_transp) // MIDI lower octave
curvoice.snd_oct = clef_def[i + 1] == 8 ? -12 : -24
break
}
return s
}
// convert an interval to a base-40 interval
function get_interval(param, score) {
|
| ︙ | ︙ | |||
138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
if (!note) {
if (i != 1 || !score) {
syntax(1, errs.bad_transp)
return
}
pit[i] = 242 // 'c' (C5)
} else {
pit[i] = abc2svg.pab40(note.pit, note.acc)
}
}
return pit[1] - pit[0]
}
// set the linebreak character
| > > > > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
if (!note) {
if (i != 1 || !score) {
syntax(1, errs.bad_transp)
return
}
pit[i] = 242 // 'c' (C5)
} else {
if (typeof note.acc == "object") {
syntax(1, errs.bad_transp)
return
}
pit[i] = abc2svg.pab40(note.pit, note.acc)
}
}
return pit[1] - pit[0]
}
// set the linebreak character
|
| ︙ | ︙ | |||
238 239 240 241 242 243 244 |
// get a stafflines value
function get_st_lines(param) {
if (!param)
return
if (/^[\]\[|.-]+$/.test(param))
return param.replace(/\]/g, '[')
| | < < | | 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 |
// get a stafflines value
function get_st_lines(param) {
if (!param)
return
if (/^[\]\[|.-]+$/.test(param))
return param.replace(/\]/g, '[')
var n = +param
switch (n) {
case 0: return "..."
case 1: return "..|"
case 2: return ".||"
case 3: return ".|||"
}
if (isNaN(n) || n < 0 || n > 16)
return //undefined
return "||||||||||||||||".slice(0, n)
}
// create a block symbol in the tune body
function new_block(subtype) {
var s = {
type: C.BLOCK,
subtype: subtype,
dur: 0
}
if (subtype.slice(0, 4) != "midi") // if not a play command
curvoice = voice_tb[0] // set the block in the first voice
sym_link(s)
return s
}
// set the voice parameters
// (possible hook)
Abc.prototype.set_vp = function(a) {
var s, item, pos, val, clefpit, tr_p
while (1) {
item = a.shift()
if (!item)
break
if (item.slice(-1) == '='
&& !a.length) {
|
| ︙ | ︙ | |||
306 307 308 309 310 311 312 | clefpit = 4 - val // 4 = 'G' break } } syntax(1, errs.bad_val, item) break case "octave=": | | | > > | > > > > | < > > > | | > > | > > > > > | > > | > > > > | > > > > > | | > | | > | 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 |
clefpit = 4 - val // 4 = 'G'
break
}
}
syntax(1, errs.bad_val, item)
break
case "octave=":
val = +a.shift()
if (isNaN(val))
syntax(1, errs.bad_val, item)
else
curvoice.octave = val
break
case "cue=":
curvoice.scale = a.shift() == 'on' ? .7 : 1
break
case "instrument=":
// instrument=M/N => score=MN and sound=cN
// (instrument=M == instrument=M/M)
item = a.shift()
val = item.indexOf('/')
if (val < 0) {
val = get_interval('c' + item)
if (val == undefined)
break
curvoice.sndtran = val
val = 0
} else {
val = get_interval('c' + item.slice(val + 1))
if (val == undefined)
break
curvoice.sndtran = val
val = get_interval(item.replace('/', ''))
if (val == undefined)
break
}
curvoice.transp = cfmt.sound ? curvoice.sndtran : val
tr_p = 1
break
case "map=": // %%voicemap
curvoice.map = a.shift()
break
case "name=":
case "nm=":
curvoice.nm = a.shift()
if (curvoice.nm[0] == '"')
curvoice.nm = cnv_escape(curvoice.nm.slice(1, -1))
curvoice.new_name = true
break
case "stem=": // compatibility
case "pos=": // from %%pos only
if (item == "pos=")
item = a.shift()
.slice(1, -1) // always inside dble quotes
.split(' ')
else
item = ["stm", a.shift()];
val = posval[item[1]]
if (val == undefined) {
syntax(1, errs.bad_val, "%%pos")
break
}
switch (item[2]) {
case "align": val |= C.SL_ALIGN; break
case "center": val |= C.SL_CENTER; break
case "close": val |= C.SL_CLOSE; break
}
if (!pos)
pos = {}
pos[item[0]] = val
break
case "scale=": // %%voicescale
val = +a.shift()
if (isNaN(val) || val < .5 || val > 2)
syntax(1, errs.bad_val, "%%voicescale")
else
curvoice.scale = val
break
case "score=":
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
// score=MN
// (score=M == score=Mc)
item = a.shift()
if (cfmt.sound)
break
val = get_interval(item, true)
if (val != undefined) {
curvoice.transp = val
tr_p = 1
}
break
case "shift=":
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
val = get_interval(a.shift())
if (val != undefined) {
curvoice.shift = curvoice.sndsh = val
tr_p = 1
}
break
case "sound=":
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
// concert-score display: apply sound=
// sounding-score display: apply sound= only if M != c/C
// sound: apply sound=
val = get_interval(a.shift())
if (val == undefined)
break
curvoice.sndtran = val
if (cfmt.sound)
curvoice.transp = val
tr_p = 1
break
case "subname=":
case "sname=":
case "snm=":
curvoice.snm = a.shift()
if (curvoice.snm[0] == '"')
curvoice.snm = curvoice.snm.slice(1, -1);
break
case "stafflines=":
val = get_st_lines(a.shift())
if (val == undefined)
syntax(1, "Bad %%stafflines value")
else if (curvoice.st != undefined)
par_sy.staves[curvoice.st].stafflines = val
else
curvoice.stafflines = val
break
case "staffnonote=":
val = +a.shift()
if (isNaN(val))
syntax(1, "Bad %%staffnonote value")
else
curvoice.staffnonote = val
break
case "staffscale=":
val = +a.shift()
if (isNaN(val) || val < .3 || val > 2)
syntax(1, "Bad %%staffscale value")
else
curvoice.staffscale = val
break
case "transpose=": // (abcMIDI compatibility)
if (cfmt.nedo) {
syntax(1, errs.notransp)
break
}
val = get_transp(a.shift())
if (val == undefined) {
syntax(1, errs.bad_transp)
} else {
curvoice.sndtran = val
if (cfmt.sound)
curvoice.transp = val
tr_p = 1
}
break
default:
switch (item.slice(0, 4)) {
case "treb":
case "bass":
case "alto":
|
| ︙ | ︙ | |||
472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
s = new_clef(s)
if (s) {
if (clefpit)
s.clefpit = clefpit
get_clef(s)
}
}
} // set_vp()
// set the K: / V: parameters
function set_kv_parm(a) { // array of items
if (!curvoice.init) { // add the global parameters if not done yet
curvoice.init = true
if (info.V) {
| > > | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
s = new_clef(s)
if (s) {
if (clefpit)
s.clefpit = clefpit
get_clef(s)
}
}
if (tr_p)
set_transp()
} // set_vp()
// set the K: / V: parameters
function set_kv_parm(a) { // array of items
if (!curvoice.init) { // add the global parameters if not done yet
curvoice.init = true
if (info.V) {
|
| ︙ | ︙ | |||
562 563 564 565 566 567 568 569 570 |
set_ref(s);
// tonic
i = 1
if (sf < -1) {
switch (param[0]) {
case 'H': // bagpipe
if (param[1].toLowerCase() != 'p') {
syntax(1, "Unknown bagpipe-like key")
| > < > < < < | | | | | | | | 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 |
set_ref(s);
// tonic
i = 1
if (sf < -1) {
switch (param[0]) {
case 'H': // bagpipe
key_end = true
if (param[1].toLowerCase() != 'p') {
syntax(1, "Unknown bagpipe-like key")
break
}
s.k_bagpipe = param[1];
sf = param[1] == 'P' ? 0 : 2;
i++
// initialize the temperament if not done yet
if (!cfmt.temper)
// detune in cents for just intonation in A
// (from https://patrickmclaurin.com/wordpress/?page_id=2420)
// C ^C D _E E F ^F G _A A _B B
// 15.3 -14.0 -2.0 -10.0 1.9 13.3 -16.0 -31.8 -12.0 0.0 11.4 3.8
// but 'A' bagpipe = 480Hz => raise Math.log2(480/440)*1200 = 151
cfmt.temper = new Float32Array([
// 1.66, 1.37, 1.49, 1.41, 1.53, 1.63, 1.35, 1.19, 1.39, 1.51, 1.62, 1.55
// C ^C D _E E F ^F G _A A _B B
11.62, 12.55,
1.66, 2.37, 3.49, 0,
1.66, 2.37, 3.49, 4.41, 5.53, 0,
3.49, 4.41, 5.53, 6.63, 7.35,
4.41, 5.53, 6.63, 7.35, 8.19, 0,
6.63, 7.35, 8.19, 9.39, 10.51, 0,
8.19, 9.39, 10.51, 11.62, 12.55, 0,
10.51, 11.62, 12.55,
1.66, 1.66
])
break
case 'P':
syntax(1, "K:P is deprecated");
sf = 0;
s.k_drum = true;
key_end = true
|
| ︙ | ︙ | |||
697 698 699 700 701 702 703 |
s.k_map = []
i = s.k_a_acc.length
while (--i >= 0) {
note = s.k_a_acc[i]
s.k_map[(note.pit + 19) % 7] = note.acc
}
} else {
| > > | > > | | 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 |
s.k_map = []
i = s.k_a_acc.length
while (--i >= 0) {
note = s.k_a_acc[i]
s.k_map[(note.pit + 19) % 7] = note.acc
}
} else {
s.k_map = s.k_bagpipe && !sf
? abc2svg.keys[9] // implicit F# and C#
: abc2svg.keys[sf + 7]
}
s.k_mode = mode
// key note as base-40
s.k_b40 = [1,24,7,30,13,36,19, 2 ,25,8,31,14,37,20,3][sf + 7]
return [s, info_split(param)]
}
// M: meter
function new_meter(p) {
var p_v,
s = {
type: C.METER,
dur: 0,
a_meter: []
},
meter = {},
val, v,
m1 = 0, m2,
|
| ︙ | ︙ | |||
823 824 825 826 827 828 829 |
if (p[i] != ' ' && p[i] != '+')
break
if (i >= p.length
|| p[i + 1] == '(') /* "M:5 (2/4+3/4)" */
break
meter.top += p[i++]
}
| | | | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 |
if (p[i] != ' ' && p[i] != '+')
break
if (i >= p.length
|| p[i + 1] == '(') /* "M:5 (2/4+3/4)" */
break
meter.top += p[i++]
}
m1 = +meter.top
break
}
if (!in_parenth) {
if (meter.bot)
m2 = +meter.bot
wmeasure += m1 * C.BLEN / m2
}
s.a_meter.push(meter);
meter = {}
while (p[i] == ' ')
i++
if (p[i] == '+') {
|
| ︙ | ︙ | |||
858 859 860 861 862 863 864 |
if (cfmt.writefields.indexOf('M') < 0)
s.a_meter = []
if (parse.state != 3) {
info.M = p;
glovar.meter = s
| | | | < | | > > > | | | 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 |
if (cfmt.writefields.indexOf('M') < 0)
s.a_meter = []
if (parse.state != 3) {
info.M = p;
glovar.meter = s
if (parse.state) {
/* in the tune header, change the unit note length */
if (!glovar.ulen) {
if (wmeasure <= 1
|| wmeasure >= C.BLEN * 3 / 4)
glovar.ulen = C.BLEN / 8
else
glovar.ulen = C.BLEN / 16
}
for (v = 0; v < voice_tb.length; v++) {
voice_tb[v].meter = s;
voice_tb[v].wmeasure = wmeasure
}
}
} else {
curvoice.wmeasure = wmeasure
if (is_voice_sig())
curvoice.meter = s
else
sym_link(s)
// set the meter of the overlay voices
for (p_v = curvoice.voice_down; p_v; p_v = p_v.voice_down)
p_v.wmeasure = wmeasure
}
}
/* Q: tempo */
function new_tempo(text) {
var i, c, d, nd,
txt = text, // (for info.Q)
s = {
type: C.TEMPO,
dur: 0
}
// get a note duration
function get_nd(p) {
var n, d,
nd = p.match(/(\d+)\/(\d+)/)
if (nd) {
d = +nd[2]
if (d && !isNaN(d) && !(d & (d - 1))) {
n = +nd[1]
if (!isNaN(n))
return C.BLEN * n / d
}
}
syntax(1, "Invalid note duration $1", c)
} // get_nd()
|
| ︙ | ︙ | |||
961 962 963 964 965 966 967 |
i = text.indexOf('/')
if (i > 0) {
nd = get_nd(text)
if (!nd)
return
s.new_beat = nd
} else {
| | | < | | | | > > | < | | | < < < | | | | | | > > | < | > < > | | 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 |
i = text.indexOf('/')
if (i > 0) {
nd = get_nd(text)
if (!nd)
return
s.new_beat = nd
} else {
s.tempo = +text
if (!s.tempo || isNaN(s.tempo)) {
syntax(1, "Bad tempo value")
return
}
}
}
if (parse.state < 2) { // if in tune header
info.Q = txt
glovar.tempo = s
return
}
if (!curvoice.time)
glovar.tempo = s
else
sym_link(s)
if (!glovar.tempo)
syntax(0, "No previous tempo")
}
// treat the information fields which may embedded
function do_info(info_type, text) {
var s, d1, d2, a, vid
// skip this line if the current voice is ignored
if (curvoice && curvoice.ignore
&& info_type != 'V')
return
switch (info_type) {
// info fields in any state
case 'I':
self.do_pscom(text)
break
case 'L':
a = text.match(/^1\/(\d+)(=(\d+)\/(\d+))?$/)
if (a) {
d1 = +a[1]
if (!d1 || (d1 & (d1 - 1)) != 0)
break
d1 = C.BLEN / d1
if (a[2]) { // if '='
d2 = +a[4]
d2 = d2 ? +a[3] / d2 * C.BLEN : 0
} else {
d2 = d1
}
} else if (text == "auto") {
d1 = d2 = -1
}
if (!d2) {
syntax(1, "Bad L: value")
break
}
if (parse.state <= 1) {
glovar.ulen = d1
} else {
curvoice.ulen = d1;
curvoice.dur_fact = d2 / d1
}
break
case 'M':
new_meter(text)
break
case 'U':
set_user(text)
break
// fields in tune header or tune body
case 'P':
if (!parse.state)
break
if (parse.state == 1) {
info.P = text
break
}
if (!parse.part)
parse.part = {}
if (parse.part[curvoice.time]) // P: already defined
break
s = {
text: text,
time: curvoice.time
}
set_ref(s)
if (cfmt.writefields.indexOf(info_type) < 0)
s.invis = true
parse.part[curvoice.time] = s
break
case 'Q':
if (!parse.state)
break
new_tempo(text)
break
case 'V':
get_voice(text)
if (parse.state == 3)
curvoice.ignore = !par_sy.voices[curvoice.v]
|
| ︙ | ︙ | |||
1118 1119 1120 1121 1122 1123 1124 | while (s2.type != C.BAR && s2.prev) s2 = s2.prev; time = s2.time; auto_time = curvoice.time - time fac = curvoice.wmeasure / auto_time /* remove the invisible rest at start of tune */ | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 |
while (s2.type != C.BAR && s2.prev)
s2 = s2.prev;
time = s2.time;
auto_time = curvoice.time - time
fac = curvoice.wmeasure / auto_time
/* remove the invisible rest at start of tune */
if (!time) {
while (s2 && !s2.dur)
s2 = s2.next
if (s2 && s2.type == C.REST
&& s2.invis) {
time += s2.dur * fac
if (s2.prev)
s2.prev.next = s2.next
|
| ︙ | ︙ | |||
1152 1153 1154 1155 1156 1157 1158 | for (i = 0; i <= s2.nhd; i++) s2.notes[i].dur *= fac } curvoice.time = s.time = time } /* -- parse a bar -- */ | | < < | < < | | < < | 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 |
for (i = 0; i <= s2.nhd; i++)
s2.notes[i].dur *= fac
}
curvoice.time = s.time = time
}
/* -- parse a bar -- */
function new_bar() {
var s2, c, bar_type,
line = parse.line,
s = {
type: C.BAR,
fname: parse.fname,
istart: parse.bol + line.index,
dur: 0,
multi: 0 // needed for decorations
}
if (vover && vover.bar) // end of voice overlay
get_vover('|')
if (glovar.new_nbar) { // %%setbarnb
s.bar_num = glovar.new_nbar;
glovar.new_nbar = 0
}
bar_type = line.char()
while (1) {
c = line.next_char()
switch (c) {
case '|':
case '[':
case ']':
case ':':
bar_type += c
continue
}
break
}
if (bar_type[0] == ':') {
if (bar_type == ':') { // ":" alone
bar_type = '|';
s.bar_dotted = true
} else {
s.rbstop = 2 // right repeat with end
}
}
// set the annotations and the decorations
if (a_gch)
csan_add(s)
if (a_dcn.length)
deco_cnv(s)
// set the start/stop of ottava
if (parse.ottava.length) {
s2 = s
if (curvoice.cst != curvoice.st) { // if staff change
s2 = {
type: C.SPACE, // put the decoration on a ...
|
| ︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 |
* a chord or an embedded header */
if (bar_type.slice(-1) == '['
&& !(/[0-9" ]/.test(c))) { // "
bar_type = bar_type.slice(0, -1);
line.index--;
c = '['
}
| < < | < < < < | > | > | > > > | > > > > > < | | < | < < < < < < < | < < > > > > > > | < | | | | | | | | | | > > > < | | 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 |
* a chord or an embedded header */
if (bar_type.slice(-1) == '['
&& !(/[0-9" ]/.test(c))) { // "
bar_type = bar_type.slice(0, -1);
line.index--;
c = '['
}
// check if a repeat variant
if (c > '0' && c <= '9') {
s.text = c
while (1) {
c = line.next_char()
if ("0123456789,.-".indexOf(c) < 0)
break
s.text += c
}
} else if (c == '"' && bar_type.slice(-1) == '[') {
s.text = ""
while (1) {
c = line.next_char()
if (!c) {
syntax(1, "No end of repeat string")
return
}
if (c == '"') {
line.index++
break
}
s.text += c
}
}
// ']' as the first character indicates a repeat bar stop
if (bar_type[0] == ']') {
s.rbstop = 2 // with end
if (bar_type.length != 1)
bar_type = bar_type.slice(1)
else
s.invis = true
}
s.iend = parse.bol + line.index
if (s.text
&& bar_type.slice(-1) == '['
&& bar_type != '[')
bar_type = bar_type.slice(0, -1)
// there cannot be variants on a left repeat bar
if (bar_type.slice(-1) == ':') { // left repeat
s.rbstop = 2 // stop the bracket
if (s.text) {
syntax(1, "Variant ending on a left repeat bar")
delete s.text
}
curvoice.tie_s_rep = null // no tie anymore on new variant
}
// handle the accidentals (ties and repeat)
if (s.text) {
s.rbstop = 2;
s.rbstart = 2
if (s.text[0] == '1') {
curvoice.tie_s_rep = curvoice.tie_s
if (curvoice.acc_tie)
curvoice.acc_tie_rep = curvoice.acc_tie.slice()
else if (curvoice.acc_tie_rep)
curvoice.acc_tie_rep = null
} else {
curvoice.tie_s = curvoice.tie_s_rep
if (curvoice.acc_tie_rep)
curvoice.acc_tie = curvoice.acc_tie_rep.slice()
}
}
if (s.rbstart
&& curvoice.norepbra
&& !curvoice.second)
s.norepbra = true
if (curvoice.ulen < 0) // L:auto
adjust_dur(s);
if (bar_type == "[" || bar_type == "|:") {
s2 = curvoice.last_sym
if (s2 && s2.time == curvoice.time) {
// search if a previous bar at this time
do {
if (s2.type == C.BAR)
break
if (w_tb[s2.type]) // symbol with a width
break
s2 = s2.prev
} while (s2)
if (s2 && s2.type == C.BAR) {
// && !s2.a_gch && !s2.a_dd
// && !s.a_gch && !s.a_dd) {
// remove the invisible repeat bars
// when no shift is needed
if ((bar_type == "["
&& !s2.text
&& (!curvoice.st
|| (par_sy.staves[curvoice.st - 1].flags & STOP_BAR)
|| s.norepbra))
|| s2.bar_type == "|") { // "|" + "|:" => "|:"
if (bar_type != "[")
s2.bar_type = bar_type
if (s.text)
s2.text = s.text
if (s.a_gch)
s2.a_gch = s.a_gch
if (s.norepbra)
s2.norepbra = s.norepbra
if (s.rbstart)
s2.rbstart = s.rbstart
if (s.rbstop)
s2.rbstop = s.rbstop
//--fixme: pb when on next line and empty staff above
return
}
// merge back-to-back repeat bars
if (bar_type == "|:") {
if (s2.bar_type == ":|") {
s2.bar_type = "::";
s2.rbstop = 2
return
}
if (s2.bar_type == "||") {
s2.bar_type = "||:";
|
| ︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 |
/* set some flags */
switch (bar_type) {
case "[":
s.rbstop = 2
case "[]":
case "[|]":
s.invis = true;
| | | > > | | | | 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 |
/* set some flags */
switch (bar_type) {
case "[":
s.rbstop = 2
case "[]":
case "[|]":
s.invis = true;
bar_type = s.rbstart ? "[" : "[]"
break
case ":|:":
case ":||:":
bar_type = "::"
break
case "||":
if (cfmt["abc-version"] >= "2.2")
break
// fall thru - play repeat on double bar when old ABC version
case "[|":
case "|]":
s.rbstop = 2
break
}
s.bar_type = bar_type
if (!curvoice.lyric_restart)
curvoice.lyric_restart = s
if (!curvoice.sym_restart)
curvoice.sym_restart = s
sym_link(s);
s.st = curvoice.st /* original staff */
/* if repeat bar and shift, add a repeat bar */
if (s.rbstart
&& bar_type != "["
&& !curvoice.norepbra
&& s.st > 0
&& !(par_sy.staves[s.st - 1].flags & STOP_BAR)) {
s2 = {
type: C.BAR,
fname: s.fname,
istart: s.istart,
iend: s.iend,
bar_type: "[",
multi: 0,
invis: true,
text: s.text,
rbstart: 2
}
sym_link(s2);
s2.st = s.st
delete s.text;
s.rbstart = 0
}
if (!s.bar_dotted && !s.invis)
curvoice.acc = [] // no accidental anymore
}
|
| ︙ | ︙ | |||
1541 1542 1543 1544 1545 1546 1547 |
flags |= STOP_BAR
continue
}
break
}
if (vids[vid]) {
syntax(1, "Double voice in %%score")
| | | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 |
flags |= STOP_BAR
continue
}
break
}
if (vids[vid]) {
syntax(1, "Double voice in %%score")
err = true
} else {
vids[vid] = true
a_vf.push([vid, flags])
}
flags = 0
if (!e)
break
|
| ︙ | ︙ | |||
1702 1703 1704 1705 1706 1707 1708 |
}
}
}
note.map = map = map[nn]
if (map[1]) { // if print map
note.pit = pit = map[1].pit
note.acc = map[1].acc
| < < < < | 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 |
}
}
}
note.map = map = map[nn]
if (map[1]) { // if print map
note.pit = pit = map[1].pit
note.acc = map[1].acc
}
if (map[2]) // if color
note.color = map[2]
nn = map[3]
if (nn) // if play map
note.midi = pit2mid(nn.pit + 19, nn.acc)
}
|
| ︙ | ︙ | |||
1737 1738 1739 1740 1741 1742 1743 |
return note
}
function parse_vpos() {
var line = parse.line,
ty = 0
| | > > | 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 |
return note
}
function parse_vpos() {
var line = parse.line,
ty = 0
if (a_dcn.length && a_dcn[a_dcn.length - 1] == "dot") {
ty = C.SL_DOTTED
a_dcn.pop()
}
switch (line.next_char()) {
case "'":
line.index++
return ty + C.SL_ABOVE
case ",":
line.index++
return ty + C.SL_BELOW
|
| ︙ | ︙ | |||
1823 1824 1825 1826 1827 1828 1829 |
p0, p1, s, b40
if (curvoice.snd_oct)
o += curvoice.snd_oct
if (acc == 3) // if natural accidental
acc = 0
if (acc) {
| | | | 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 |
p0, p1, s, b40
if (curvoice.snd_oct)
o += curvoice.snd_oct
if (acc == 3) // if natural accidental
acc = 0
if (acc) {
if (typeof acc == "object") {
s = acc[0] / acc[1] // microtonal accidental
if (acc[1] == 100) // in cents
return p + o + s
} else {
s = acc // simple accidental
}
} else {
if (cfmt.temper)
return cfmt.temper[abc2svg.p_b40[pit % 7]] + o
return p + o
}
if (!cfmt.nedo) { // non equal temperament
if (!cfmt.temper) {
p += o + s // standard temperament
return p
}
} else { // equal temperament
if (typeof acc != "object") { // if not a fraction
b40 = abc2svg.p_b40[pit % 7] + acc
return cfmt.temper[b40] + o
}
if (acc[1] == cfmt.nedo) { // fraction of the edo divider
b40 = abc2svg.p_b40[pit % 7]
return cfmt.temper[b40] + o + s
|
| ︙ | ︙ | |||
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 |
p1 = cfmt.temper[(abc2svg.p_b40[pit % 7] + 39) % 40]
if (p1 > p0)
p1 -= 12
s = -s
}
return p0 + o + (p1 - p0) * s
} // pit2mid()
// (possible hook)
Abc.prototype.new_note = function(grace, sls) {
var note, s, in_chord, c, dcn, type, tie_s, acc_tie,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < > > > > > > | 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
p1 = cfmt.temper[(abc2svg.p_b40[pit % 7] + 39) % 40]
if (p1 > p0)
p1 -= 12
s = -s
}
return p0 + o + (p1 - p0) * s
} // pit2mid()
// handle the ties
// @s = tie ending smbol
// @tei_s = tie starting symbol
function do_ties(s, tie_s) {
var i, m, not1, not2, mid, g,
nt = 0,
se = (tie_s.time + tie_s.dur) == curvoice.time // 'start-end' flag
for (m = 0; m <= s.nhd; m++) {
not2 = s.notes[m]
mid = not2.midi
if (tie_s.type != C.GRACE) {
for (i = 0; i <= tie_s.nhd; i++) {
not1 = tie_s.notes[i]
if (!not1.tie_ty)
continue
if (not1.midi == mid
&& (!se
|| !not1.tie_e)) { // (if unison)
not2.tie_s = not1
not2.s = s
if (se) {
not1.tie_e = not2
not1.s = tie_s
}
nt++
break
}
}
} else {
for (g = tie_s.extra; g; g = g.next) {
not1 = g.notes[0] // (fixme: only one note)
if (!not1.tie_ty)
continue
if (not1.midi == mid) {
g.ti1 = true
not2.tie_s = not1
not2.s = s
not1.tie_e = not2
not1.s = g
nt++
break
}
}
}
}
if (!nt)
error(1, tie_s, "Bad tie")
else
s.ti2 = true
} // do_ties()
// (possible hook)
Abc.prototype.new_note = function(grace, sls) {
var note, s, in_chord, c, dcn, type, tie_s, acc_tie,
i, n, s2, nd, res, num, dur, apit, div, ty,
sl1 = [],
line = parse.line,
a_dcn_sav = a_dcn // save parsed decoration names
a_dcn = []
parse.stemless = false;
s = {
type: C.NOTE,
fname: parse.fname,
stem: 0,
multi: 0,
nhd: 0,
xmx: 0
}
s.istart = parse.bol + line.index
if (curvoice.color)
s.color = curvoice.color
if (grace) {
s.grace = true
} else {
if (curvoice.tie_s) { // if tie from previous note / grace note
tie_s = curvoice.tie_s
curvoice.tie_s = null
}
if (a_gch)
csan_add(s)
if (parse.repeat_n) {
s.repeat_n = parse.repeat_n;
s.repeat_k = parse.repeat_k;
parse.repeat_n = 0
}
}
c = line.char()
switch (c) {
case 'X':
s.invis = true
case 'Z':
s.type = C.MREST;
c = line.next_char()
s.nmes = (c > '0' && c <= '9') ? line.get_int() : 1;
s.dur = curvoice.wmeasure * s.nmes
// ignore if in second voice
if (curvoice.second) {
delete curvoice.eoln // ignore the end of line
curvoice.time += s.dur
return //null
}
// convert 'Z'/'Z1' to a whole measure rest
if (s.nmes == 1) {
s.type = C.REST;
s.dur_orig = s.dur;
s.fmr = 1 // full measure rest
s.notes = [{
pit: 18,
dur: s.dur
}]
} else {
glovar.mrest_p = true
}
|
| ︙ | ︙ | |||
1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 |
s.type = C.REST;
line.index++;
nd = parse_dur(line);
s.dur_orig = ((curvoice.ulen < 0) ?
C.BLEN :
curvoice.ulen) * nd[0] / nd[1];
s.dur = s.dur_orig * curvoice.dur_fact;
s.notes = [{
pit: 18,
dur: s.dur_orig
}]
break
case '[': // chord
in_chord = true;
| > > | 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 |
s.type = C.REST;
line.index++;
nd = parse_dur(line);
s.dur_orig = ((curvoice.ulen < 0) ?
C.BLEN :
curvoice.ulen) * nd[0] / nd[1];
s.dur = s.dur_orig * curvoice.dur_fact;
if (s.dur == curvoice.wmeasure)
s.fmr = 1 // full measure rest
s.notes = [{
pit: 18,
dur: s.dur_orig
}]
break
case '[': // chord
in_chord = true;
|
| ︙ | ︙ | |||
2030 2031 2032 2033 2034 2035 2036 |
type = char_tb[i]
switch (type[0]) {
case '(':
sl1.push(parse_vpos());
c = line.char()
continue
case '!':
| < < | | < < < < < < < < < < < | < > > < < < < < < > > > > > > > > | | < < > > | 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 |
type = char_tb[i]
switch (type[0]) {
case '(':
sl1.push(parse_vpos());
c = line.char()
continue
case '!':
if (type.length > 1)
a_dcn.push(type.slice(1, -1))
else
get_deco() // line -> a_dcn
c = line.next_char()
continue
}
break
}
}
note = parse_basic_note(line,
s.grace ? C.BLEN / 4 :
curvoice.ulen < 0 ?
C.BLEN :
curvoice.ulen)
if (!note)
return //null
// transpose
if (curvoice.octave)
note.pit += curvoice.octave * 7
apit = note.pit + 19 // pitch from C-1
i = note.acc
// get the explicit or implicit accidental
if (i) {
curvoice.acc[apit] = i
} else {
i = curvoice.acc[apit]
if (!i && acc_tie)
i = acc_tie[apit]
if (!i)
i = curvoice.ckey.k_map[apit % 7] || 0
}
// map
if (curvoice.map
&& maps[curvoice.map])
set_map(note, i)
if (!note.midi) // if not map play
note.midi = pit2mid(apit, i)
if (curvoice.ckey.k_sndtran)
note.midi += abc2svg.b40m(curvoice.ckey.k_sndtran +
122) - 36
// starting slurs
if (sl1.length) {
while (1) {
i = sl1.shift()
if (!i)
break
curvoice.sls.push({
is_note: true,
note: note,
ty: i
})
}
note.s = s; // link the note to the chord
}
if (a_dcn.length)
dh_cnv(s, note)
s.notes.push(note)
if (!in_chord)
break
// in chord: get the ending slurs and the ties
c = line.char()
while (1) {
switch (c) {
case ')':
note.s = s
slur_add(note, true)
c = line.next_char()
continue
case '-':
note.tie_ty = parse_vpos()
note.s = s
curvoice.tie_s = s
s.ti1 = true
if (curvoice.acc[apit]
|| (acc_tie
&& acc_tie[apit])) {
if (!curvoice.acc_tie)
curvoice.acc_tie = []
curvoice.acc_tie[apit] =
curvoice.acc[apit] ||
acc_tie[apit]
}
c = line.char()
continue
case '.':
c = line.next_char()
switch (c) {
case '-':
case '(':
a_dcn.push("dot")
continue
}
syntax(1, "Misplaced dot")
break
}
break
}
|
| ︙ | ︙ | |||
2185 2186 2187 2188 2189 2190 2191 |
s.dur_orig = s.notes[0].dur;
s.dur = s.notes[0].dur * curvoice.dur_fact
}
if (s.grace && s.type != C.NOTE) {
syntax(1, errs.bad_grace)
return //null
}
| < < < < | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 |
s.dur_orig = s.notes[0].dur;
s.dur = s.notes[0].dur * curvoice.dur_fact
}
if (s.grace && s.type != C.NOTE) {
syntax(1, errs.bad_grace)
return //null
}
if (s.notes) { // if note or rest
if (!grace) {
switch (curvoice.pos.stm & 0x07) {
case C.SL_ABOVE: s.stem = 1; break
case C.SL_BELOW: s.stem = -1; break
case C.SL_HIDDEN: s.stemless = true; break
}
// adjust the symbol duration
num = curvoice.brk_rhythm
|
| ︙ | ︙ | |||
2234 2235 2236 2237 2238 2239 2240 |
curvoice.time = s2.time + s2.dur;
// adjust the time of the grace notes, bars...
for (s2 = s2.next; s2; s2 = s2.next)
s2.time = curvoice.time
}
} else { /* grace note - adjust its duration */
| | < > > > > > > | < | < | < < < < < < < < < < < < | | > > | 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 |
curvoice.time = s2.time + s2.dur;
// adjust the time of the grace notes, bars...
for (s2 = s2.next; s2; s2 = s2.next)
s2.time = curvoice.time
}
} else { /* grace note - adjust its duration */
div = curvoice.ckey.k_bagpipe ? 8 : 4
for (i = 0; i <= s.nhd; i++)
s.notes[i].dur /= div;
s.dur /= div;
s.dur_orig /= div
if (grace.stem)
s.stem = grace.stem
}
curvoice.last_note = s
// get the possible ties and end of slurs
c = line.char()
while (1) {
switch (c) {
case '.':
if (line.buffer[line.index + 1] != '-')
break
a_dcn.push("dot")
line.index++
// fall thru
case '-':
ty = parse_vpos()
for (i = 0; i <= s.nhd; i++) {
s.notes[i].tie_ty = ty
s.notes[i].s = s
}
curvoice.tie_s = grace || s
curvoice.tie_s.ti1 = true
for (i = 0; i <= s.nhd; i++) {
note = s.notes[i]
apit = note.pit + 19 // pitch from C-1
if (curvoice.acc[apit]
|| (acc_tie
&& acc_tie[apit])) {
if (!curvoice.acc_tie)
curvoice.acc_tie = []
curvoice.acc_tie[apit] =
curvoice.acc[apit] ||
acc_tie[apit]
}
}
c = line.char()
continue
}
break
}
// handle the ties ending on this chord/note
if (tie_s) // if tie from previous note / grace note
do_ties(s, tie_s)
}
sym_link(s)
if (!grace) {
if (!curvoice.lyric_restart)
curvoice.lyric_restart = s
if (!curvoice.sym_restart)
curvoice.sym_restart = s
}
if (a_dcn_sav.length) {
a_dcn = a_dcn_sav
deco_cnv(s, s.prev)
}
if (parse.ottava.length) {
if (grace)
grace.ottava = parse.ottava
else
s.ottava = parse.ottava
parse.ottava = []
}
|
| ︙ | ︙ | |||
2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 |
else
s.tpe = 1
break
}
s = s.next
}
} // tp_adj()
// characters in the music line (ASCII only)
var nil = "0",
char_tb = [
nil, nil, nil, nil, /* 00 - .. */
nil, nil, nil, nil,
nil, " ", "\n", nil, /* . \t \n . */
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 |
else
s.tpe = 1
break
}
s = s.next
}
} // tp_adj()
// get a decoration
function get_deco() {
var c,
line = parse.line,
i = line.index, // in case no deco end
dcn = ""
while (1) {
c = line.next_char()
if (!c) {
syntax(1, "No end of decoration")
line.index = i;
return
}
if (c == '!')
break
dcn += c
}
if (ottava[dcn] != undefined) {
glovar.ottava = true;
parse.ottava.push(ottava[dcn])
} else {
a_dcn.push(dcn)
}
} // get_deco()
// characters in the music line (ASCII only)
var nil = "0",
char_tb = [
nil, nil, nil, nil, /* 00 - .. */
nil, nil, nil, nil,
nil, " ", "\n", nil, /* . \t \n . */
|
| ︙ | ︙ | |||
2404 2405 2406 2407 2408 2409 2410 |
function check_mac(m) {
var i, j, b
for (i = 1, j = line.index + 1; i < m.length; i++, j++) {
if (m[i] == line.buffer[j])
continue
if (m[i] != 'n') // search the base note
| | | | | | > > | 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 |
function check_mac(m) {
var i, j, b
for (i = 1, j = line.index + 1; i < m.length; i++, j++) {
if (m[i] == line.buffer[j])
continue
if (m[i] != 'n') // search the base note
return //undefined
b = ntb.indexOf(line.buffer[j])
if (b < 0)
return //undefined
while (line.buffer[j + 1] == "'") {
b += 7;
j++
}
while (line.buffer[j + 1] == ',') {
b -= 7;
j++
}
}
line.index = j
return b
} // check_mac()
// convert a note as a number into a note as a ABC string
function n2n(n) {
var c = ''
while (n < 0) {
n += 7;
c += ','
}
while (n >= 14) {
n -= 7;
c += "'"
}
return ntb[n] + c
} // n2n()
// expand a transposing macro
function expand(m, b) {
if (b == undefined) // if static macro
return m
var c, i,
r = "", // result
n = m.length
for (i = 0; i < n; i++) {
c = m[i]
if (c >= 'h' && c <= 'z') {
|
| ︙ | ︙ | |||
2491 2492 2493 2494 2495 2496 2497 | range: curvoice.v } } curvoice.time = ti s = curvoice.last_sym parse.line = line = new scanBuf parse.istart += line_sav.index | | | | 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 |
range: curvoice.v
}
}
curvoice.time = ti
s = curvoice.last_sym
parse.line = line = new scanBuf
parse.istart += line_sav.index
line.buffer = expand(m, b)
parse_seq(true)
if (curvoice.time != te)
syntax(1, "Bad length of the macro sequence")
if (!s)
s = curvoice.sym
for ( ; s; s = s.next)
s.invis = s.play = true
curvoice = curv
} else {
line.buffer = expand(m, b)
parse_seq(true)
}
parse.line = line = line_sav
parse.istart = istart_sav
} // parse_mac()
|
| ︙ | ︙ | |||
2531 2532 2533 2534 2535 2536 2537 | break // [V:nn] found c = line.next_char() if (!c) return } } | < < < < < < < < < < < | | | 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 |
break // [V:nn] found
c = line.next_char()
if (!c)
return
}
}
// check if start of a macro
if (!in_mac && maci[c]) {
n = undefined
for (k in mac) {
if (!mac.hasOwnProperty(k)
|| k[0] != c)
continue
if (k.indexOf('n') < 0) {
if (line.buffer.indexOf(k, line.index)
!= line.index)
continue
line.index += k.length
} else {
n = check_mac(k)
if (n == undefined)
continue
}
parse_mac(k, mac[k], n)
n = 1
break
}
if (n)
|
| ︙ | ︙ | |||
2587 2588 2589 2590 2591 2592 2593 | if (grace) grace.gr_shift = true } break case '\n': // line break if (cfmt.barsperstaff) break | < < | | | 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 |
if (grace)
grace.gr_shift = true
}
break
case '\n': // line break
if (cfmt.barsperstaff)
break
curvoice.eoln = true
break
case '&': // voice overlay
if (grace) {
syntax(1, errs.bad_grace)
break
}
c = line.next_char()
if (c == ')') {
get_vover(c) // full overlay stop
break
}
get_vover('&')
continue
case '(': // slur start - tuplet - vover
c = line.next_char()
if (c > '0' && c <= '9') { // tuplet
|
| ︙ | ︙ | |||
2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 |
}
}
if (qplet == 0 || qplet == undefined)
qplet = (curvoice.wmeasure % 9) == 0 ?
3 : 2;
if (tpn < 0)
tpn = tp.length // new tuplet
tp.push({
p: pplet,
q: qplet,
r: rplet,
ro: rplet,
| > > > > > > > > > > > > > > > | | 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 |
}
}
if (qplet == 0 || qplet == undefined)
qplet = (curvoice.wmeasure % 9) == 0 ?
3 : 2;
if (tpn < 0)
tpn = tp.length // new tuplet
c = cfmt.tuplets
if (curvoice.pos.tup) {
c = Object.create(c)
switch (curvoice.pos.tup & 0x07) {
case C.SL_ABOVE:
c[3] = 1
break
case C.SL_BELOW:
c[3] = 2
break
case C.SL_HIDDEN:
c[2] = 1
break
}
}
tp.push({
p: pplet,
q: qplet,
r: rplet,
ro: rplet,
f: c
})
continue
}
if (c == '&') { // voice overlay start
if (grace) {
syntax(1, errs.bad_grace)
break
|
| ︙ | ︙ | |||
2688 2689 2690 2691 2692 2693 2694 | syntax(1, errs.bad_char, c) break } s.notes[0].s = s slur_add(s.notes[0]) break case '!': // start of decoration | < < | | | < < < < < < < < < < < < < < < < < < < < | < | 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 |
syntax(1, errs.bad_char, c)
break
}
s.notes[0].s = s
slur_add(s.notes[0])
break
case '!': // start of decoration
if (type.length > 1) // decoration letter
a_dcn.push(type.slice(1, -1))
else
get_deco() // (line -> a_dcn)
break
case '"':
if (grace) {
syntax(1, errs.bad_grace)
break
}
parse_gchord(type)
|
| ︙ | ︙ | |||
2825 2826 2827 2828 2829 2830 2831 |
if (grace) {
syntax(1, "'{' in grace note")
break
}
last_note_sav = curvoice.last_note;
curvoice.last_note = null;
a_dcn_sav = a_dcn;
| | > > | | | | 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 |
if (grace) {
syntax(1, "'{' in grace note")
break
}
last_note_sav = curvoice.last_note;
curvoice.last_note = null;
a_dcn_sav = a_dcn;
a_dcn = []
grace = {
type: C.GRACE,
fname: parse.fname,
istart: parse.bol + line.index,
dur: 0,
multi: 0
}
if (curvoice.color)
grace.color = curvoice.color
switch (curvoice.pos.gst & 0x07) {
case C.SL_ABOVE: grace.stem = 1; break
case C.SL_BELOW: grace.stem = -1; break
case C.SL_HIDDEN: grace.stem = 2; break /* opposite */
}
sym_link(grace);
c = line.next_char()
if (c == '/') {
grace.sappo = true // acciaccatura
break
}
continue
case '|':
if (grace) {
syntax(1, errs.bar_grace)
break
}
new_bar()
continue
case '}':
s = curvoice.last_note
if (!grace || !s) {
syntax(1, errs.bad_char, c)
break
}
if (a_dcn.length)
syntax(1, "Decoration ignored");
grace.extra = grace.next;
grace.extra.prev = null;
grace.next = null;
curvoice.last_sym = grace;
grace = null
if (!s.prev // if one grace note
|
| ︙ | ︙ | |||
2889 2890 2891 2892 2893 2894 2895 | syntax(1, errs.bad_char, c) break } line.index++ } } // parse_seq() | < | | < < > > > > < < | < | < < > > | 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 |
syntax(1, errs.bad_char, c)
break
}
line.index++
}
} // parse_seq()
if (parse.state != 3) // if not in tune body
return
if (parse.tp) {
tp = parse.tp
tpn = parse.tpn
tps = parse.tps
parse.tp = null
}
parse_seq()
if (tp.length) {
parse.tp = tp
parse.tps = tps
parse.tpn = tpn
}
if (sls.length)
syntax(1, "Start of slur without note")
if (a_dcn.length) {
syntax(1, "Decoration without symbol")
a_dcn = []
}
if (grace) {
syntax(1, "No end of grace note sequence");
curvoice.last_sym = grace.prev;
curvoice.last_note = last_note_sav
if (grace.prev)
grace.prev.next = null
}
if (!no_eol && !cfmt.barsperstaff && !vover
&& char_tb['\n'.charCodeAt(0)] == '\n')
curvoice.eoln = true
if (curvoice.eoln && cfmt.breakoneoln && curvoice.last_note)
curvoice.last_note.beam_end = true
}
|
Changes to core/subs.js.
1 2 | // abc2svg - subs.js - text output // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - subs.js - text output // // Copyright (C) 2014-2021 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>.
// add font styles
var sheet
var add_fstyle = typeof document != "undefined" ?
function(s) {
var e
if (!sheet) {
if (abc2svg.sheet) { // if styles from a previous generation
sheet = abc2svg.sheet
e = sheet.cssRules.length
while (--e >= 0)
sheet.deleteRule(e)
} else {
| > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// along with abc2svg-core. If not, see <http://www.gnu.org/licenses/>.
// add font styles
var sheet
var add_fstyle = typeof document != "undefined" ?
function(s) {
var e
if (cfmt.fullsvg)
font_style += "\n" + s
if (!sheet) {
if (abc2svg.sheet) { // if styles from a previous generation
sheet = abc2svg.sheet
e = sheet.cssRules.length
while (--e >= 0)
sheet.deleteRule(e)
} else {
|
| ︙ | ︙ | |||
131 132 133 134 135 136 137 |
if (typeof str == "object") { // if string already converted
el.innerHTML = str
str.wh = [ el.clientWidth, el.clientHeight ]
return str.wh
}
| | < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
if (typeof str == "object") { // if string already converted
el.innerHTML = str
str.wh = [ el.clientWidth, el.clientHeight ]
return str.wh
}
str = str.replace(/<|>|&[^&\s]*?;|&/g, function(c){
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
}
return c // &xxx;
})
while (1) {
i = str.indexOf('$', i)
if (i < 0)
|
| ︙ | ︙ | |||
167 168 169 170 171 172 173 | el.style.font = style_font(font).slice(5); i += 2; i0 = i } el.innerHTML = str.slice(i0); w += el.clientWidth; | < | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
el.style.font = style_font(font).slice(5);
i += 2;
i0 = i
}
el.innerHTML = str.slice(i0);
w += el.clientWidth;
return [w, h]
}
})() :
// .. by internal tables
function(str) {
var font = gene.curfont,
|
| ︙ | ︙ | |||
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
}
i++;
swfac = font.swfac
if (font.size > h)
h = font.size
continue
case '&':
j = str.indexOf(';', i)
if (j > 0 && j - i < 10) {
i = j;
c = 'a' // XML character reference
}
break
}
w += cwid(c) * swfac
}
| > > < | 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 |
}
i++;
swfac = font.swfac
if (font.size > h)
h = font.size
continue
case '&':
if (str[i + 1] == ' ')
break // normal '&'
j = str.indexOf(';', i)
if (j > 0 && j - i < 10) {
i = j;
c = 'a' // XML character reference
}
break
}
w += cwid(c) * swfac
}
return [w, h]
}
// convert a string to a SVG text, handling the font changes
// The string size is memorized into the String.
function str2svg(str) {
// check if the string is already converted
|
| ︙ | ︙ | |||
240 241 242 243 244 245 246 | cl = nf.class // change only the class else cl = font_class(nf) return '<tspan\n\tclass="' + cl + '">' } // tspan() | | < | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
cl = nf.class // change only the class
else
cl = font_class(nf)
return '<tspan\n\tclass="' + cl + '">'
} // tspan()
o = str.replace(/<|>|&[^&\s]*?;|&|\$./g, function(c){
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
default:
if (c[0] != '$')
break
if (c[1] == '0')
n_font = gene.deffont
else if (c[1] >= '1' && c[1] <= '9')
n_font = get_font("u" + c[1])
|
| ︙ | ︙ | |||
267 268 269 270 271 272 273 | c_font = n_font if (c_font == o_font) return c return c + tspan(c_font, o_font) } return c // &xxx; }) | | < < > > > | 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 |
c_font = n_font
if (c_font == o_font)
return c
return c + tspan(c_font, o_font)
}
return c // &xxx;
})
if (c_font != o_font)
o += "</tspan>"
// convert to String and memorize the string width and height
o = new String(o)
if (typeof document != "undefined")
strwh(o) // browser
else
o.wh = strwh(str) // CLI
gene.curfont = c_font // keep the current font for the next paragraph
return o
} // str2svg()
// set the default and current font
function set_font(xxx) {
if (typeof xxx == "string")
xxx = get_font(xxx)
|
| ︙ | ︙ | |||
343 344 345 346 347 348 349 |
function trim_title(title, is_subtitle) {
var i
if (cfmt.titletrim) {
i = title.lastIndexOf(", ")
if (i < 0 || title[i + 2] < 'A' || title[i + 2] > 'Z') {
i = 0
| | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
function trim_title(title, is_subtitle) {
var i
if (cfmt.titletrim) {
i = title.lastIndexOf(", ")
if (i < 0 || title[i + 2] < 'A' || title[i + 2] > 'Z') {
i = 0
} else if (cfmt.titletrim == 1) { // (true) compatibility
if (i < title.length - 7
|| title.indexOf(' ', i + 3) >= 0)
i = 0
} else {
if (i < title.length - cfmt.titletrim - 2)
i = 0
}
|
| ︙ | ︙ | |||
434 435 436 437 438 439 440 |
case 'c': x = strlw / 2; break
case 'r': x = strlw - font.pad; break
default: x = font.pad; break
}
j = 0
while (1) {
i = text.indexOf('\n', j)
| < < < < < < > > > | | > > > | < | | > | < | | > > > < | | | 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 |
case 'c': x = strlw / 2; break
case 'r': x = strlw - font.pad; break
default: x = font.pad; break
}
j = 0
while (1) {
i = text.indexOf('\n', j)
if (i == j) { // new paragraph
vskip(parskip);
blk_flush()
use_font(gene.curfont)
while (text[i + 1] == '\n') {
vskip(lineskip);
i++
}
if (i == text.length)
break
} else {
if (i < 0)
str = text.slice(j)
else
str = text.slice(j, i)
vskip(strwh(str)[1] * cfmt.lineskipfac
+ font.pad * 2)
xy_str(x, font.pad, str, action)
if (i < 0)
break
}
j = i + 1
}
vskip(parskip);
blk_flush()
break
case 'f':
case 'j':
j = 0
while (1) {
i = text.indexOf('\n\n', j)
if (i < 0)
words = text.slice(j)
else
words = text.slice(j, i);
words = words.split(/\s+/);
w = k = wh = 0
for (j = 0; j < words.length; j++) {
ww = strwh(words[j])
w += ww[0]
if (w >= strlw) {
vskip(wh * cfmt.lineskipfac)
xy_str(0, 0, words.slice(k, j).join(' '),
action, strlw)
k = j;
w = ww[0]
wh = 0
}
w += cwidf(' ')
if (ww[1] > wh)
wh = ww[1]
}
if (w != 0) { // last line
vskip(wh * cfmt.lineskipfac)
xy_str(0, 0, words.slice(k).join(' '))
}
vskip(parskip);
blk_flush()
if (i < 0)
break
while (text[i + 2] == '\n') {
vskip(lineskip);
|
| ︙ | ︙ | |||
514 515 516 517 518 519 520 |
function put_words(words) {
var p, i, j, nw, w, lw, x1, x2, i1, i2, do_flush,
maxn = 0, // max number of characters per line
n = 1 // number of verses
// output a line of words after tune
function put_wline(p, x) {
| | > > | > | | > | | | 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 |
function put_words(words) {
var p, i, j, nw, w, lw, x1, x2, i1, i2, do_flush,
maxn = 0, // max number of characters per line
n = 1 // number of verses
// output a line of words after tune
function put_wline(p, x) {
var i = 0,
k = 0
if (p[0] == '$' // if font change
&& p[1] >= '0' && p[1] <= '9') {
gene.curfont = p[1] == '0' ? gene.deffont
: get_font("u" + p[1])
p = p.slice(2)
}
if ((p[i] >= '0' && p[i] <= '9') || p[i + 1] == '.') {
while (i < p.length) {
i++
if (p[i] == ' '
|| p[i - 1] == ':'
|| p[i - 1] == '.')
break
}
k = i
while (p[i] == ' ')
i++
}
if (k != 0)
xy_str(x, 0, p.slice(0, k), 'r')
if (i < p.length)
xy_str(x + 5, 0, p.slice(i), 'l')
} // put_wline()
set_font("words")
vskip(cfmt.wordsspace)
svg_flush()
|
| ︙ | ︙ | |||
677 678 679 680 681 682 683 |
R: "info",
T: "title",
X: "title"
}
function write_headform(lwidth) {
var c, font, font_name, align, x, y, sz,
info_val = {},
| | | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 |
R: "info",
T: "title",
X: "title"
}
function write_headform(lwidth) {
var c, font, font_name, align, x, y, sz,
info_val = {},
info_font = Object.create(info_font_init),
info_sz = {
A: cfmt.infospace,
C: cfmt.composerspace,
O: cfmt.composerspace,
R: cfmt.infospace
},
info_nb = {}
|
| ︙ | ︙ |
Changes to core/svg.js.
1 2 | // abc2svg - svg.js - svg functions // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - svg.js - svg functions // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
// 1: start a block
// 2: start a new page
// glyphs in music font
var tgls = {
"mtr ": {x:0, y:0, c:"\u0020"}, // space
brace: {x:0, y:0, c:"\ue000"},
| | | | > > > | 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 |
// 1: start a block
// 2: start a new page
// glyphs in music font
var tgls = {
"mtr ": {x:0, y:0, c:"\u0020"}, // space
brace: {x:0, y:0, c:"\ue000"},
lphr: {x:0, y:23, c:"\ue030"},
mphr: {x:0, y:23, c:"\ue038"},
sphr: {x:0, y:26, c:"\ue039"},
short: {x:0, y:32, c:"\ue038"},
tick: {x:0, y:29, c:"\ue039"},
rdots: {x:-1, y:0, c:"\ue043"}, // repeat dots
dsgn: {x:-4, y:-4, c:"\ue045"}, // D.S.
dcap: {x:-4, y:-4, c:"\ue046"}, // D.C.
sgno: {x:-6, y:0, c:"\ue047"}, // segno
coda: {x:-12, y:-6, c:"\ue048"},
tclef: {x:-8, y:0, c:"\ue050"},
cclef: {x:-8, y:0, c:"\ue05c"},
bclef: {x:-8, y:0, c:"\ue062"},
pclef: {x:-6, y:0, c:"\ue069"},
spclef: {x:-6, y:0, c:"\ue069"},
stclef: {x:-8, y:0, c:"\ue07a"},
scclef: {x:-8, y:0, c:"\ue07b"},
sbclef: {x:-7, y:0, c:"\ue07c"},
oct: {x:0, y:2, c:"\ue07d"}, // 8 for clefs
oct2: {x:0, y:2, c:"\ue07e"}, // 15 for clefs
mtr0: {x:0, y:0, c:"\ue080"}, // meters
mtr1: {x:0, y:0, c:"\ue081"},
mtr2: {x:0, y:0, c:"\ue082"},
mtr3: {x:0, y:0, c:"\ue083"},
mtr4: {x:0, y:0, c:"\ue084"},
mtr5: {x:0, y:0, c:"\ue085"},
mtr6: {x:0, y:0, c:"\ue086"},
|
| ︙ | ︙ | |||
124 125 126 127 128 129 130 |
sacc1: {x:-2, y:0, sc: .7, c:"\ue262"}, // small sharp (editorial)
acc2: {x:-3, y:0, c:"\ue263"}, // double sharp
"acc-2": {x:-3, y:0, c:"\ue264"}, // double flat
"acc-1_2": {x:-2, y:0, c:"\ue280"}, // quarter-tone flat
"acc-3_2": {x:-3, y:0, c:"\ue281"}, // three-quarter-tones flat
acc1_2: {x:-1, y:0, c:"\ue282"}, // quarter-tone sharp
acc3_2: {x:-3, y:0, c:"\ue283"}, // three-quarter-tones sharp
| | | | > | | | | | | | | | | | | | | | | | | | 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 |
sacc1: {x:-2, y:0, sc: .7, c:"\ue262"}, // small sharp (editorial)
acc2: {x:-3, y:0, c:"\ue263"}, // double sharp
"acc-2": {x:-3, y:0, c:"\ue264"}, // double flat
"acc-1_2": {x:-2, y:0, c:"\ue280"}, // quarter-tone flat
"acc-3_2": {x:-3, y:0, c:"\ue281"}, // three-quarter-tones flat
acc1_2: {x:-1, y:0, c:"\ue282"}, // quarter-tone sharp
acc3_2: {x:-3, y:0, c:"\ue283"}, // three-quarter-tones sharp
accent: {x:-3, y:2.5, c:"\ue4a0"},
stc: {x:-1, y:-2, c:"\ue4a2"}, // staccato
emb: {x:-4, y:-2, c:"\ue4a4"},
wedge: {x:-1, y:0, c:"\ue4a8"},
marcato: {x:-3, y:-2, c:"\ue4ac"},
hld: {x:-7, y:-2, c:"\ue4c0"}, // fermata
brth: {x:0, y:0, c:"\ue4ce"},
caes: {x:0, y:8, c:"\ue4d1"},
r00: {x:-1.5, y:0, c:"\ue4e1"},
r0: {x:-1.5, y:0, c:"\ue4e2"},
r1: {x:-3.5, y:-6, c:"\ue4e3"},
r2: {x:-3.2, y:0, c:"\ue4e4"},
r4: {x:-3, y:0, c:"\ue4e5"},
r8: {x:-3, y:0, c:"\ue4e6"},
r16: {x:-4, y:0, c:"\ue4e7"},
r32: {x:-4, y:0, c:"\ue4e8"},
r64: {x:-4, y:0, c:"\ue4e9"},
r128: {x:-4, y:0, c:"\ue4ea"},
// mrest: {x:-10, y:0, c:"\ue4ee"},
mrep: {x:-6, y:0, c:"\ue500"},
mrep2: {x:-9, y:0, c:"\ue501"},
p: {x:-4, y:-6, c:"\ue520"},
f: {x:-2.5, y:-6, c:"\ue522"},
pppp: {x:-15, y:-6, c:"\ue529"},
ppp: {x:-11, y:-6, c:"\ue52a"},
pp: {x:-8, y:-6, c:"\ue52b"},
mp: {x:-8.5, y:-6, c:"\ue52c"},
mf: {x:-8, y:-6, c:"\ue52d"},
ff: {x:-6, y:-6, c:"\ue52f"},
fff: {x:-9, y:-6, c:"\ue530"},
ffff: {x:-12, y:-6, c:"\ue531"},
sfz: {x:-9, y:-6, c:"\ue539"},
trl: {x:-4, y:-2, c:"\ue566"}, // trill
turn: {x:-5, y:3, c:"\ue567"},
turnx: {x:-5, y:3, c:"\ue569"},
umrd: {x:-7, y:2, c:"\ue56c"},
lmrd: {x:-7, y:2, c:"\ue56d"},
dplus: {x:-4, y:0, c:"\ue582"}, // plus
sld: {x:-8, y:12, c:"\ue5d0"}, // slide
grm: {x:-2, y:0, c:"\ue5e2"}, // grace mark
dnb: {x:-4, y:0, c:"\ue610"}, // down bow
upb: {x:-3, y:0, c:"\ue612"}, // up bow
opend: {x:-2, y:0, c:"\ue614"}, // harmonic
roll: {x:0, y:2, c:"\ue618"},
thumb: {x:0, y:0, c:"\ue624"},
snap: {x:-2, y:0, c:"\ue630"},
ped: {x:-10, y:0, c:"\ue650"},
pedoff: {x:-5, y:0, c:"\ue655"},
// "mtro.": {x:0, y:0, c:"\ue910"}, // (unused)
mtro: {x:0, y:0, c:"\ue911"}, // tempus perfectum
// "mtro|": {x:0, y:0, c:"\ue912"}, // (unused)
|
| ︙ | ︙ | |||
195 196 197 198 199 200 201 |
// convert a meter string to a SmuFL encoded string
function m_gl(s) {
return s.replace(/[Cco]\||[co]\.|./g,
function(e) {
var m = tgls["mtr" + e]
//fixme: !! no m.x nor m.y yet !!
// if (!m.x && !m.y)
| | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
// convert a meter string to a SmuFL encoded string
function m_gl(s) {
return s.replace(/[Cco]\||[co]\.|./g,
function(e) {
var m = tgls["mtr" + e]
//fixme: !! no m.x nor m.y yet !!
// if (!m.x && !m.y)
return m ? m.c : 0
// return '<tspan dx="'+ m.x.toFixed(1) +
// '" dy="' + m.y.toFixed(1) +
// '">' +
// m.c + '</tspan>'
})
}
|
| ︙ | ︙ | |||
426 427 428 429 430 431 432 |
anno_out(s, t, user.anno_start)
}
function a_stop(s, t) {
anno_out(s, t, user.anno_stop)
}
function empty_function() {
}
| > | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
anno_out(s, t, user.anno_start)
}
function a_stop(s, t) {
anno_out(s, t, user.anno_stop)
}
function empty_function() {
}
// the values are updated on generate()
var anno_start = empty_function,
anno_stop = empty_function
// output the stop user annotations
function anno_put() {
var s
while (1) {
s = anno_a.shift()
if (!s)
|
| ︙ | ︙ | |||
554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
function xypath(x, y, fill) {
if (fill)
out_XYAB('<path d="mX Y', x, y)
else
out_XYAB('<path class="stroke" d="mX Y', x, y)
}
Abc.prototype.xypath = xypath
// output the list of glyphs and the stems
// [0] = x glyph
// [1] = y glyph
// [2] = glyph code
// [3] = x, y, h of stem (3 values per stem)
var gla = [[], [], "", [], [], []]
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
function xypath(x, y, fill) {
if (fill)
out_XYAB('<path d="mX Y', x, y)
else
out_XYAB('<path class="stroke" d="mX Y', x, y)
}
Abc.prototype.xypath = xypath
// draw all the helper/ledger lines
function draw_all_hl() {
var st, p_st
function hlud(hla, d) {
var hl, hll, i, xp, dx2, x2,
n = hla.length
if (!n)
return
for (i = 0; i < n; i++) { // for all lines
hll = hla[i]
if (!hll || !hll.length)
continue
xp = sx(hll[0][0]) // previous x
output +=
'<path class="stroke" stroke-width="1" d="M' +
xp.toFixed(1) + ' ' +
sy(p_st.y + d * i).toFixed(1)
dx2 = 0
while (1) {
hl = hll.shift()
if (!hl)
break
x2 = sx(hl[0])
output += 'm' +
(x2 - xp + hl[1] - dx2).toFixed(2) +
' 0h' + (-hl[1] + hl[2]).toFixed(2)
xp = x2
dx2 = hl[2]
}
output += '"/>\n'
}
} // hlud()
for (st = 0; st <= nstaff; st++) {
p_st = staff_tb[st]
if (!p_st.hlu)
continue // (staff not yet displayed)
set_sscale(st)
hlud(p_st.hlu, 6)
hlud(p_st.hld, -6)
}
} // draw_all_hl()
// output the list of glyphs and the stems
// [0] = x glyph
// [1] = y glyph
// [2] = glyph code
// [3] = x, y, h of stem (3 values per stem)
var gla = [[], [], "", [], [], []]
|
| ︙ | ︙ | |||
788 789 790 791 792 793 794 | y += h; dx /= stv_g.scale; output += '<path class="stroke" d="m'; out_sxsy(x, ' ', y); output += 'v' + h.toFixed(1) + 'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) + | | > | > > > > > | | | < < < < < < | | > > > > > > | 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 |
y += h;
dx /= stv_g.scale;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
output += 'v' + h.toFixed(1) +
'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed(1) + '"/>\n'
}
// tuplet bracket with number - the staves are not defined
function out_tubrn(x, y, dx, dy, up, str) {
var dxx,
sw = str.length * 10,
h = up ? -3 : 3;
set_font("tuplet")
xy_str(x + dx / 2, y + dy / 2 - gene.curfont.size * .5 + 2,
str, 'c')
dx /= stv_g.scale
if (!up)
y += 6;
output += '<path class="stroke" d="m';
out_sxsy(x, ' ', y);
dxx = dx - sw + 1
if (dy > 0)
sw += dy / 8
else
sw -= dy / 8
output += 'v' + h.toFixed(1) +
'm' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) +
'v' + (-h).toFixed(1) + '"/>\n' +
'<path class="stroke" stroke-dasharray="' +
(dxx / 2).toFixed(1) + ' ' + sw.toFixed(1) +
'" d="m';
out_sxsy(x, ' ', y - h);
output += 'l' + dx.toFixed(1) + ' ' + (-dy).toFixed(1) + '"/>\n'
}
// underscore line
function out_wln(x, y, w) {
out_XYAB('<path class="stroke" stroke-width="0.8" d="mX YhF"/>\n',
x, y + 3, w)
}
// decorations with string
var deco_str_style = {
crdc: {
dx: 0,
dy: 5,
style: 'font:italic 14px text,serif'
},
dacs: {
dx: 0,
dy: 3,
style: 'font:16px text,serif',
anchor: ' text-anchor="middle"'
},
pf: {
dx: 0,
dy: 5,
style: 'font:italic bold 16px text,serif'
},
'@': {
dx: 0,
dy: 5,
style: 'font:12px text,sans-serif'
}
}
function out_deco_str(x, y, name, str) {
if (name == 'fng') {
out_XYAB('\
<text x="X" y="Y" style="font-size:14px" text-anchor="middle">A</text>\n',
x, y, m_gl(str))
return
}
var a, f,
a_deco = deco_str_style[name]
if (!a_deco) {
xygl(x, y, name)
return
}
|
| ︙ | ︙ | |||
882 883 884 885 886 887 888 |
while (--val >= 0) {
xygl(x, 6, "ltr");
x += 6
}
g_close()
}
function out_cresc(x, y, val, defl) {
| | | | | 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 |
while (--val >= 0) {
xygl(x, 6, "ltr");
x += 6
}
g_close()
}
function out_cresc(x, y, val, defl) {
x += val * stv_g.scale
val = -val;
out_XYAB('<path class="stroke"\n\
d="mX YlF ', x, y + 5, val)
if (defl.nost)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_dim(x, y, val, defl) {
out_XYAB('<path class="stroke"\n\
d="mX YlF ', x, y + 5, val)
if (defl.noen)
output += '-2.2m0 -3.6l' + (-val).toFixed(1) + ' -2.2"/>\n'
else
output += '-4l' + (-val).toFixed(1) + ' -4"/>\n'
}
function out_ltr(x, y, val) {
y += 4;
|
| ︙ | ︙ | |||
916 917 918 919 920 921 922 923 924 |
y += 4;
if (!defl.nost)
xygl(x, y, "ped");
if (!defl.noen)
xygl(x + val + 6, y, "pedoff")
}
function out_8va(x, y, val, defl) {
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
| > > > > | < < > > > > | | | | < < > > > > | < < > > > > | | | | < < | 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 |
y += 4;
if (!defl.nost)
xygl(x, y, "ped");
if (!defl.noen)
xygl(x + val + 6, y, "pedoff")
}
function out_8va(x, y, val, defl) {
if (val < 18) {
val = 18
x -= 4
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">8\
<tspan dy="-4" style="font-size:10px">va</tspan></text>\n',
x - 8, y);
x += 12;
val -= 12
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_8vb(x, y, val, defl) {
if (val < 18) {
val = 18
x -= 4
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">8\
<tspan dy=".5" style="font-size:10px">vb</tspan></text>\n',
x - 8, y);
x += 10
val -= 10
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
function out_15ma(x, y, val, defl) {
if (val < 25) {
val = 25
x -= 6
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">15\
<tspan dy="-4" style="font-size:10px">ma</tspan></text>\n',
x - 10, y);
x += 20;
val -= 20
}
y += 6;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv6"/>\n', x + val, y)
}
function out_15mb(x, y, val, defl) {
if (val < 24) {
val = 24
x -= 5
}
if (!defl.nost) {
out_XYAB('<text x="X" y="Y" \
style="font:italic bold 12px text,serif">15\
<tspan dy=".5" style="font-size:10px">mb</tspan></text>\n',
x - 10, y);
x += 18
val -= 18
}
// y -= 2;
out_XYAB('<path class="stroke" stroke-dasharray="6,6" d="mX YhF"/>\n',
x, y, val)
if (!defl.noen)
out_XYAB('<path class="stroke" d="mX Yv-6"/>\n', x + val, y)
}
|
| ︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 |
set_font("tempo")
if (s.tempo_str1) {
str.push(s.tempo_str1)
w += strwh(s.tempo_str1)[0]
}
if (s.tempo_notes) {
| | | | | < < | | | < | | 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 |
set_font("tempo")
if (s.tempo_str1) {
str.push(s.tempo_str1)
w += strwh(s.tempo_str1)[0]
}
if (s.tempo_notes) {
dy = ' dy="-1"' // notes a bit higher
for (i = 0; i < s.tempo_notes.length; i++) {
p = tempo_note(s, s.tempo_notes[i])
str.push('<tspan\nclass="' +
font_class(cfmt.musicfont) +
'" style="font-size:' +
(gene.curfont.size * 1.3).toFixed(1) + 'px"' +
dy + '>' +
p + '</tspan>')
j = p.length > 1 ? 2 : 1 // (note and optional dot)
w += j * gene.curfont.swfac
dy = ''
}
str.push('<tspan dy="1">=</tspan>')
w += cwidf('=')
if (s.tempo_ca) {
str.push(s.tempo_ca)
w += strwh(s.tempo_ca)[0]
j = s.tempo_ca.length + 1
}
if (s.tempo) { // with a number of beats per minute
str.push(s.tempo)
w += strwh(s.tempo.toString())[0]
} else { // with a beat as a note
p = tempo_note(s, s.new_beat)
str.push('<tspan\nclass="' +
font_class(cfmt.musicfont) +
'" style="font-size:' +
(gene.curfont.size * 1.3).toFixed(1) +
'px" dy="-1">' +
p + '</tspan>')
j = p.length > 1 ? 2 : 1
w += j * gene.curfont.swfac
dy = 'y'
}
}
if (s.tempo_str2) {
if (dy)
str.push('<tspan\n\tdy="1">' +
s.tempo_str2 + '</tspan>')
else
str.push(s.tempo_str2)
w += strwh(s.tempo_str2)[0]
}
// build the string
s.tempo_str = str.join(' ')
w += cwidf(' ') * (str.length - 1)
s.tempo_wh = [w, 13.0] // (the height is not used)
} // tempo_build()
// output a tempo
function writempo(s, x, y) {
var bh
set_font("tempo")
if (gene.curfont.box) {
gene.curfont.box = false
bh = gene.curfont.size + 4
}
//fixme: xy_str() cannot be used because <tspan> in s.tempo_str
//fixme: then there cannot be font changes by "$n" in the Q: texts
output += '<text class="' + font_class(gene.curfont) +
'" x="'
out_sxsy(x, '" y="', y + gene.curfont.size * .2)
output += '">' + s.tempo_str + '</text>\n'
if (bh) {
gene.curfont.box = true
output += '<rect class="stroke" x="'
out_sxsy(x - 2, '" y="', y + bh - 1)
output += '" width="' + (s.tempo_wh[0] + 2).toFixed(1) +
'" height="' + bh.toFixed(1) +
'"/>\n'
}
// don't display anymore
s.invis = true
|
| ︙ | ︙ | |||
1225 1226 1227 1228 1229 1230 1231 |
posy *= cfmt.scale
if (user.imagesize) {
head += user.imagesize +
' viewBox="0 0 ' + img.width.toFixed(0) + ' ' +
posy.toFixed(0) + '">\n'
} else {
| > > | | < < < < | 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 |
posy *= cfmt.scale
if (user.imagesize) {
head += user.imagesize +
' viewBox="0 0 ' + img.width.toFixed(0) + ' ' +
posy.toFixed(0) + '">\n'
} else {
head += ' viewBox="0 0 ' + img.width.toFixed(0) + ' ' +
posy.toFixed(0) +
'" width="' + img.width.toFixed(0) +
'px" height="' + posy.toFixed(0) + 'px">\n'
}
head += fulldefs
if (style || font_style)
head += '<style>' + font_style + style + '\n</style>\n'
if (defs)
head += '<defs>' + defs + '\n</defs>\n'
// if %%pagescale != 1, do a global scale
// (with a container: transform scale in <svg> does not work
// the same in all browsers)
|
| ︙ | ︙ |
Changes to core/tail.js.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 |
init_tune()
// Abc functions used by the modules
Abc.prototype.a_de = function() { return a_de }
Abc.prototype.add_style = function(s) { style += s };
Abc.prototype.cfmt = function() { return cfmt };
Abc.prototype.clone = clone;
| | > > > > > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
init_tune()
// Abc functions used by the modules
Abc.prototype.a_de = function() { return a_de }
Abc.prototype.add_style = function(s) { style += s };
Abc.prototype.cfmt = function() { return cfmt };
Abc.prototype.clone = clone;
Abc.prototype.deco_put = function(nm, s) {
a_dcn.push(nm)
deco_cnv(s)
}
Abc.prototype.defs_add = defs_add
Abc.prototype.dh_put = function(nm, s, nt) {
a_dcn.push(nm)
dh_cnv(s, nt)
}
Abc.prototype.draw_meter = draw_meter
Abc.prototype.draw_note = draw_note;
Abc.prototype.errs = errs;
Abc.prototype.font_class = font_class;
Abc.prototype.gch_tr1 = gch_tr1;
Abc.prototype.get_bool = get_bool;
Abc.prototype.get_cur_sy = function() { return cur_sy };
|
| ︙ | ︙ | |||
52 53 54 55 56 57 58 |
Abc.prototype.get_posy = function() { var t = posy; posy = 0; return t };
Abc.prototype.get_staff_tb = function() { return staff_tb };
Abc.prototype.get_top_v = function() { return par_sy.top_voice };
Abc.prototype.get_tsfirst = function() { return tsfirst };
Abc.prototype.get_unit = get_unit;
Abc.prototype.get_voice_tb = function() { return voice_tb };
Abc.prototype.glout = glout
| < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
Abc.prototype.get_posy = function() { var t = posy; posy = 0; return t };
Abc.prototype.get_staff_tb = function() { return staff_tb };
Abc.prototype.get_top_v = function() { return par_sy.top_voice };
Abc.prototype.get_tsfirst = function() { return tsfirst };
Abc.prototype.get_unit = get_unit;
Abc.prototype.get_voice_tb = function() { return voice_tb };
Abc.prototype.glout = glout
Abc.prototype.info = function() { return info };
Abc.prototype.new_block = new_block;
Abc.prototype.out_arp = out_arp;
Abc.prototype.out_deco_str = out_deco_str;
Abc.prototype.out_deco_val = out_deco_val;
Abc.prototype.out_ltr = out_ltr;
Abc.prototype.param_set_font = param_set_font;
|
| ︙ | ︙ |
Changes to core/tune.js.
1 2 | // abc2svg - tune.js - tune generation // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - tune.js - tune generation // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg-core. // // abc2svg-core is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 |
if (parse.tune_v_opts.hasOwnProperty(opt))
vfilt(parse.tune_v_opts[opt], opt)
}
}
/* -- link a ABC symbol into the current voice -- */
function sym_link(s) {
if (!s.fname)
set_ref(s)
| > > | | | | | | | | > > > > > > > > | 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 |
if (parse.tune_v_opts.hasOwnProperty(opt))
vfilt(parse.tune_v_opts[opt], opt)
}
}
/* -- link a ABC symbol into the current voice -- */
function sym_link(s) {
var tim = curvoice.time
if (!s.fname)
set_ref(s)
parse.last_sym = s
s.prev = curvoice.last_sym
if (curvoice.last_sym)
curvoice.last_sym.next = s
else
curvoice.sym = s
curvoice.last_sym = s
s.v = curvoice.v;
s.p_v = curvoice;
s.st = curvoice.cst;
s.time = tim
if (s.dur && !s.grace)
curvoice.time += s.dur;
parse.ufmt = true
s.fmt = cfmt // global parameters
s.pos = curvoice.pos
if (curvoice.second)
s.second = true
if (curvoice.floating)
s.floating = true
if (curvoice.eoln) {
s.soln = true
curvoice.eoln = false
}
if (parse.part && parse.part[tim]) {
if (!parse.part[tim].done) {
s.part = parse.part[tim]
parse.part[tim].done = true
}
}
}
/* -- add a new symbol in a voice -- */
function sym_add(p_voice, type) {
var s = {
type:type,
|
| ︙ | ︙ | |||
105 106 107 108 109 110 111 | } return s } /* -- sort all symbols by time and vertical sequence -- */ // weight of the symbols !! depends on the symbol type !! var w_tb = new Uint8Array([ | | | | | | | | | > > > > > > > > > > > > | | > > | > | < < > > | < | > | > | > | | > | > > > > | > > > > | | | > > > > > | < < | > | < | < < | | > | | > | | | < < < < < < < < < < < < < < | | 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 |
}
return s
}
/* -- sort all symbols by time and vertical sequence -- */
// weight of the symbols !! depends on the symbol type !!
var w_tb = new Uint8Array([
5, // bar
1, // clef
8, // custos
0, // (free)
4, // grace
2, // key
3, // meter
9, // mrest
9, // note
0, // part
9, // rest
4, // space
0, // staves
7, // stbrk
0, // tempo
0, // (free)
0, // block
0 // remark
])
function sort_all() {
var s, s2, time, w, wmin, ir, fmt,
fl, new_sy,
nv = voice_tb.length,
vtb = [],
vn = [], // voice indexed by range
sy = cur_sy, // first staff system
v = sy.top_voice,
p_voice = voice_tb[v], // top voice
prev = { // symbol defining the first staff system
type: C.STAVES,
dur: 0,
v: v,
p_v: p_voice,
time: 0,
st: 0,
sy: sy,
next: p_voice.sym,
seqst: true
}
if (!p_voice.sym)
return
prev.fmt = fmt = p_voice.sym.fmt // starting format
// set the first symbol of each voice
for (v = 0; v < nv; v++) {
s = voice_tb[v].sym
vtb[v] = s
if (sy.voices[v])
vn[sy.voices[v].range] = v
}
// insert the first staff system in the top voice
p_voice.sym = tsfirst = s = prev
if (s.next)
s.next.prev = s
else
p_voice.last_sym = s
// if Q: from tune header, put it at start of the music
// (after the staff system)
s = glovar.tempo
if (s) {
s.v = v = p_voice.v
s.p_v = p_voice
s.st = 0
s.time = 0
s.prev = prev
s.next = prev.next
if (s.next)
s.next.prev = s
else
p_voice.last_sym = s
s.prev.next = s
s.fmt = fmt
glovar.tempo = null
vtb[v] = s
}
// loop on the symbols of all voices
while (1) {
if (new_sy) {
sy = new_sy;
new_sy = null;
vn = []
for (v = 0; v < nv; v++) {
if (!sy.voices[v])
continue
vn[sy.voices[v].range] = v
}
}
/* search the min time and symbol weight */
wmin = time = 10000000 // big int
ir = 0
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time > time)
continue
w = w_tb[s.type]
if (s.time < time) {
time = s.time;
wmin = w
} else if (w < wmin) {
wmin = w
}
}
if (wmin > 127)
break // done
/* link the vertical sequence */
ir = 0
while (1) {
v = vn[ir++]
if (v == undefined)
break
s = vtb[v]
if (!s || s.time != time
|| w_tb[s.type] != wmin)
continue
if (s.type == C.STAVES)
new_sy = s.sy
if (fl) {
fl = 0;
s.seqst = true
}
s.ts_prev = prev
prev.ts_next = s
prev = s
vtb[v] = s.next
}
fl = wmin /* start a new sequence if some width */
}
}
// adjust some voice elements
function voice_adj(sys_chg) {
var p_voice, s, s2, v, sl
// set the duration of the notes under a feathered beam
function set_feathered_beam(s1) {
var s, s2, t, d, b, i, a,
d = s1.dur,
n = 1
|
| ︙ | ︙ | |||
285 286 287 288 289 290 291 |
// terminate voice cloning
if (curvoice && curvoice.clone) {
parse.istart = parse.eol
do_cloning()
}
| < < < < < < < < < < < < < < < < < < < < < < < < | < | | < < < < < < < < < < < < < < | | | | | | | | | 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 |
// terminate voice cloning
if (curvoice && curvoice.clone) {
parse.istart = parse.eol
do_cloning()
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v]
if (!sys_chg) { // if not %%score
delete p_voice.eoln
while (1) { // set the end of slurs
sl = p_voice.sls.shift()
if (!sl)
break
s = sl.note.s
for (s2 = s.next; s2; s2 = s2.next) {
if (s2.bar_type && s2.bar_type[0] == ':')
break
}
if (s2) {
if (!s.sls)
s.sls = []
s.sls.push({
ty: sl.ty,
note: {s: s2}
})
} else {
error(1, s, "Lack of ending slur(s)")
}
}
} // not %%score
for (s = p_voice.sym; s; s = s.next) {
if (s.time >= staves_found)
break
}
for ( ; s; s = s.next) {
switch (s.type) {
case C.GRACE:
// with w_tb[C.BAR] = 4 and w_tb[C.GRACE] = 3,
// the grace notes go after the bar;
// if before a bar, change the grace time
if (s.next && s.next.type == C.BAR)
s.time--
if (!cfmt.graceword)
continue
for (s2 = s.next; s2; s2 = s2.next) {
switch (s2.type) {
case C.SPACE:
continue
case C.NOTE:
if (!s2.a_ly)
break
s.a_ly = s2.a_ly;
s2.a_ly = null
break
}
break
}
continue
}
if (s.feathered_beam)
set_feathered_beam(s)
}
}
}
/* -- create a new staff system -- */
function new_syst(init) {
var st, v, sy_staff, p_voice,
sy_new = {
voices: [],
staves: [],
top_voice: 0
}
if (init) { /* first staff system */
cur_sy = par_sy = sy_new
return
}
// update the previous system
for (v = 0; v < voice_tb.length; v++) {
if (par_sy.voices[v]) {
st = par_sy.voices[v].st
sy_staff = par_sy.staves[st]
p_voice = voice_tb[v]
sy_staff.staffnonote = p_voice.staffnonote
if (p_voice.staffscale)
sy_staff.staffscale = p_voice.staffscale;
}
}
for (st = 0; st < par_sy.staves.length; st++) {
|
| ︙ | ︙ | |||
466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
// set the measure number on the top bars
for ( ; s; s = s.ts_next) {
if (!s.seqst)
continue
switch (s.type) {
case C.METER:
bar_num += (s.time - bar_tim) / wmeasure
bar_tim = s.time
wmeasure = s.wmeasure
break
case C.BAR:
if (s.invis)
break
| > | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
// set the measure number on the top bars
for ( ; s; s = s.ts_next) {
if (!s.seqst)
continue
switch (s.type) {
case C.METER:
if (wmeasure != 1) // if not M:none
bar_num += (s.time - bar_tim) / wmeasure
bar_tim = s.time
wmeasure = s.wmeasure
break
case C.BAR:
if (s.invis)
break
|
| ︙ | ︙ | |||
541 542 543 544 545 546 547 |
// convert a note to ABC
function not2abc(pit, acc) {
var i,
nn = ''
if (acc && acc != 3) {
| | | | | 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 |
// convert a note to ABC
function not2abc(pit, acc) {
var i,
nn = ''
if (acc && acc != 3) {
if (typeof acc != "object") {
nn = ['__', '_', '', '^', '^^'][acc + 2]
} else {
i = acc[0]
if (i > 0) {
nn += '^'
} else {
nn += '_'
i = -i
}
nn += i + '/' + acc[1]
}
}
nn += ntb[(pit + 75) % 7]
for (i = pit; i >= 23; i -= 7)
nn += "'"
for (i = pit; i < 16; i += 7)
nn += ","
return nn
} // not2abc()
// note mapping
// %%map map_name note [print [note_head]] [param]*
function get_map(text) {
|
| ︙ | ︙ | |||
690 691 692 693 694 695 696 697 698 699 700 701 702 703 |
if (sndtran == undefined)
return
} else {
curvoice.vtransp = transp
}
if (is_voice_sig()) { // if no symbol yet
curvoice.key = s = clone(curvoice.okey)
} else {
s = curvoice.last_sym
while (1) { // set the transposition in the previous K:
if (s.type == C.KEY)
break
s = s.prev
| > | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
if (sndtran == undefined)
return
} else {
curvoice.vtransp = transp
}
if (is_voice_sig()) { // if no symbol yet
curvoice.okey.fmt = cfmt
curvoice.key = s = clone(curvoice.okey)
} else {
s = curvoice.last_sym
while (1) { // set the transposition in the previous K:
if (s.type == C.KEY)
break
s = s.prev
|
| ︙ | ︙ | |||
718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
/* transpose a note / chord */
function note_transp(s, sk, note) {
var ak, an, d, b40,
n = note.pit,
a = note.acc
if (!a && sk.k_a_acc) // if accidental list
a = sk.k_map[(n + 19) % 7] // invisible accidental
b40 = abc2svg.pab40(n, a) + sk.k_transp // base-40 transposition
note.pit = abc2svg.b40p(b40) // new pitch
| > > > > > > > > | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
/* transpose a note / chord */
function note_transp(s, sk, note) {
var ak, an, d, b40,
n = note.pit,
a = note.acc
if (typeof a == "object") {
d = a[1]
a = a[0]
if (d != 2) {
error(1, s, "Microtone transposition not coded")
return
}
}
if (!a && sk.k_a_acc) // if accidental list
a = sk.k_map[(n + 19) % 7] // invisible accidental
b40 = abc2svg.pab40(n, a) + sk.k_transp // base-40 transposition
note.pit = abc2svg.b40p(b40) // new pitch
|
| ︙ | ︙ | |||
752 753 754 755 756 757 758 |
return // no change
ak = sk.k_map[(note.pit + 19) % 7]
if (ak)
an = 3 // natural
} else {
return // same accidental (in the key)
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | 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 |
return // no change
ak = sk.k_map[(note.pit + 19) % 7]
if (ak)
an = 3 // natural
} else {
return // same accidental (in the key)
}
if (d && an != a) {
switch (Number(a)) {
case -3:
switch (an) {
case -2:
an = -1
break
case 3: // natural
an = -3
note.pit++
break
case 2:
an = -1
break
}
break
case -1:
switch (an) {
case -2:
an = -3
break
case 3: // natural
an = 1
break
}
break
case 1:
switch (an) {
case -1:
an = -3
break
case 3: // natural
an = -1
break
case 2:
an = 3
break
}
break
case 3:
switch (an) {
case -1:
an = 1
break
case 1:
an = 1
note.pit++
break
}
break
}
}
note.acc = d ? [an, d] : an
}
// adjust the pitches according to the transposition(s)
function pit_adj() {
var i, p_v, s, sk, g,
nv = voice_tb.length
while (--nv >= 0) {
p_v = voice_tb[nv]
if (p_v.vtransp == undefined)
continue // no transposition in this voice
if (p_v.key.k_transp) {
sk = p_v.key
key_transp(sk)
sk.k_old_sf = sk.k_sf // no natural
} else {
sk = null
}
s = p_v.sym
while (s) {
// search a transposing key signature
|
| ︙ | ︙ | |||
866 867 868 869 870 871 872 |
if (param.slice(-5) == ' lock') {
fmt_lock[cmd] = true;
param = param.slice(0, -5).trim()
} else if (fmt_lock[cmd]) {
return
}
| < < < < < < < < < < < < < < < < > | | > < < | 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 |
if (param.slice(-5) == ' lock') {
fmt_lock[cmd] = true;
param = param.slice(0, -5).trim()
} else if (fmt_lock[cmd]) {
return
}
switch (cmd) {
case "clef":
if (parse.state >= 2) {
s = new_clef(param)
if (s)
get_clef(s)
}
return
case "deco":
deco_add(param)
return
case "linebreak":
set_linebreak(param)
return
case "map":
get_map(param)
return
case "maxsysstaffsep":
case "sysstaffsep":
if (parse.state == 3) {
val = get_unit(param)
if (isNaN(val)) {
syntax(1, errs.bad_val, "%%" + cmd)
return
}
par_sy.voices[curvoice.v][cmd[0] == 'm' ? "maxsep" : "sep"] =
val
return
}
break
case "multicol":
if (parse.state >= 2) {
curvoice = voice_tb[0]
s = new_block("mc_" + param)
break
}
switch (param) {
case "start":
multicol = {
|
| ︙ | ︙ | |||
959 960 961 962 963 964 965 | break default: syntax(1, "Unknown keyword '$1' in %%multicol", param) break } return case "ottava": | | < | < < < | < < | 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 |
break
default:
syntax(1, "Unknown keyword '$1' in %%multicol", param)
break
}
return
case "ottava":
if (parse.state != 3)
return
n = parseInt(param)
if (isNaN(n) || n < -2 || n > 2) {
syntax(1, errs.bad_val, "%%ottava")
return
}
glovar.ottava = true;
parse.ottava.push(n)
return
case "repbra":
if (curvoice)
curvoice.norepbra = !get_bool(param)
return
case "repeat":
if (parse.state != 3)
return
if (!curvoice.last_sym) {
syntax(1, "%%repeat cannot start a tune")
return
|
| ︙ | ︙ | |||
1057 1058 1059 1060 1061 1062 1063 |
return
case "setbarnb":
val = parseInt(param)
if (isNaN(val) || val < 1) {
syntax(1, "Bad %%setbarnb value")
break
}
| < < | < | < < | < | < < | 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 |
return
case "setbarnb":
val = parseInt(param)
if (isNaN(val) || val < 1) {
syntax(1, "Bad %%setbarnb value")
break
}
glovar.new_nbar = val
return
case "staff":
if (parse.state != 3)
return
val = parseInt(param)
if (isNaN(val)) {
syntax(1, "Bad %%staff value '$1'", param)
return
}
var st
if (param[0] == '+' || param[0] == '-')
st = curvoice.cst + val
else
st = val - 1
if (st < 0 || st > nstaff) {
syntax(1, "Bad %%staff number $1 (cur $2, max $3)",
st, curvoice.cst, nstaff)
return
}
delete curvoice.floating;
curvoice.cst = st
return
case "staffbreak":
if (parse.state != 3)
return
s = {
type: C.STBRK,
dur:0
}
if (param.slice(-1) == 'f') {
s.stbrk_forced = true
param = param.replace(/\sf$/, '')
|
| ︙ | ︙ | |||
1118 1119 1120 1121 1122 1123 1124 | case "stafflines": case "staffscale": case "staffnonote": set_v_param(cmd, param) return case "staves": case "score": | | | < | < < < < | < < | < < < < | > | | | | < < < | 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 |
case "stafflines":
case "staffscale":
case "staffnonote":
set_v_param(cmd, param)
return
case "staves":
case "score":
if (!parse.state)
return
if (parse.scores && parse.scores.length > 0) {
text = parse.scores.shift();
cmd = text.match(/([^\s]+)\s*(.*)/);
param = cmd[2]
cmd = cmd[1]
}
get_staves(cmd, param)
return
case "center":
case "text":
k = cmd[0] == 'c' ? 'c' : cfmt.textoption
set_font("text")
if (parse.state >= 2) {
s = new_block("text")
s.text = param
s.opt = k
s.font = cfmt.textfont
return
}
write_text(param, k)
return
case "transpose": // (abcm2ps compatibility)
if (cfmt.sound)
return
val = get_transp(param)
if (val == undefined) { // accept note interval
val = get_interval(param)
if (val == undefined)
return
}
switch (parse.state) {
case 0:
cfmt.transp = 0
// fall thru
case 1:
cfmt.transp = (cfmt.transp || 0) + val
return
}
for (s = curvoice.last_sym; s; s = s.prev) {
switch (s.type) {
case C.NOTE: // insert a key
s = clone(curvoice.okey);
|
| ︙ | ︙ | |||
1195 1196 1197 1198 1199 1200 1201 | case "tune": //fixme: to do return case "user": set_user(param) return case "voicecolor": | < | < < < | | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 |
case "tune":
//fixme: to do
return
case "user":
set_user(param)
return
case "voicecolor":
if (curvoice)
curvoice.color = param
return
case "vskip":
val = get_unit(param)
if (isNaN(val)) {
syntax(1, errs.bad_val, "%%vskip")
return
}
|
| ︙ | ︙ | |||
1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 |
var i, j, action, s
switch (type) {
case "js":
js_inject(text)
break
case "ml":
if (parse.state >= 2) {
s = new_block(type);
s.text = text
} else {
blk_flush()
if (user.img_out)
user.img_out(text)
| > > > > | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
var i, j, action, s
switch (type) {
case "js":
js_inject(text)
break
case "ml":
if (cfmt.pageheight) {
syntax(1, "Cannot have %%beginml with %%pageheight")
break
}
if (parse.state >= 2) {
s = new_block(type);
s.text = text
} else {
blk_flush()
if (user.img_out)
user.img_out(text)
|
| ︙ | ︙ | |||
1296 1297 1298 1299 1300 1301 1302 |
}
break
case "text":
action = get_textopt(opt);
if (!action)
action = cfmt.textoption
set_font("text")
| > > | | 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 |
}
break
case "text":
action = get_textopt(opt);
if (!action)
action = cfmt.textoption
set_font("text")
if (text.indexOf('\\') >= 0)
text = cnv_escape(text)
if (parse.state > 1) {
s = new_block(type);
s.text = text
s.opt = action
s.font = cfmt.textfont
break
}
write_text(text, action)
|
| ︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 |
}
if (vover) {
syntax(1, "No end of voice overlay");
get_vover(vover.bar ? '|' : ')')
}
| < < > > > > | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 |
}
if (vover) {
syntax(1, "No end of voice overlay");
get_vover(vover.bar ? '|' : ')')
}
voice_adj();
sort_all() /* define the time / vertical sequences */
if (!tsfirst)
return
if (user.anno_start)
anno_start = a_start
if (user.anno_stop)
anno_stop = a_stop
self.set_bar_num()
pit_adj()
if (info.P)
tsfirst.parts = info.P // for play
// give the parser result to the application
|
| ︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 |
}
}
return //undefined
}
/* -- get staves definition (%%staves / %%score) -- */
function get_staves(cmd, parm) {
| | | > | > > | | | < < < < < | < < | < > > > > > > > > > > > > > > > > | | | > | 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 |
}
}
return //undefined
}
/* -- get staves definition (%%staves / %%score) -- */
function get_staves(cmd, parm) {
var s, p_voice, p_voice2, i, flags, v, vid, a_vf,
st, range,
nv = voice_tb.length,
maxtime = 0
if (parm) {
a_vf = parse_staves(parm) // => array of [vid, flags]
if (!a_vf)
return
}
/* create a new staff system */
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (p_voice.time > maxtime)
maxtime = p_voice.time
}
if (!maxtime) { // if first %%staves
par_sy.staves = []
par_sy.voices = []
} else {
if (nv) // if many voices
voice_adj(true)
/*
* create a new staff system and
* link the 'staves' symbol in a voice which is seen from
* the previous system - see sort_all
*/
for (v = 0; v < par_sy.voices.length; v++) {
if (par_sy.voices[v]) {
curvoice = voice_tb[v]
break
}
}
curvoice.time = maxtime;
s = {
type: C.STAVES,
dur: 0
}
sym_link(s); // link the staves in this voice
par_sy.nstaff = nstaff;
// if no parameter, duplicate the current staff system
// and do a voice re-synchronization
if (!parm) {
s.sy = clone(par_sy, 1)
par_sy.next = s.sy
par_sy = s.sy
staves_found = maxtime
for (v = 0; v < nv; v++)
voice_tb[v].time = maxtime
curvoice = voice_tb[par_sy.top_voice]
return
}
new_syst();
s.sy = par_sy
}
staves_found = maxtime
/* initialize the (old) voices */
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
delete p_voice.second
delete p_voice.ignore
delete p_voice.floating
}
range = 0
for (i = 0; i < a_vf.length; i++) {
vid = a_vf[i][0];
p_voice = new_voice(vid);
p_voice.time = maxtime;
v = p_voice.v
a_vf[i][0] = p_voice;
// set the range and add the overlay voices
while (1) {
par_sy.voices[v] = {
range: range++
}
p_voice = p_voice.voice_down
if (!p_voice)
break
v = p_voice.v
}
}
par_sy.top_voice = a_vf[0][0].v
|
| ︙ | ︙ | |||
1605 1606 1607 1608 1609 1610 1611 |
/* change the behaviour of '|' in %%score */
if (cmd[1] == 'c') { /* if %%score */
for (st = 0; st < nstaff; st++)
par_sy.staves[st].flags ^= STOP_BAR
}
| > > | > > > > > > > > > > > > > > | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 |
/* change the behaviour of '|' in %%score */
if (cmd[1] == 'c') { /* if %%score */
for (st = 0; st < nstaff; st++)
par_sy.staves[st].flags ^= STOP_BAR
}
nv = voice_tb.length
st = 0
for (v = 0; v < nv; v++) {
p_voice = voice_tb[v]
if (par_sy.voices[v])
st = p_voice.st
else
p_voice.st = st // (this avoids later crashes)
// if first %%staves
// update the staff of the symbols with no time
if (!maxtime) {
for (s = p_voice.sym; s; s = s.next)
s.st = st
}
if (!par_sy.voices[v])
continue
// set the staff of the overlay voices
p_voice2 = p_voice.voice_down
while (p_voice2) {
i = p_voice2.v
p_voice2.st = p_voice2.cst =
par_sy.voices[i].st = st
p_voice2 = p_voice2.voice_down
}
par_sy.voices[v].second = p_voice.second;
st = p_voice.st
if (st > 0 && !p_voice.norepbra
&& !(par_sy.staves[st - 1].flags & STOP_BAR))
p_voice.norepbra = true
}
if (!maxtime && nv) // if first staff system and many voices
voice_adj(true)
curvoice = parse.state >= 2 ? voice_tb[par_sy.top_voice] : null
}
// get a voice or create a clone of the current voice
function clone_voice(id) {
var v, p_voice
|
| ︙ | ︙ | |||
1651 1652 1653 1654 1655 1656 1657 | p_voice.sls = [] delete p_voice.nm delete p_voice.snm delete p_voice.new_name delete p_voice.lyric_restart delete p_voice.lyric_cont | < | 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 | p_voice.sls = [] delete p_voice.nm delete p_voice.snm delete p_voice.new_name delete p_voice.lyric_restart delete p_voice.lyric_cont delete p_voice.sym_restart delete p_voice.sym_cont delete p_voice.have_ly delete p_voice.tie_s voice_tb.push(p_voice) return p_voice |
| ︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 |
par_sy.voices[v2].range = range + 1
}
p_voice2.ulen = curvoice.ulen
p_voice2.dur_fact = curvoice.dur_fact
p_voice2.acc = [] // no accidental
if (!vover) { /* first '&' in a measure */
| < < < < > > > | > | | > | | | | > | 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 |
par_sy.voices[v2].range = range + 1
}
p_voice2.ulen = curvoice.ulen
p_voice2.dur_fact = curvoice.dur_fact
p_voice2.acc = [] // no accidental
if (!vover) { /* first '&' in a measure */
time = p_voice2.time
for (s = curvoice.last_sym; /*s*/; s = s.prev) {
if (s.type == C.BAR
|| s.time <= time) /* (if start of tune) */
break
}
vover = {
bar: (s && s.bar_type) ? s.bar_type : '|',
p_voice: curvoice,
time: s.time
}
} else {
if (curvoice != vover.p_voice
&& curvoice.time != vover.p_voice.time) {
syntax(1, "Wrong duration in voice overlay")
if (curvoice.time > vover.p_voice.time)
vover.p_voice.time = curvoice.time
}
}
p_voice2.time = vover.time;
curvoice = p_voice2
// add a bar at start of the measure overlay
// (needed for sort_all() in case of spaces - 'y')
if (vover.bar && vover.time) {
sym_link({
type: C.BAR,
bar_type: vover.bar,
invis: 1,
dur: 0,
multi: 0
})
}
}
// check if a clef, key or time signature may go at start of the current voice
function is_voice_sig() {
var s
if (!curvoice.last_sym)
return true
if (curvoice.time)
return false
for (s = curvoice.last_sym; s; s = s.prev)
if (w_tb[s.type])
return false
return true
}
// treat a clef found in the tune body
function get_clef(s) {
if (is_voice_sig()) {
curvoice.clef = s
s.fmt = cfmt
return
}
// clef change
sym_link(s);
s.clef_small = true
|
| ︙ | ︙ | |||
1819 1820 1821 1822 1823 1824 1825 | var v, p_voice, s, transp, sndtran, // [s_key, a] = new_key(parm) // KO with nodejs a = new_key(parm), s_key = a[0]; a = a[1] | < | < < > > | < < > | < > | | | > > > > > > | > | | | < | > | 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 |
var v, p_voice, s, transp, sndtran,
// [s_key, a] = new_key(parm) // KO with nodejs
a = new_key(parm),
s_key = a[0];
a = a[1]
if (parse.state == 1) { // in tune header (first K:)
if (s_key.k_sf == undefined && !s_key.k_a_acc) { // empty K:
s_key.k_sf = 0;
s_key.k_none = true
s_key.k_map = abc2svg.keys[7]
}
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.key = clone(s_key);
p_voice.okey = clone(s_key);
p_voice.ckey = clone(s_key)
}
parse.ckey = s_key
if (!glovar.ulen)
glovar.ulen = C.BLEN / 8;
if (a.length) {
memo_kv_parm('*', a)
a = ''
}
goto_tune()
parse.state = 3 // in tune body
}
set_kv_parm(a)
if (!curvoice.ckey.k_bagpipe && !curvoice.ckey.k_drum
&& (cfmt.transp != undefined
|| curvoice.transp != undefined
|| curvoice.shift != undefined))
transp = (cfmt.transp || 0) +
(curvoice.transp || 0) +
(curvoice.shift || 0)
if (curvoice.sndtran != undefined
|| curvoice.sndsh != undefined)
sndtran = (curvoice.sndtran || 0) +
(curvoice.sndsh || 0)
if (s_key.k_sf == undefined) {
if (!s_key.k_a_acc
&& transp == undefined) {
if (sndtran == undefined)
return // not a key signature
s_key.invis = true // play only
}
s_key.k_sf = curvoice.okey.k_sf
}
curvoice.okey = clone(s_key)
if (transp != undefined) {
curvoice.vtransp = transp;
s_key.k_transp = transp
}
if (sndtran != undefined)
s_key.k_sndtran = sndtran
s_key.k_old_sf = curvoice.ckey.k_sf; // memorize the key changes
if ((!s_key.k_a_acc || !s_key.k_a_acc.length)
&& !s_key.k_sf && !s_key.k_old_sf)
s_key.invis = true // don't display the key signature
if (!s_key.k_b40)
s_key.k_b40 = curvoice.ckey.k_b40
curvoice.ckey = s_key
if (is_voice_sig()) {
s_key.fmt = cfmt
curvoice.key = clone(s_key)
if (s_key.k_none)
curvoice.key.k_sf = 0
} else {
sym_link(s_key) // (don't move the key)
}
}
// get / create a new voice
function new_voice(id) {
var v, p_v_sav,
p_voice = voice_tb[0],
n = voice_tb.length
// if first explicit voice and no music, replace the default V:1
if (n == 1
&& p_voice.default) {
delete p_voice.default
if (!p_voice.time) { // if no symbol yet
p_voice.id = id
delete p_voice.init // reload the global attributes
if (cfmt.transp // != undefined
&& parse.state >= 2) {
p_v_sav = curvoice;
curvoice = p_voice;
set_transp();
curvoice = p_v_sav
}
|
| ︙ | ︙ | |||
1925 1926 1927 1928 1929 1930 1931 |
p_voice = {
v: v,
id: id,
time: 0,
new: true,
pos: {
| | | | | | > | | | 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 |
p_voice = {
v: v,
id: id,
time: 0,
new: true,
pos: {
// dyn: 0,
// gch: 0,
// gst: 0,
// orn: 0,
// stm: 0,
// tup: 0,
// voc: 0,
// vol: 0
},
scale: 1,
// st: 0,
// cst: 0,
ulen: glovar.ulen,
dur_fact: 1,
key: clone(parse.ckey), // key at start of tune (parse / gene)
|
| ︙ | ︙ | |||
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 |
nstaff = -1;
voice_tb = [];
curvoice = null;
new_syst(true);
staves_found = -1;
gene = {}
a_de = [] // remove old decorations
}
// treat V: with many voices
function do_cloning() {
var i,
clone = curvoice.clone,
vs = clone.vs,
| > | 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 |
nstaff = -1;
voice_tb = [];
curvoice = null;
new_syst(true);
staves_found = -1;
gene = {}
a_de = [] // remove old decorations
cross = {} // new cross voice decorations
}
// treat V: with many voices
function do_cloning() {
var i,
clone = curvoice.clone,
vs = clone.vs,
|
| ︙ | ︙ | |||
2041 2042 2043 2044 2045 2046 2047 |
if (vid == '*') {
syntax(1, "Cannot have V:* in tune body")
return
}
curvoice = new_voice(vs[0])
| | < < < | 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 |
if (vid == '*') {
syntax(1, "Cannot have V:* in tune body")
return
}
curvoice = new_voice(vs[0])
// if many voices, memorize the start of sequence
if (vs.length > 1) {
vs.shift()
curvoice.clone = {
vs: vs,
a: a,
bol: parse.iend
}
if (parse.file[curvoice.clone.bol - 1] != ']')
curvoice.clone.bol++ // start of new line
}
set_kv_parm(a)
v = curvoice.v
if (curvoice.new) { // if new voice
delete curvoice.new
if (staves_found < 0) { // if no %%score/%%staves
curvoice.st = curvoice.cst = ++nstaff;
par_sy.nstaff = nstaff;
|
| ︙ | ︙ | |||
2084 2085 2086 2087 2088 2089 2090 |
&& (parse.voice_opts
|| parse.tune_v_opts)) {
curvoice.filtered = true;
voice_filter()
}
}
| | | | < < < < < < < < | < < < < < | | > | > | > < | < < < < < < | 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 |
&& (parse.voice_opts
|| parse.tune_v_opts)) {
curvoice.filtered = true;
voice_filter()
}
}
// change state from 'tune header' to 'in tune body'
// curvoice is defined when called from get_voice()
function goto_tune() {
var v, p_voice
set_page();
write_heading();
if (glovar.new_nbar) {
gene.nbar = glovar.new_nbar // measure numbering
glovar.new_nbar = 0
} else {
gene.nbar = 1
}
// if no voice yet, create the default voice
if (!voice_tb.length) {
get_voice("1");
curvoice.clef.istart = curvoice.key.istart;
curvoice.clef.iend = curvoice.key.iend;
// nstaff = 0;
curvoice.default = true
} else {
curvoice = voice_tb[staves_found < 0 ? 0 : par_sy.top_voice]
}
// update some voice parameters
for (v = 0; v < voice_tb.length; v++) {
p_voice = voice_tb[v];
p_voice.ulen = glovar.ulen
if (p_voice.ckey.k_bagpipe
&& !p_voice.pos.stm) {
p_voice.pos = clone(p_voice.pos)
p_voice.pos.stm &= ~0x07
p_voice.pos.stm |= C.SL_BELOW
}
}
// initialize the voices when no %%staves/score
if (staves_found < 0) {
v = voice_tb.length
par_sy.nstaff =
nstaff = v - 1
while (--v >= 0) {
p_voice = voice_tb[v];
delete p_voice.new; // old voice
p_voice.st = p_voice.cst = v;
par_sy.voices[v] = {
st: v,
range: v
}
par_sy.staves[v] = {
stafflines: p_voice.stafflines || "|||||",
staffscale: 1
}
}
}
}
|
Changes to edit-de.js.
1 2 3 4 5 6 7 8 9 10 11 12 |
//JS - abc2svg edit - Text in Deutsch
function loadtxt() {
texts = {
bad_nb: 'fehlerhafte Zeilennummer',
fn: 'Filename: ',
load: 'Bitte öffne die eingebundene Datei ',
play: 'Wiedergabe',
stop: 'Stop',
}
var text_kv = {
a: 'Über ...',
b: 'ABC-Files:',
| < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//JS - abc2svg edit - Text in Deutsch
function loadtxt() {
texts = {
bad_nb: 'fehlerhafte Zeilennummer',
fn: 'Filename: ',
load: 'Bitte öffne die eingebundene Datei ',
play: 'Wiedergabe',
stop: 'Stop',
}
var text_kv = {
a: 'Über ...',
b: 'ABC-Files:',
cmpt: 'Stück',
cmps: 'Auswahl',
cmpl: 'Schleife',
cmpc: 'Weiter',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Fehler',
|
| ︙ | ︙ |
Changes to edit-en.js.
1 2 3 4 5 6 7 8 9 10 |
//JS - abc2svg edit - text in English
function loadtxt() {
texts = {
bad_nb: 'Bad line number',
fn: 'File name: ',
load: 'Please, load the included file ',
}
var text_kv = {
a: 'About',
b: 'ABC files:',
| < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//JS - abc2svg edit - text in English
function loadtxt() {
texts = {
bad_nb: 'Bad line number',
fn: 'File name: ',
load: 'Please, load the included file ',
}
var text_kv = {
a: 'About',
b: 'ABC files:',
cmpt: 'Tune',
cmps: 'Selection',
cmpl: 'Loop',
cmpc: 'Continue',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Errors',
|
| ︙ | ︙ |
Changes to edit-fr.js.
1 2 3 4 5 6 7 8 9 10 |
//JS - abc2svg edit - textes en français
function loadtxt() {
texts = {
bad_nb: 'Mauvais numéro de ligne',
fn: 'Nom de fichier: ',
load: 'SVP, ouvrez le fichier à inclure ',
}
var text_kv = {
a: 'A propos',
b: 'Fichiers ABC:',
| < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//JS - abc2svg edit - textes en français
function loadtxt() {
texts = {
bad_nb: 'Mauvais numéro de ligne',
fn: 'Nom de fichier: ',
load: 'SVP, ouvrez le fichier à inclure ',
}
var text_kv = {
a: 'A propos',
b: 'Fichiers ABC:',
cmpt: 'Morceau',
cmps: 'Selection',
cmpl: 'Boucle',
cmpc: 'Continuer',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Erreurs',
|
| ︙ | ︙ |
Changes to edit-it.js.
1 2 3 4 5 6 7 8 9 10 |
//JS - abc2svg edit - text in Italian
function loadtxt() {
texts = {
bad_nb: 'Numero di linea errato',
fn: 'Nome file: ',
load: 'Carica il file da includere ',
}
var text_kv = {
a: 'A proposito',
b: 'File ABC:',
| < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//JS - abc2svg edit - text in Italian
function loadtxt() {
texts = {
bad_nb: 'Numero di linea errato',
fn: 'Nome file: ',
load: 'Carica il file da includere ',
}
var text_kv = {
a: 'A proposito',
b: 'File ABC:',
cmpt: 'Brano',
cmps: 'Selezione',
cmpl: 'Loop',
cmpc: 'Continua',
// df: 'Caratteristiche di abc2svg',
// dp: 'Parametri di abc2svg',
er: 'Errori',
|
| ︙ | ︙ |
Changes to edit-pt_BR.js.
1 2 3 4 5 6 7 8 9 10 |
//JS - abc2svg edit - texto em português do Brasil
function loadtxt() {
texts = {
bad_nb: 'Número de linha incorreto',
fn: 'Nome do arquivo: ',
load: 'Por favor, inclua o arquivo ',
}
var text_kv = {
a: 'Sobre',
b: 'Arquivos ABC:',
| < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//JS - abc2svg edit - texto em português do Brasil
function loadtxt() {
texts = {
bad_nb: 'Número de linha incorreto',
fn: 'Nome do arquivo: ',
load: 'Por favor, inclua o arquivo ',
}
var text_kv = {
a: 'Sobre',
b: 'Arquivos ABC:',
cmpt: 'Peça',
cmps: 'Selecção',
cmpl: 'Loop',
cmpc: 'Continua',
// df: 'abc2svg features',
// dp: 'abc2svg parameters',
er: 'Erros',
|
| ︙ | ︙ |
Changes to editor/edit.css.
1 2 |
/* edit.css - file used in the abc2svg editor */
@page {margin:0}
| < | 1 2 3 4 5 6 7 8 9 |
/* edit.css - file used in the abc2svg editor */
@page {margin:0}
svg {display:block;background-color:#ffffff}
.abcr {fill: #d00000; fill-opacity: 0; z-index: 15}
@media screen {
body, html {height: 90%}
text, path {pointer-events: none}
svg {margin-left:auto;margin-right:0}
#dleft {
|
| ︙ | ︙ |
Changes to editor/edit.js.
1 2 | // edit.js - file used in the abc2svg editor // | | | 1 2 3 4 5 6 7 8 9 10 | // edit.js - file used in the abc2svg editor // // Copyright (C) 2014-2022 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
210 211 212 213 214 215 216 |
}
}
elt_ref.diverr.innerHTML = '';
selx[0] = selx[1] = 0;
render2()
}
function render2() {
| | > | > > > > > > > > > > > > | 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 |
}
}
elt_ref.diverr.innerHTML = '';
selx[0] = selx[1] = 0;
render2()
}
function render2() {
var content = elt_ref.source.value,
def = (abc2svg.a_inc && abc2svg.a_inc["default.abc"]) || ''
// load the required modules
if (!abc2svg.modules.load(content + elt_ref.src1.value + def, render2))
return
// if page formatting, define a function to get the modification date
if (abc2svg.modules.pageheight.loaded) {
abc2svg.get_mtime = function(fn) {
var files = document.getElementById("abcfile").files
if (files && files[0].lastModified)
return new Date(files[0].lastModified)
return new Date()
}
}
abc = new abc2svg.Abc(user);
abc_images = '';
// document.body.style.cursor = "wait";
syms = []
// insert the file default.abc if loaded
if (abc2svg.a_inc && abc2svg.a_inc["default.abc"]) {
try {
abc.tosvg("default.abc", abc2svg.a_inc["default.abc"])
} catch(e) {
alert(e.message + '\nabc2svg tosvg bug - stack:\n' + e.stack)
return
}
}
// render the textarea
try {
abc.tosvg(abc_fname[0], content)
} catch(e) {
alert(e.message + '\nabc2svg tosvg bug - stack:\n' + e.stack)
return
}
abc2svg.abc_end() // close the page if %%pageheight
|
| ︙ | ︙ | |||
272 273 274 275 276 277 278 279 |
if (o > m)
o = m
return o
} // soffs()
// select a source ABC element on error
function gotoabc(l, c) {
selsrc(0)
| > > > | | | | 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 |
if (o > m)
o = m
return o
} // soffs()
// select a source ABC element on error
function gotoabc(l, c) {
var s = elt_ref.source
selsrc(0)
if (l >= 0)
c = soffs(l, Number(c))
s.focus();
s.setSelectionRange(c, syms[c] ? syms[c].iend : c + 1)
}
// click in the target
function selsvg(evt) {
var v,
cl = evt.target.getAttribute('class')
play.loop = false;
// evt.stopImmediatePropagation();
// evt.preventDefault()
// remove the context menu if active
if (ctxMenu && ctxMenu.style.display == "block") {
ctxMenu.style.display = "none"
return
}
|
| ︙ | ︙ | |||
582 583 584 585 586 587 588 | return sym } sym = sym.ts_prev } // not reached } | | | | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
return sym
}
sym = sym.ts_prev
}
// not reached
}
function gsot(si) { // go to the first symbol of a tune
return syms[si].p_v.sym
}
function get_se(si) { // get the starting symbol
var sym = syms[si]
while (!sym.seqst)
sym = sym.ts_prev
return sym
|
| ︙ | ︙ | |||
678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
}
play_start(si, ei)
}
// set the version and initialize the playing engine
function edit_init() {
// loop until abc2svg is fully loaded
if (typeof abc2svg != "object"
|| !abc2svg.modules) {
setTimeout(edit_init, 500)
return
}
| > | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
}
play_start(si, ei)
}
// set the version and initialize the playing engine
function edit_init() {
var a, i, e
// loop until abc2svg is fully loaded
if (typeof abc2svg != "object"
|| !abc2svg.modules) {
setTimeout(edit_init, 500)
return
}
|
| ︙ | ︙ | |||
738 739 740 741 742 743 744 |
loadlang(v, true)
}
document.getElementById("abc2svg").innerHTML =
'abc2svg-' + abc2svg.version + ' (' + abc2svg.vdate + ')'
// keep references on the page elements
| | | | | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 |
loadlang(v, true)
}
document.getElementById("abc2svg").innerHTML =
'abc2svg-' + abc2svg.version + ' (' + abc2svg.vdate + ')'
// keep references on the page elements
a = ["diverr", "source", "src1", "s0", "s1", "target"]
for (i = 0; i < a.length; i++) {
e = a[i]
elt_ref[e] = document.getElementById(e)
}
// set the callback functions
document.getElementById("saveas").onclick = saveas;
elt_ref.s0.onclick = function(){selsrc(0)};
elt_ref.s1.onclick = function(){selsrc(1)};
|
| ︙ | ︙ | |||
785 786 787 788 789 790 791 |
// Math.log(play.abcplay.set_speed()) / Math.log(3);
document.getElementById("gvol").setAttribute("value",
play.abcplay.set_vol() * 10)
document.getElementById("gvl").setAttribute("value",
(play.abcplay.set_vol() * 10).toFixed(2))
});
| | > | | | | 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 |
// Math.log(play.abcplay.set_speed()) / Math.log(3);
document.getElementById("gvol").setAttribute("value",
play.abcplay.set_vol() * 10)
document.getElementById("gvl").setAttribute("value",
(play.abcplay.set_vol() * 10).toFixed(2))
});
// display the play menu
// This function is called on non left click
function show_menu(evt) {
var x, y,
elt = evt.target,
cl = elt.getAttribute('class')
// evt.stopImmediatePropagation();
evt.preventDefault()
// if right click on an element, select it
if (cl && cl.substr(0, 4) == 'abcr') {
setsel(1, Number(cl.slice(6, -1)))
return false
}
|
| ︙ | ︙ | |||
813 814 815 816 817 818 819 |
ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "block";
x = evt.pageX - elt_ref.target.parentNode.offsetLeft
+ elt_ref.target.parentNode.scrollLeft;
y = evt.pageY + elt_ref.target.parentNode.scrollTop;
ctxMenu.style.left = (x - 30) + "px";
ctxMenu.style.top = (y - 10) + "px"
| > | > > | > > | 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 |
ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "block";
x = evt.pageX - elt_ref.target.parentNode.offsetLeft
+ elt_ref.target.parentNode.scrollLeft;
y = evt.pageY + elt_ref.target.parentNode.scrollTop;
ctxMenu.style.left = (x - 30) + "px";
ctxMenu.style.top = (y - 10) + "px"
} // showmenu
e = elt_ref.target
e.onauxclick = show_menu // right or middle buttons
e.oncontextmenu = function(ev) {
ev.preventDefault()
}
}
set_pref() // set the preferences from local storage
}
// drag and drop
function drag_enter(evt) {
evt.stopImmediatePropagation();
|
| ︙ | ︙ | |||
851 852 853 854 855 856 857 |
+ e.value.slice(h)
src_change()
return
}
// check if file
data = evt.dataTransfer.files // FileList object.
if (data.length) {
| | > > > | | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 |
+ e.value.slice(h)
src_change()
return
}
// check if file
data = evt.dataTransfer.files // FileList object.
if (data.length) {
var reader = new FileReader(),
s = srcidx == 0 ? "source" : "src1"
elt_ref["s" + srcidx].value = abc_fname[srcidx] = data[0].name
reader.onload = function(evt) {
elt_ref[s].value = evt.target.result
src_change()
}
reader.readAsText(data[0],"UTF-8")
// return
}
}
|
| ︙ | ︙ |
Changes to editor/edit.xhtml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="edit-@MAJOR@.css" rel="stylesheet" type="text/css"/>
<script src="edit-@MAJOR@.js" type="text/javascript" async="true"></script>
<script src="abc2svg-@MAJOR@.js" type="text/javascript" async="true"></script>
<title>ABC edit with abc2svg</title>
</head>
<body ontouchstart="" bgcolor="#faf0e6">
<!-- left -->
<div id="dleft">
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="edit-@MAJOR@.css" rel="stylesheet" type="text/css"/>
<script src="edit-@MAJOR@.js" type="text/javascript" async="true"></script>
<script src="abc2svg-@MAJOR@.js" type="text/javascript" async="true"></script>
<script src="pref.js" type="text/javascript" async="true"></script>
<title>ABC edit with abc2svg</title>
</head>
<body ontouchstart="" bgcolor="#faf0e6">
<!-- left -->
<div id="dleft">
|
| ︙ | ︙ | |||
61 62 63 64 65 66 67 |
<li onclick="loadlang('pt_BR')">Português do Brasil</li>
</ul>
</li>
<li class="dropbutton"><label id="h">Help</label>
<ul class="droplinks">
<li id="ha" onclick="popshow('help', true)">Help</li>
<li><a id="df" target="_blank"
| | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<li onclick="loadlang('pt_BR')">Português do Brasil</li>
</ul>
</li>
<li class="dropbutton"><label id="h">Help</label>
<ul class="droplinks">
<li id="ha" onclick="popshow('help', true)">Help</li>
<li><a id="df" target="_blank"
href="http://moinejf.free.fr/abcm2ps-doc/features.html">abc2svg features</a>
</li>
<li><a id="dp" target="_blank"
href="http://moinejf.free.fr/abcm2ps-doc/index.html">abc2svg parameters</a>
</li>
<li id="a" onclick="popshow('about', true)">About</li>
</ul>
</li>
|
| ︙ | ︙ | |||
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | </p> <textarea id="source" rows="40" cols="73" wrap="off" style="font: 14px monospace" ondrop="drop(event)" ondragenter="drag_enter(event)" oninput="src_change()"></textarea> <textarea id="src1" rows="40" cols="73" wrap="off" style="font: 14px monospace; display: none" oninput="src_change()"></textarea> </div> <!-- right - needed for the scrollbars --> <div id="dright"> <!-- context menu --> <div id="ctxMenu" title="Play"> <ul class="droplinks"> | > | > | 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 | </p> <textarea id="source" rows="40" cols="73" wrap="off" style="font: 14px monospace" ondrop="drop(event)" ondragenter="drag_enter(event)" oninput="src_change()"></textarea> <textarea id="src1" rows="40" cols="73" wrap="off" style="font: 14px monospace; display: none" ondrop="drop(event)" ondragenter="drag_enter(event)" oninput="src_change()"></textarea> </div> <!-- right - needed for the scrollbars --> <div id="dright"> <!-- context menu --> <div id="ctxMenu" title="Play"> <ul class="droplinks"> <!-- 'All' does not work anymore <li id="cmpa" onclick="play_tune(-1)" style="display:none">All</li> --> <li id="cmpt" onclick="play_tune(0)">Tune</li> <li id="cmps" onclick="play_tune(1)">Selection</li> <li id="cmpl" onclick="play_tune(2)">Loop</li> <li id="cmpc" onclick="play_tune(3)">Continue</li> </ul> </div> |
| ︙ | ︙ |
Changes to err-de.js.
| ︙ | ︙ | |||
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 |
"'$1:' line ignored": "'$1:' Zeile ignoriert",
"$1: inside tune - ignored": "$1: innerhalb der Stimme ignoriert",
"!$1! must be on a note": "!$1! muss an einer Note stehen",
"!$1! must be on a note or a rest": "!$1! muss an einer Note oder Pause stehen",
"!$1! must be on the last of a couple of notes": "!$1! muss an der letzten Notengruppe stehen",
"!beamon! must be on a bar": "!beamon! muss an einem Taktstrich stehen",
"%%deco: abnormal h/wl/wr value '$1'": "%%deco: falscher Wert '$1' für h/wl/wr",
"%%deco: bad C function index '$1'": "%%deco: falscher C Funktionsindex '$1'",
"%%deco: bad C function value '$1'": "%%deco: falscher C Funtionswert '$1'",
"%%multicol end without start": "%%multicol end ohne start",
"%%multicol new without start": "%%multicol new ohne start",
"%%repeat cannot start a tune": "%%repeat kann nicht am Anfang einer Stimme stehen",
"%%staffwidth too big": "%%staffwidth zu groß",
"%%staffwidth too small": "%%staffwidth zu klein",
"%%tune not treated yet": "%%tune noch nicht behandelt",
"%%vskip cannot be negative": "%%vskip kann nicht negativ sein",
"Bad !xstem!": "!xstem! fehlerhaft",
"Bad %%setbarnb value": "fehlerhaft Wert für %%setbarnb",
"Bad %%staff number $1 (cur $2, max $3)": "falsche %%staff Nummer $1 (cur $2, max $3)",
"Bad %%staff value '$1'": "fehlerhafte %%staff Nummer '$1'",
"Bad %%stafflines value": "fehlerhafter Wert für %%stafflines",
"Bad %%staffscale value": "fehlerhafter Wert für %%staffscale",
"Bad char '$1' in M:": "fehlerhaftes Zeichen '$1' in M:",
"Bad character '$1'": "fehlerhaftes Zeichen '$1'",
"Bad character in grace note sequence":
"fehlerhaftes Zeichen in Sequenz von Vorschlagnoten",
"Bad controller number in %%MIDI": "Bad controller number in %%MIDI",
"Bad controller value in %%MIDI": "Bad controller value in %%MIDI",
"Bad duration '$1' in M:": "fehlerhafte Dauer '$1' in M:",
"Bad integer value": "fehlerhafte Ganzzahl",
"Bad instr= value": "fehlerhafter Wert für instr=",
"Bad L: value": "fehlerhafter Wert für L:",
"Bad measure duration": "Bad measure duration",
"Bad note in %%map": "fehlerhafte Note in %%map",
"Bad page width": "fehlerhafte Seitenbreite",
"Bad program in %%MIDI": "falsches Program in %%MIDI",
"Bad scale value in %%font": "fehlerhafter Wert für scale in %%font",
"Bad tempo value": "fehlerhafter Wert für tempo",
"Bad tie": "fehlerhafter Haltebogen",
"Bad transpose value": "fehlerhafter Wert für transpose",
"Bad user character '$1'": "falsches benutzerdefiniertes Zeichen '$1' in U:/%%user",
"Bad value '$1' in %%linebreak - ignored": "fehlerhafter Wert '$1' in %%linebreak - ignoriert",
"Bad value in $1": "fehlerhafter Wert in $1",
"Bad voice ID in %%score": "fehlerhafte ID für Stimme in %%score",
"Bar in repeat sequence": "Taktstrich in Wiederholungssequenz",
"Cannot have !$1! on a head": "!$1! im Kopfbereich nicht erlaubt",
"Cannot have '$1' inside a tune": "'$1' innerhalb einer Stimme nicht erlaubt",
"Cannot have a bar in grace notes": "Taktstrich in Vorschlagnote nicht erlaubt",
"Cannot have a broken rhythm in grace notes": "gebrochener Rythmus in Ziernoten nicht erlaubt",
"Cannot have V:* in tune body": "V:* im Notenbereich nicht erlaubt",
"Cannot read file '$1'": "File '$1' kann nicht gelesen werden",
"Decoration ignored": "Dekoration ignoriert",
"Empty line in tune header - ignored": "Leerzeile in Kopfbereich - ignoriert",
"End of slur without start": "End of slur without start",
"Erroneous end of voice overlay":
"Fehlerhaftes Ende einer Stimme in Stimm-Überlagerung",
"Error loading the module $1": "Error loading the module $1",
"Incorrect 1st value in %%repeat": "erster Wert fehlerhaft in %%repeat",
"Incorrect 2nd value in %%repeat": "zweiter Wert fehlerhaft in %%repeat",
"Invalid 'r' in tuplet": "'r' fehlerhaft in Tuplet",
"Invalid decoration '$1'": "fehlerhafte Dekoration '$1'",
"Invalid note duration $1": "Fehlerhafte Notendekoration '$1'",
"Lack of ']'": "']' fehlt",
"Lack of bar after multi-measure rest":
"Lack of bar after multi-measure rest",
"Lack of ending slur(s)": "Lack of ending slur(s)",
"Lack of starting [, ! or \" in U: / %%user":
"[, ! or \" fehlt in U: / %%user",
"Line split problem - adjust maxshrink and/or breaklimit":
"Probleme beim Aufteilen der Zeile - justiere maxshrink und/oder breaklimit",
"Line too much shrunk $1 $2 $3": "Zeile zu stark geschrumpft $1 $2 $3",
"Line underfull ($1pt of $2pt)": "Zeile nicht voll genug ($1pt of $2pt)",
"Misplaced '$1' in %%score": "'$1' fehlerhaft platziert in %%score",
"Misplaced dot": "fehlerhaft platzierter Punkt",
"Mix of old and new transposition syntaxes":
"Mix von alter und neuer Transponierungs-syntax",
"No $1 after %%$2": "kein $1 nach %%$2",
"No </defs> in %%beginsvg sequence": "kein </defs> in %%beginsvg squenz",
"No </style> in %%beginsvg sequence": "kein </style> in %%beginsvg sequenz",
"No accidental after 'exp'": "kein Vorzeichen nach 'exp'",
"No end of decoration": "kein Ende der Dekoration",
"No end of grace note sequence": "kein Ende der Vorschlagnoten",
| > > > > > > > > > > > > > | > > > > > > > | 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 |
"'$1:' line ignored": "'$1:' Zeile ignoriert",
"$1: inside tune - ignored": "$1: innerhalb der Stimme ignoriert",
"!$1! must be on a note": "!$1! muss an einer Note stehen",
"!$1! must be on a note or a rest": "!$1! muss an einer Note oder Pause stehen",
"!$1! must be on the last of a couple of notes": "!$1! muss an der letzten Notengruppe stehen",
"!beamon! must be on a bar": "!beamon! muss an einem Taktstrich stehen",
"%%deco: abnormal h/wl/wr value '$1'": "%%deco: falscher Wert '$1' für h/wl/wr",
"%%combinevoices is deprecated - use %%voicecombine instead":
"%%combinevoices is deprecated - use %%voicecombine instead",
"%%deco: bad C function index '$1'": "%%deco: falscher C Funktionsindex '$1'",
"%%deco: bad C function value '$1'": "%%deco: falscher C Funtionswert '$1'",
"%%multicol end without start": "%%multicol end ohne start",
"%%multicol new without start": "%%multicol new ohne start",
"%%repeat cannot start a tune": "%%repeat kann nicht am Anfang einer Stimme stehen",
"%%staffwidth too big": "%%staffwidth zu groß",
"%%staffwidth too small": "%%staffwidth zu klein",
"%%tune not treated yet": "%%tune noch nicht behandelt",
"%%vskip cannot be negative": "%%vskip kann nicht negativ sein",
"Bad !xstem!": "!xstem! fehlerhaft",
"Bad %%setbarnb value": "fehlerhaft Wert für %%setbarnb",
"Bad %%staff number $1 (cur $2, max $3)": "falsche %%staff Nummer $1 (cur $2, max $3)",
"Bad %%staff value '$1'": "fehlerhafte %%staff Nummer '$1'",
"Bad %%stafflines value": "fehlerhafter Wert für %%stafflines",
"Bad %%staffnonote value": "Bad %%staffnonote value",
"Bad %%staffscale value": "fehlerhafter Wert für %%staffscale",
"Bad char '$1' in M:": "fehlerhaftes Zeichen '$1' in M:",
"Bad character '$1'": "fehlerhaftes Zeichen '$1'",
"Bad character in grace note sequence":
"fehlerhaftes Zeichen in Sequenz von Vorschlagnoten",
"Bad controller number in %%MIDI": "Bad controller number in %%MIDI",
"Bad controller value in %%MIDI": "Bad controller value in %%MIDI",
"Bad duration '$1' in M:": "fehlerhafte Dauer '$1' in M:",
"Bad integer value": "fehlerhafte Ganzzahl",
"Bad instr= value": "fehlerhafter Wert für instr=",
"Bad L: value": "fehlerhafter Wert für L:",
"Bad length of the macro sequence": "Bad length of the macro sequence",
"Bad measure duration": "Bad measure duration",
"Bad note in %%map": "fehlerhafte Note in %%map",
"Bad page width": "fehlerhafte Seitenbreite",
"Bad program in %%MIDI": "falsches Program in %%MIDI",
"Bad scale value in %%font": "fehlerhafter Wert für scale in %%font",
"Bad strings in tablature": "Bad strings in tablature",
"Bad tempo value": "fehlerhafter Wert für tempo",
"Bad tie": "fehlerhafter Haltebogen",
"Bad transpose value": "fehlerhafter Wert für transpose",
"Bad user character '$1'": "falsches benutzerdefiniertes Zeichen '$1' in U:/%%user",
"Bad value '$1' in %%linebreak - ignored": "fehlerhafter Wert '$1' in %%linebreak - ignoriert",
"Bad value in $1": "fehlerhafter Wert in $1",
"Bad voice ID in %%score": "fehlerhafte ID für Stimme in %%score",
"Bar in repeat sequence": "Taktstrich in Wiederholungssequenz",
"Cannot have !$1! on a head": "!$1! im Kopfbereich nicht erlaubt",
"Cannot have '$1' inside a tune": "'$1' innerhalb einer Stimme nicht erlaubt",
"Cannot have %%beginml with %%pageheight":
"Cannot have %%beginml with %%pageheight",
"Cannot have a bar in grace notes": "Taktstrich in Vorschlagnote nicht erlaubt",
"Cannot have a broken rhythm in grace notes": "gebrochener Rythmus in Ziernoten nicht erlaubt",
"Cannot have V:* in tune body": "V:* im Notenbereich nicht erlaubt",
"Cannot read file '$1'": "File '$1' kann nicht gelesen werden",
"Decoration ignored": "Dekoration ignoriert",
"Decoration without symbol": "Decoration without symbol",
"Double voice in %%score": "Double voice in %%score",
"Empty line in tune header - ignored": "Leerzeile in Kopfbereich - ignoriert",
"End of slur without start": "End of slur without start",
"Erroneous end of voice overlay":
"Fehlerhaftes Ende einer Stimme in Stimm-Überlagerung",
"Error in %%pos": "Error in %%pos",
"Error loading the module $1": "Error loading the module $1",
"Incorrect 1st value in %%repeat": "erster Wert fehlerhaft in %%repeat",
"Incorrect 2nd value in %%repeat": "zweiter Wert fehlerhaft in %%repeat",
"Invalid 'r' in tuplet": "'r' fehlerhaft in Tuplet",
"Invalid decoration '$1'": "fehlerhafte Dekoration '$1'",
"Invalid note duration $1": "Fehlerhafte Notendekoration '$1'",
"K:P is deprecated": "K:P is deprecated",
"Lack of ']'": "']' fehlt",
"Lack of bar after multi-measure rest":
"Lack of bar after multi-measure rest",
"Lack of ending slur(s)": "Lack of ending slur(s)",
"Lack of starting [, ! or \" in U: / %%user":
"[, ! or \" fehlt in U: / %%user",
"Line split problem - adjust maxshrink and/or breaklimit":
"Probleme beim Aufteilen der Zeile - justiere maxshrink und/oder breaklimit",
"Line too much shrunk $1 $2 $3": "Zeile zu stark geschrumpft $1 $2 $3",
"Line underfull ($1pt of $2pt)": "Zeile nicht voll genug ($1pt of $2pt)",
"Microtone transposition not coded":
"Microtone transposition not coded",
"Misplaced '$1' in %%score": "'$1' fehlerhaft platziert in %%score",
"Misplaced dot": "fehlerhaft platzierter Punkt",
"Mix of old and new transposition syntaxes":
"Mix von alter und neuer Transponierungs-syntax",
"No $1 after %%$2": "kein $1 nach %%$2",
"No </defs> in %%beginsvg sequence": "kein </defs> in %%beginsvg squenz",
"No </style> in %%beginsvg sequence": "kein </style> in %%beginsvg sequenz",
"No accidental after 'exp'": "kein Vorzeichen nach 'exp'",
"No end of decoration": "kein Ende der Dekoration",
"No end of grace note sequence": "kein Ende der Vorschlagnoten",
"No end of chord symbol/annotation": "kein Ende des Akkordsymbols",
"No end of repeat string": "kein Ende des Wiederholungszeichens",
"No end of string in font family": "No end of string in font family",
"No end of tuplet": "kein Ende des Tuplets",
"No end of tuplet in this music line":
"Kein Ende des Tuplets in dieser Zeile",
"No end of url in font family": "No end of url in font family",
"No end of voice overlay": "kein Ende der Stimmüberlagerung",
"No function for decoration '$1'": "keine Funktion für Dekoration '$1'",
"No note before '-'": "keine Note vor '-'",
"No note before '<'": "keine Note vor '<'",
"No note in voice overlay": "keine Note in Stimmüberlagerung",
// "Non standard note duration $1": "??",
"No read_file support": "Einlesen von Files nicht unterstützt",
"No start of !$1!": "kein Start von !$1!",
"Not an ASCII character": "kein ASCII - Zeichen",
"Not enough measure bars for lyric line": "nicht genug Takte für Liedtextzeile",
"Not enough measure bars for symbol line":
"Nicht genügend Takte für eine Symbolzeile",
"Not enough measures for %%repeat": "nicht genug Takte für %%repeat",
"Not enough parameters in %%map": "nicht genug Parameter in %%map",
"Not enough symbols after repeat sequence": "nicht genug Symbole nach einer Wiederholungssequenz",
"Not enough notes/rests for %%repeat": "nicht genug Noten/Pausen für %%repeat",
"Note too long": "Note zu lang",
"Note too short": "Note zu kurz",
"Start of slur without note": "Start of slur without note",
"s: without music": "s: ohne Musik",
"Too many elements in symbol line": "zu viele elemente in einer Symbolzeile",
"Too many include levels": "Verschachtelung für include zu tief",
"There cannot be chord symbols on measure bars":
"There cannot be chord symbols on measure bars",
"Too many ties": "zu viele Haltebogen",
"Too many words in lyric line": "zu viele Worte in Liedtextzeile",
"Unknown bagpipe-like key": "unbekante Dudelsackartige Tonart",
"Unknown clef '$1'": "unbekannter Schlüssel '$1'",
"Unknown decoration '$1'": "unbekannte Dekoration '$1'",
"Unknown font $1": "unbekannte Schriftart '$1'",
"Unknown glyph: '$1'": "Unbekanntes Schriftsybol '$1'",
"Unknown keyword '$1' in %%multicol": "unbekanntes Schlüsselwort '$1' in %%multicol",
"Unsecure code": "Unsicherer Code",
"Unterminated string": "nicht abgeschlossene Zeichenkette",
"Unterminated string in Q:": "nicht abgeschlossene Zeichenkette in Q:",
"Variant ending on a left repeat bar":
"Variant ending on a left repeat bar",
"Voice overlay already started": "Stimmüberlagerung bereits gestartet",
"w: without music": "w: ohne Noten",
"Wrong duration in voice overlay": "fehlerhafte Notenwerte in Stimmüberlagerung"
}
|
Changes to err-fr.js.
| ︙ | ︙ | |||
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 | "$1: inside tune - ignored": "$1: en milieu de morceau - ignoré", "!$1! must be on a note": "!$1! doit être sur une note", "!$1! must be on a note or a rest": "!$1! doit être sur une note ou un silence", "!$1! must be on the last of a couple of notes": "!$1! doit être sur la 2ème note d'un couple", "!beamon! must be on a bar": "!beamon! doit être sur une barre", "%%deco: abnormal h/wl/wr value '$1'": "%%deco: valeur '$1' anormale pour h/wl/wr", "%%deco: bad C function index '$1'": "%%deco: mauvais index de fonction '$1'", "%%deco: bad C function value '$1'": "%%deco: mauvaise valeur de fonction '$1'", "%%multicol end without start": "%%multicol end sans start", "%%multicol new without start": "%%multicol new sans start", "%%repeat cannot start a tune": "%%repeat ne peut pas être en début de morceau", "%%staffwidth too big": "%%staffwidth trop grand", "%%staffwidth too small": "%%staffwidth trop petit", "%%tune not treated yet": "%%tune n'est pas encore traité", "%%vskip cannot be negative": "%%vskip ne peut pas être négatif", "Bad !xstem!": "!xstem! erroné", "Bad %%setbarnb value": "Valeur incorrecte dans %%setbarnb", "Bad %%staff number $1 (cur $2, max $3)": "Numéro %%staff $1 incorrect (cur $2, max $3)", "Bad %%staff value '$1'": "Valeur incorrecte '$1' dans %%staff", "Bad %%stafflines value": "Valeur incorrecte dans %%stafflines", "Bad %%staffscale value": "Valeur incorrecte dans %%staffscale", "Bad char '$1' in M:": "Mauvais caractère '$1' dans M:", "Bad character '$1'": "Mauvais caractère '$1'", "Bad character in grace note sequence": "Caractère incorrect dans notes d'agrément", "Bad controller number in %%MIDI": "Mauvais numéro de controleur dans %%MIDI", "Bad controller value in %%MIDI": "Mauvaise valeur de controle dans %%MIDI", "Bad duration '$1' in M:": "Durée '$1' incorrecte dans M:", "Bad integer value": "Mauvaise valeur entière", "Bad instr= value": "Mauvaise valeur de instr=", "Bad L: value": "Mauvaise valeur pour L:", "Bad measure duration": "Mauvaise durée de la mesure", "Bad note in %%map": "Note incorrecte dans %%map", "Bad page width": "Mauvaise largeur de page", "Bad program in %%MIDI": "Mauvais 'program' dans %%MIDI", "Bad scale value in %%font": "Mauvaise échelle dans %%font", "Bad tempo value": "Mauvaise valeur de tempo", "Bad tie": "Mauvaise liaison de prolongation", "Bad transpose value": "Mauvaise valeur de transposition", "Bad user character '$1'": "Caractère illégal '$1' dans U:/%%user", "Bad value '$1' in %%linebreak - ignored": "Valeur incorrecte '$1' dans %%linebreak - ignorée", "Bad value in $1": "Mauvaise valeur dans $1", "Bad voice ID in %%score": "Mauvaise identité de voix dans %%score", "Bar in repeat sequence": "Barre dans la séquence à répéter", "Cannot have !$1! on a head": "!$1! ne peut pas être sur une tête de note", "Cannot have '$1' inside a tune": "'$1' ne peut pas être dans un morceau", "Cannot have a bar in grace notes": "Il ne peut pas y avoir de barre dans les notes d'agrément", "Cannot have a broken rhythm in grace notes": "Il ne peut pas y avoir '<' ou '>' dans les notes d'agrément", "Cannot have V:* in tune body": "Il ne peut pas y avoir V:* dans le corps du morceau", "Cannot read file '$1'": "Fichier '$1' inexistant", "Decoration ignored": "Décoration ignorée", "Empty line in tune header - ignored": "Ligne vide dans en-tête de morceau - ignorée", "End of slur without start": "Fin de liaison sans début", "Erroneous end of voice overlay": "Fin de superposition de voix erronée", "Error loading the module $1": "Erreur de chargement du module $1", "Incorrect 1st value in %%repeat": "Première valeur incorrecte dans %%repeat", "Incorrect 2nd value in %%repeat": "Deuxième valeur incorrecte dans %%repeat", "Invalid 'r' in tuplet": "'r' invalide dans le tuplet", "Invalid decoration '$1'": "Décoration '$1' invalide", "Invalid note duration $1": "Durée de note $1 invalide", "Lack of ']'": "']' manquant", "Lack of bar after multi-measure rest": "Manque de barre de mesure après silence multiple", "Lack of ending slur(s)": "Pas de fin de liaison(s)", 'Lack of starting [, ! or " in U: / %%user': 'U: / %%user ne commence pas par [, ! ou "', "Line split problem - adjust maxshrink and/or breaklimit": "Problème de découpe en lignes - ajuster maxshrink et/ou breaklimit", "Line too much shrunk $1 $2 $3": "Ligne trop compressée $1 $2 $3", "Line underfull ($1pt of $2pt)": "Trop d'espacement ($1pt of $2pt)", "Misplaced '$1' in %%score": "'$1' mal placé dans %%score", "Misplaced dot": "Point mal placé", "Mix of old and new transposition syntaxes": "Mélange des syntaxes de transposition ancienne et nouvelle", "No $1 after %%$2": "Pas de $1 après %%$2", "No </defs> in %%beginsvg sequence": "Pas de </defs> dans séquence %%beginsvg", "No </style> in %%beginsvg sequence": "Pas de </style> dans séquence %%beginsvg", "No accidental after 'exp'": "Pas d'altération après 'exp'", "No end of decoration": "Pas de fin de décoration", "No end of grace note sequence": "Pas de fin de notes d'agrément", | > > > > > > > > > > > > > | > > > | 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 | "$1: inside tune - ignored": "$1: en milieu de morceau - ignoré", "!$1! must be on a note": "!$1! doit être sur une note", "!$1! must be on a note or a rest": "!$1! doit être sur une note ou un silence", "!$1! must be on the last of a couple of notes": "!$1! doit être sur la 2ème note d'un couple", "!beamon! must be on a bar": "!beamon! doit être sur une barre", "%%combinevoices is deprecated - use %%voicecombine instead": "%%combinevoices est déprécié - remplacer par %%voicecombine", "%%deco: abnormal h/wl/wr value '$1'": "%%deco: valeur '$1' anormale pour h/wl/wr", "%%deco: bad C function index '$1'": "%%deco: mauvais index de fonction '$1'", "%%deco: bad C function value '$1'": "%%deco: mauvaise valeur de fonction '$1'", "%%multicol end without start": "%%multicol end sans start", "%%multicol new without start": "%%multicol new sans start", "%%repeat cannot start a tune": "%%repeat ne peut pas être en début de morceau", "%%staffwidth too big": "%%staffwidth trop grand", "%%staffwidth too small": "%%staffwidth trop petit", "%%tune not treated yet": "%%tune n'est pas encore traité", "%%vskip cannot be negative": "%%vskip ne peut pas être négatif", "Bad !xstem!": "!xstem! erroné", "Bad %%setbarnb value": "Valeur incorrecte dans %%setbarnb", "Bad %%staff number $1 (cur $2, max $3)": "Numéro %%staff $1 incorrect (cur $2, max $3)", "Bad %%staff value '$1'": "Valeur incorrecte '$1' dans %%staff", "Bad %%stafflines value": "Valeur incorrecte dans %%stafflines", "Bad %%staffnonote value": "Valeur incorrecte dans %%staffnonote", "Bad %%staffscale value": "Valeur incorrecte dans %%staffscale", "Bad char '$1' in M:": "Mauvais caractère '$1' dans M:", "Bad character '$1'": "Mauvais caractère '$1'", "Bad character in grace note sequence": "Caractère incorrect dans notes d'agrément", "Bad controller number in %%MIDI": "Mauvais numéro de controleur dans %%MIDI", "Bad controller value in %%MIDI": "Mauvaise valeur de controle dans %%MIDI", "Bad duration '$1' in M:": "Durée '$1' incorrecte dans M:", "Bad integer value": "Mauvaise valeur entière", "Bad instr= value": "Mauvaise valeur de instr=", "Bad L: value": "Mauvaise valeur pour L:", "Bad length of the macro sequence": "Mauvaise durée de la séquence macro", "Bad measure duration": "Mauvaise durée de la mesure", "Bad note in %%map": "Note incorrecte dans %%map", "Bad page width": "Mauvaise largeur de page", "Bad program in %%MIDI": "Mauvais 'program' dans %%MIDI", "Bad scale value in %%font": "Mauvaise échelle dans %%font", "Bad strings in tablature": "Mauvaise valeur dans la tablature", "Bad tempo value": "Mauvaise valeur de tempo", "Bad tie": "Mauvaise liaison de prolongation", "Bad transpose value": "Mauvaise valeur de transposition", "Bad user character '$1'": "Caractère illégal '$1' dans U:/%%user", "Bad value '$1' in %%linebreak - ignored": "Valeur incorrecte '$1' dans %%linebreak - ignorée", "Bad value in $1": "Mauvaise valeur dans $1", "Bad voice ID in %%score": "Mauvaise identité de voix dans %%score", "Bar in repeat sequence": "Barre dans la séquence à répéter", "Cannot have !$1! on a head": "!$1! ne peut pas être sur une tête de note", "Cannot have '$1' inside a tune": "'$1' ne peut pas être dans un morceau", "Cannot have %%beginml with %%pageheight": "On ne peut pas avoir %%beginml avec %%pageheight", "Cannot have a bar in grace notes": "Il ne peut pas y avoir de barre dans les notes d'agrément", "Cannot have a broken rhythm in grace notes": "Il ne peut pas y avoir '<' ou '>' dans les notes d'agrément", "Cannot have V:* in tune body": "Il ne peut pas y avoir V:* dans le corps du morceau", "Cannot read file '$1'": "Fichier '$1' inexistant", "Decoration ignored": "Décoration ignorée", "Decoration without symbol": "Pas de symbole où mettre la décoration", "Double voice in %%score": "Voix en double dans %%score", "Empty line in tune header - ignored": "Ligne vide dans en-tête de morceau - ignorée", "End of slur without start": "Fin de liaison sans début", "Erroneous end of voice overlay": "Fin de superposition de voix erronée", "Error in %%pos": "Erreur dans %%pos", "Error loading the module $1": "Erreur de chargement du module $1", "Incorrect 1st value in %%repeat": "Première valeur incorrecte dans %%repeat", "Incorrect 2nd value in %%repeat": "Deuxième valeur incorrecte dans %%repeat", "Invalid 'r' in tuplet": "'r' invalide dans le tuplet", "Invalid decoration '$1'": "Décoration '$1' invalide", "Invalid note duration $1": "Durée de note $1 invalide", "K:P is deprecated": "K:P est déprécié", "Lack of ']'": "']' manquant", "Lack of bar after multi-measure rest": "Manque de barre de mesure après silence multiple", "Lack of ending slur(s)": "Pas de fin de liaison(s)", 'Lack of starting [, ! or " in U: / %%user': 'U: / %%user ne commence pas par [, ! ou "', "Line split problem - adjust maxshrink and/or breaklimit": "Problème de découpe en lignes - ajuster maxshrink et/ou breaklimit", "Line too much shrunk $1 $2 $3": "Ligne trop compressée $1 $2 $3", "Line underfull ($1pt of $2pt)": "Trop d'espacement ($1pt of $2pt)", "Microtone transposition not coded": "Transposition de microtonalité pas codée", "Misplaced '$1' in %%score": "'$1' mal placé dans %%score", "Misplaced dot": "Point mal placé", "Mix of old and new transposition syntaxes": "Mélange des syntaxes de transposition ancienne et nouvelle", "No $1 after %%$2": "Pas de $1 après %%$2", "No </defs> in %%beginsvg sequence": "Pas de </defs> dans séquence %%beginsvg", "No </style> in %%beginsvg sequence": "Pas de </style> dans séquence %%beginsvg", "No accidental after 'exp'": "Pas d'altération après 'exp'", "No end of decoration": "Pas de fin de décoration", "No end of grace note sequence": "Pas de fin de notes d'agrément", "No end of chord symbol/annotation": "Pas de fin d'accord/annotation", "No end of repeat string": "Chaine de répétition non terminée", "No end of string in font family": "Pas de fin de chaine dans le nom de famille de la police", "No end of tuplet": "Pas de fin de tuplet", "No end of tuplet in this music line": "Pas de fin de tuplet dans cette ligne de musique", "No end of url in font family": "Pas de fin de l'url de la police", "No end of voice overlay": "Pas de fin de superposition de voix", "No function for decoration '$1'": "Pas de fonction pour décoration '$1'", "No note before '-'": "Pas de note devant '-'", "No note before '<'": "Pas de note devant '<'", "No note in voice overlay": "Pas de note dans voix superposée", "Non standard note duration $1": "Durée de note $1 non standard", "No read_file support": "La fonction read_file n'existe pas", |
| ︙ | ︙ | |||
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 | "Pas assez de mesures pour %%repeat", "Not enough parameters in %%map": "Pas assez de paramètres dans %%map", "Not enough notes/rests for %%repeat": "Pas assez de notes/silences pour %%repeat", "Note too long": "Durée de note trop longue", "Note too short": "Durée de note trop courte", "s: without music": "s: sans musique", "Too many elements in symbol line": "Trop d'éléments dans ligne s:", "Too many include levels": "Trop de niveaux d'inclusion de fichier", "Too many ties": "Trop de liaisons de prolongation", "Too many words in lyric line": "Trop de mots dans la ligne de paroles", "Unknown bagpipe-like key": "Armature de cornemuse inconnue", "Unknown clef '$1'": "Clé '$1' inconnue", "Unknown decoration '$1'": "Décoration '$1' inconnue", "Unknown font $1": "Police $1 inconnue", "Unknown glyph: '$1'": "Glyph '$1' inconnu", "Unknown keyword '$1' in %%multicol": "Mot clé '$1' inconnu dans %%multicol", "Unsecure code": "Code dangereux", "Unterminated string": "Chaine de caractères non terminée", "Unterminated string in Q:": "Chaine de caractères non terminée dans Q:", "Voice overlay already started": "Superposition de voix déjà démarrée", "w: without music": "w: sans musique", "Wrong duration in voice overlay": "Mauvaise durée de la voix superposée" } | > > > > > | 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 | "Pas assez de mesures pour %%repeat", "Not enough parameters in %%map": "Pas assez de paramètres dans %%map", "Not enough notes/rests for %%repeat": "Pas assez de notes/silences pour %%repeat", "Note too long": "Durée de note trop longue", "Note too short": "Durée de note trop courte", "Start of slur without note": "Début de liaison sans note", "s: without music": "s: sans musique", "There cannot be chord symbols on measure bars": "On ne peut pas mettre d'indication d'accord sur une barre de mesure", "Too many elements in symbol line": "Trop d'éléments dans ligne s:", "Too many include levels": "Trop de niveaux d'inclusion de fichier", "Too many ties": "Trop de liaisons de prolongation", "Too many words in lyric line": "Trop de mots dans la ligne de paroles", "Unknown bagpipe-like key": "Armature de cornemuse inconnue", "Unknown clef '$1'": "Clé '$1' inconnue", "Unknown decoration '$1'": "Décoration '$1' inconnue", "Unknown font $1": "Police $1 inconnue", "Unknown glyph: '$1'": "Glyph '$1' inconnu", "Unknown keyword '$1' in %%multicol": "Mot clé '$1' inconnu dans %%multicol", "Unsecure code": "Code dangereux", "Unterminated string": "Chaine de caractères non terminée", "Unterminated string in Q:": "Chaine de caractères non terminée dans Q:", "Variant ending on a left repeat bar": "Variante sur la barre de début de séquence répétée", "Voice overlay already started": "Superposition de voix déjà démarrée", "w: without music": "w: sans musique", "Wrong duration in voice overlay": "Mauvaise durée de la voix superposée" } |
Changes to err-it.js.
| ︙ | ︙ | |||
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 | "$1: inside tune - ignored": "$1: nel corpo del brano - ignorato", "!$1! must be on a note": "!$1! deve stare su di una nota", "!$1! must be on a note or a rest": "!$1! deve stare su una nota o su una pausa", "!$1! must be on the last of a couple of notes": "!$1! deve stare sulla seconda di due note", "!beamon! must be on a bar": "!beamon! deve stare su una stanghetta", "%%deco: abnormal h/wl/wr value '$1'": "%%deco: valore '$1' illegale per h/wl/wr", "%%deco: bad C function index '$1'": "%%deco: indice errato per la funzione C '$1'", "%%deco: bad C function value '$1'": "%%deco: valore errato per la funzione C '$1'", "%%multicol end without start": "%%multicol end senza start", "%%multicol new without start": "%%multicol new senza start", "%%repeat cannot start a tune": "%%repeat non può stare all'inizio del brano", "%%staffwidth too big": "%%staffwidth troppo grande", "%%staffwidth too small": "%%staffwidth troppo piccolo", "%%tune not treated yet": "%%tune non ancora gestito", "%%vskip cannot be negative": "%%vskip non può essere negativo", "Bad !xstem!": "!xstem! errato", "Bad %%setbarnb value": "Valore errato in %%setbarnb", "Bad %%staff number $1 (cur $2, max $3)": "Numero $1 in %%staff errato (attuale $2, max $3)", "Bad %%staff value '$1'": "Valore errato '$1' in %%staff", "Bad %%stafflines value": "Valore errato in %%stafflines", "Bad %%staffscale value": "Valore errato in %%staffscale", "Bad char '$1' in M:": "Carattere errato '$1' in M:", "Bad character '$1'": "Carattere errato '$1'", "Bad character in grace note sequence": "Carattere errato nelle note di abbellimento", "Bad controller number in %%MIDI": "Numero errato del controller in %%MIDI", "Bad controller value in %%MIDI": "Valore errato del controller in %%MIDI", "Bad duration '$1' in M:": "Durata '$1' errata in M:", "Bad integer value": "Valore intero errato", "Bad instr= value": "Valore errato di instr=", "Bad L: value": "Valore errato per L:", "Bad measure duration": "Bad measure duration", "Bad note in %%map": "Nota errata in %%map", "Bad page width": "Larghezza di pagina errata", "Bad program in %%MIDI": "Numero di programma non valido in %%MIDI", "Bad scale value in %%font": "Valore di scala non valido in %%font", "Bad tempo value": "Bad tempo value", "Bad tie": "Legatura non valida", "Bad transpose value": "Valore non valido per la trasposizione", "Bad user character '$1'": "Carattere illegale '$1' in U:/%%user", "Bad value '$1' in %%linebreak - ignored": "Valore errato '$1' in %%linebreak - ignorato", "Bad value in $1": "Valore errato in $1", "Bad voice ID in %%score": "ID di voce non valido in %%score", "Bar in repeat sequence": "Stanghetta in sequenza ripetuta", "Cannot have !$1! on a head": "!$1! non è consentito su una nota", "Cannot have '$1' inside a tune": "'$1' non è consentito entro il brano", "Cannot have a bar in grace notes": "Stanghette non consentite nelle note di abbellimento", "Cannot have a broken rhythm in grace notes": "'Broken rhythm' non consentito nelle note di abbellimento", "Cannot have V:* in tune body": "V:* non consentito nel corpo del brano", "Cannot read file '$1'": "File '$1' inesistente", "Decoration ignored": "Decorazione ignorata", "Empty line in tune header - ignored": "Linea vuota nella testata - ignorata", "End of slur without start": "End of slur without start", "Erroneous end of voice overlap": "Fine di voice overlay errata", "Error loading the module $1": "Error loading the module $1", "Incorrect 1st value in %%repeat": "Primo valore in %%repeat errato", "Incorrect 2nd value in %%repeat": "Secondo valore in %%repeat errato", "Invalid 'r' in tuplet": "'r' non valido in gruppo irregolare", "Invalid decoration '$1'": "Decorazione '$1' non valida", "Invalid note duration $1": "Durée de note $1 non valida", "Lack of ']'": "']' mancante", "Lack of bar after multi-measure rest": "Lack of bar after multi-measure rest", "Lack of ending slur(s)": "Lack of ending slur(s)", 'Lack of starting [, ! or " in U: / %%user': 'U: / %%user non inizia con [, ! o "', "Line split problem - adjust maxshrink and/or breaklimit": "Problema di linea divisa - modificare maxshrink e/o breaklimit", "Line too much shrunk $1 $2 $3": "Linea troppo compressa $1 $2 $3", "Line underfull ($1pt of $2pt)": "Linea troppo vuota ($1pt di $2pt)", "Misplaced '$1' in %%score": "'$1' in posizione errata in %%score", "Misplaced dot": "Punto in posizione errata", "Mix of old and new transposition syntaxes": "Sintassi di trasposizione vecchia e nuova allo stesso tempo", "No $1 after %%$2": "Manca $1 dopo %%$2", "No </defs> in %%beginsvg sequence": "Manca </defs> nella sequenza %%beginsvg", "No </style> in %%beginsvg sequence": "manca </style> nella sequenza %%beginsvg", "No accidental after 'exp'": "Manca l'alterazione dopo 'exp'", "No end of decoration": "Decorazione non terminata", "No end of grace note sequence": "Sequenza di note di abbellimento non terminata", | > > > > > > > > > > > > > > < > > > > > > > > | 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 |
"$1: inside tune - ignored": "$1: nel corpo del brano - ignorato",
"!$1! must be on a note": "!$1! deve stare su di una nota",
"!$1! must be on a note or a rest":
"!$1! deve stare su una nota o su una pausa",
"!$1! must be on the last of a couple of notes":
"!$1! deve stare sulla seconda di due note",
"!beamon! must be on a bar": "!beamon! deve stare su una stanghetta",
"%%combinevoices is deprecated - use %%voicecombine instead":
"%%combinevoices is deprecated - use %%voicecombine instead",
"%%deco: abnormal h/wl/wr value '$1'":
"%%deco: valore '$1' illegale per h/wl/wr",
"%%deco: bad C function index '$1'":
"%%deco: indice errato per la funzione C '$1'",
"%%deco: bad C function value '$1'":
"%%deco: valore errato per la funzione C '$1'",
"%%multicol end without start": "%%multicol end senza start",
"%%multicol new without start": "%%multicol new senza start",
"%%repeat cannot start a tune": "%%repeat non può stare all'inizio del brano",
"%%staffwidth too big": "%%staffwidth troppo grande",
"%%staffwidth too small": "%%staffwidth troppo piccolo",
"%%tune not treated yet": "%%tune non ancora gestito",
"%%vskip cannot be negative": "%%vskip non può essere negativo",
"Bad !xstem!": "!xstem! errato",
"Bad %%setbarnb value": "Valore errato in %%setbarnb",
"Bad %%staff number $1 (cur $2, max $3)":
"Numero $1 in %%staff errato (attuale $2, max $3)",
"Bad %%staff value '$1'": "Valore errato '$1' in %%staff",
"Bad %%stafflines value": "Valore errato in %%stafflines",
"Bad %%staffnonote value": "Bad %%staffnonote value",
"Bad %%staffscale value": "Valore errato in %%staffscale",
"Bad char '$1' in M:": "Carattere errato '$1' in M:",
"Bad character '$1'": "Carattere errato '$1'",
"Bad character in grace note sequence":
"Carattere errato nelle note di abbellimento",
"Bad controller number in %%MIDI": "Numero errato del controller in %%MIDI",
"Bad controller value in %%MIDI": "Valore errato del controller in %%MIDI",
"Bad duration '$1' in M:": "Durata '$1' errata in M:",
"Bad integer value": "Valore intero errato",
"Bad instr= value": "Valore errato di instr=",
"Bad L: value": "Valore errato per L:",
"Bad length of the macro sequence": "Bad length of the macro sequence",
"Bad measure duration": "Bad measure duration",
"Bad note in %%map": "Nota errata in %%map",
"Bad page width": "Larghezza di pagina errata",
"Bad program in %%MIDI": "Numero di programma non valido in %%MIDI",
"Bad scale value in %%font": "Valore di scala non valido in %%font",
"Bad strings in tablature": "Bad strings in tablature",
"Bad tempo value": "Bad tempo value",
"Bad tie": "Legatura non valida",
"Bad transpose value": "Valore non valido per la trasposizione",
"Bad user character '$1'": "Carattere illegale '$1' in U:/%%user",
"Bad value '$1' in %%linebreak - ignored":
"Valore errato '$1' in %%linebreak - ignorato",
"Bad value in $1": "Valore errato in $1",
"Bad voice ID in %%score": "ID di voce non valido in %%score",
"Bar in repeat sequence": "Stanghetta in sequenza ripetuta",
"Cannot have !$1! on a head": "!$1! non è consentito su una nota",
"Cannot have '$1' inside a tune": "'$1' non è consentito entro il brano",
"Cannot have %%beginml with %%pageheight":
"Cannot have %%beginml with %%pageheight",
"Cannot have a bar in grace notes":
"Stanghette non consentite nelle note di abbellimento",
"Cannot have a broken rhythm in grace notes":
"'Broken rhythm' non consentito nelle note di abbellimento",
"Cannot have V:* in tune body":
"V:* non consentito nel corpo del brano",
"Cannot read file '$1'": "File '$1' inesistente",
"Decoration ignored": "Decorazione ignorata",
"Decoration without symbol": "Decoration without symbol",
"Double voice in %%score": "Double voice in %%score",
"Empty line in tune header - ignored":
"Linea vuota nella testata - ignorata",
"End of slur without start": "End of slur without start",
"Erroneous end of voice overlap": "Fine di voice overlay errata",
"Error in %%pos": "Error in %%pos",
"Error loading the module $1": "Error loading the module $1",
"Incorrect 1st value in %%repeat": "Primo valore in %%repeat errato",
"Incorrect 2nd value in %%repeat": "Secondo valore in %%repeat errato",
"Invalid 'r' in tuplet": "'r' non valido in gruppo irregolare",
"Invalid decoration '$1'": "Decorazione '$1' non valida",
"Invalid note duration $1": "Durée de note $1 non valida",
"K:P is deprecated": "K:P is deprecated",
"Lack of ']'": "']' mancante",
"Lack of bar after multi-measure rest":
"Lack of bar after multi-measure rest",
"Lack of ending slur(s)": "Lack of ending slur(s)",
'Lack of starting [, ! or " in U: / %%user':
'U: / %%user non inizia con [, ! o "',
"Line split problem - adjust maxshrink and/or breaklimit":
"Problema di linea divisa - modificare maxshrink e/o breaklimit",
"Line too much shrunk $1 $2 $3": "Linea troppo compressa $1 $2 $3",
"Line underfull ($1pt of $2pt)": "Linea troppo vuota ($1pt di $2pt)",
"Microtone transposition not coded":
"Microtone transposition not coded",
"Misplaced '$1' in %%score": "'$1' in posizione errata in %%score",
"Misplaced dot": "Punto in posizione errata",
"Mix of old and new transposition syntaxes":
"Sintassi di trasposizione vecchia e nuova allo stesso tempo",
"No $1 after %%$2": "Manca $1 dopo %%$2",
"No </defs> in %%beginsvg sequence":
"Manca </defs> nella sequenza %%beginsvg",
"No </style> in %%beginsvg sequence":
"manca </style> nella sequenza %%beginsvg",
"No accidental after 'exp'": "Manca l'alterazione dopo 'exp'",
"No end of chord symbol/annotation": "Accordo di accompagnamento non terminato",
"No end of decoration": "Decorazione non terminata",
"No end of grace note sequence": "Sequenza di note di abbellimento non terminata",
"No end of repeat string": "Stringa di ripetizione non terminata",
"No end of string in font family": "No end of string in font family",
"No end of tuplet": "Gruppo irregolare non terminato",
"No end of tuplet in this music line":
"Gruppo irregolare non terminato in questa linea",
"No end of url in font family": "No end of url in font family",
"No end of voice overlay": "No end of voice overlay",
"No function for decoration '$1'": "Funzione inesistente per la decorazione '$1'",
"No note before '-'": "Nota mancante davanti a '-'",
"No note before '<'": "Nota mancante davanti a '<'",
"No note in voice overlay": "Nota mancante in voce sovrapposta (overlay)",
// "Non standard note duration $1": "??",
"No read_file support": "La funzione read_file non è supportata",
"No start of !$1!": "Manca l'inizio di !$1!",
"Not an ASCII character": "Non è un carattere ASCII",
"Not enough measure bars for lyric line":
"Battute insufficienti per le parole",
"Not enough measure bars for symbol line":
"Battute insufficienti per la linea s:",
"Not enough measures for %%repeat":
"Battute insufficienti per %%repeat",
"Not enough parameters in %%map":
"Parametri insufficienti in %%map",
"Not enough notes/rests for %%repeat":
"Note o pause insufficienti in %%repeat",
"Note too long": "Durata della nota troppo lunga",
"Note too short": "Durata della nota troppo corta",
"Start of slur without note": "Start of slur without note",
"s: without music": "s: senza musica",
"There cannot be chord symbols on measure bars":
"There cannot be chord symbols on measure bars",
"Too many elements in symbol line": "Troppi elementi nella linea s:",
"Too many include levels": "Troppi livelli di inclusione di file",
"Too many ties": "Troppi simboli di legato",
"Too many words in lyric line": "Troppe parole per la linea di musica",
"Unknown bagpipe-like key": "Chiave per cornamusa sconosciuta",
"Unknown clef '$1'": "Chiave '$1' sconosciuta",
"Unknown decoration '$1'": "Decorazione '$1' sconosciuta",
"Unknown font $1": "Font $1 sconosciuto",
"Unknown glyph: '$1'": "Glifo '$1' sconosciuto",
"Unknown keyword '$1' in %%multicol": "Keyword '$1' sconosciuta in %%multicol",
"Unsecure code": "Codice pericoloso",
"Unterminated string": "Stringa di testo non terminata",
"Unterminated string in Q:": "Stringa di testo non terminata in Q:",
"Variant ending on a left repeat bar":
"Variant ending on a left repeat bar",
"Voice overlay already started": "Voce sovrapposta (overlay) già iniziata",
"w: without music": "w: senza musica",
"Wrong duration in voice overlay":
"Durata errata nella voce sovrapposta (overlay)",
}
|
Changes to err-pt_BR.js.
1 2 3 4 | //JS abc2svg - Brazilian Portuguese translation of the error codes: // Tradução dos códigos de erro para português brasileiro // Adicione este arquivo na linha de comando para obter as // mensagens de erro em português do Brasil. | | > > > | > | | > > > > > | > > < > | > > | > > > > > > > > | 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 |
//JS abc2svg - Brazilian Portuguese translation of the error codes:
// Tradução dos códigos de erro para português brasileiro
// Adicione este arquivo na linha de comando para obter as
// mensagens de erro em português do Brasil.
// (Hudson Lacerda - 11/dez/2016 - 23/set/2021)
user.textrans = {
"+: lyric without music": "+: palavras sem música",
"+: symbol line without music": "+: linha de símbolos sem música",
"+: without previous info field": "+: continuação sem campo anterior",
"'{' in grace note": "'{' em notinha ornamental",
"'}', ')' or ']' missing in %%score":
"Falta '}', ')' ou ']' em %%score",
"',' lacking in annotation '@x,y'":
"Falta uma ',' na anotação '@x,y'",
"'$1' is not a note": "'$1' não é uma nota",
"'$1:' line ignored": "'$1:' linha ignorada",
"$1: inside tune - ignored": "$1: no meio da música - ignorando",
"!$1! must be on a note": "!$1! deveria estar em uma nota",
"!$1! must be on a note or a rest":
"!$1! deveria estar em uma nota ou pausa",
"!$1! must be on the last of a couple of notes":
"!$1! deveria estar na segunda nota de um par de notas",
"!beamon! must be on a bar": "!beamon! deveria estar em uma barra de compasso",
"%%combinevoices is deprecated - use %%voicecombine instead":
"%%combinevoices é obsoleto - substitua-o por %%voicecombine",
"%%deco: abnormal h/wl/wr value '$1'":
"%%deco: '$1' é um valor anormal para h/wl/wr",
"%%deco: bad C function index '$1'":
"%%deco: índice de função '$1' incorreto",
"%%deco: bad C function value '$1'":
"%%deco: valor de função '$1' incorreto",
"%%multicol end without start": "%%multicol end sem 'start'",
"%%multicol new without start": "%%multicol new sem 'start'",
"%%repeat cannot start a tune": "%%repeat não pode estar no início de uma música",
"%%staffwidth too big": "%%staffwidth muito grande",
"%%staffwidth too small": "%%staffwidth muito pequeno",
"%%tune not treated yet": "%%tune ainda não é tratado",
"%%vskip cannot be negative": "%%vskip não pode ser negativo",
"Bad !xstem!": "!xstem! incorreto",
"Bad %%setbarnb value": "Valor incorreto para %%setbarnb",
"Bad %%staff number $1 (cur $2, max $3)":
"Número incorreto $1 em %%staff (atual $2, máximo $3)",
"Bad %%staff value '$1'": "Valor incorreto '$1' em %%staff",
"Bad %%stafflines value": "Valor incorreto em %%stafflines",
"Bad %%staffnonote value": "Valor incorreto em %%staffnonote",
"Bad %%staffscale value": "Valor incorreto em %%staffscale",
"Bad char '$1' in M:": "Caráter inválido '$1' em M:",
"Bad character '$1'": "Caráter inválido '$1'",
"Bad character in grace note sequence":
"Caráter inválido em grupo de notinhas ornamentais",
"Bad controller number in %%MIDI": "Número inválido do controlador em %%MIDI",
"Bad controller value in %%MIDI": "Valor incorreto para controlador em %%MIDI",
"Bad duration '$1' in M:": "Duração '$1' incorreta em M:",
"Bad integer value": "Número inteiro inválido",
"Bad instr= value": "Valor incorreto para instr=",
"Bad L: value": "Valor incorreto de L:",
"Bad length of the macro sequence": "Duração incorreta em sequência de macro",
"Bad measure duration": "Compasso com duração incorreta",
"Bad note in %%map": "Nota incorreta em %%map",
"Bad page width": "Largura de página incorreta",
"Bad program in %%MIDI": "Valor incorreto de instrumento %%MIDI",
"Bad scale value in %%font": "Tamanho incorreto em %%font",
"Bad tempo value": "tempo inválido",
"Bad strings in tablature": "Cordas inválidas em tablatura",
"Bad tie": "Ligadura de prolongamento incorreta",
"Bad transpose value": "Valor incorreto de transposição",
"Bad user character '$1'": "Caráter ilegal '$1' em U:/%%user",
"Bad value '$1' in %%linebreak - ignored":
"Valor incorreto '$1' em %%linebreak - ignorado",
"Bad value in $1": "Valor incorreto em $1",
"Bad voice ID in %%score": "Identificador de voz incorreto em %%score",
"Bar in repeat sequence": "Barra de compasso em um fragmento %%repeat",
"Cannot have !$1! on a head": "!$1! não pode estar em cabeça de nota",
"Cannot have '$1' inside a tune": "'$1' não pode estar dentro de uma música",
"Cannot have %%beginml with %%pageheight":
"Não pode haver %%beginml com %%pageheight",
"Cannot have a bar in grace notes":
"Não pode haver barra de compasso em grupo de notinhas ornamentais",
"Cannot have a broken rhythm in grace notes":
"Não pode haver ritmo quebrado em notinhas ornamentais",
"Cannot have V:* in tune body": "Não pode haver V:* no corpo da música",
"Cannot read file '$1'": "Arquivo '$1' não pôde ser aberto ou não existe",
"Decoration ignored": "Decoração ignorada",
"Decoration without symbol": "Decoração sem símbolo",
"Double voice in %%score": "Voz duplicada em %%score",
"Empty line in tune header - ignored":
"Linha em branco no cabeçalho da música - ignorada",
"End of slur without start": "Fim de ligadura sem início",
"Erroneous end of voice overlay": "Terminação incorreta de superposição de vozes",
"Error in %%pos": "Erro em %%pos",
"Error loading the module $1": "Error loading the module $1",
"Incorrect 1st value in %%repeat": "Primeiro valor incorreto em %%repeat",
"Incorrect 2nd value in %%repeat": "Segundo valor incorreto em %%repeat",
"Invalid 'r' in tuplet": "'r' inválido em quiáltera",
"Invalid decoration '$1'": "Decoração '$1' inválida",
"Invalid note duration $1": "Duração de nota $1 inválida",
"K:P is deprecated": "K:P é obsoleto",
"Lack of ']'": "']' faltando",
"Lack of bar after multi-measure rest":
"Falta barra de compasso após pausa de múltiplos compassos",
"Lack of ending slur(s)": "Falta fim de ligadura(s)",
'Lack of starting [, ! or " in U: / %%user':
'U: / %%user não começou com [, ! ou "',
"Line split problem - adjust maxshrink and/or breaklimit":
"Problema de quebra de linha - ajuste maxshrink e/ou breaklimit",
"Line too much shrunk $1 $2 $3": "Linha muito encolhida $1 $2 $3",
"Line underfull ($1pt of $2pt)": "Linha muito espaçada ($1pt de $2pt)",
"Microtone transposition not coded":
"A transposição de microtons não está codificada",
"Misplaced '$1' in %%score": "'$1' deslocado em %%score",
"Misplaced dot": "Ponto fora de lugar",
"Mix of old and new transposition syntaxes":
"Mistura de sintaxes de transposição antiga e nova",
"No $1 after %%$2": "Falta $1 após %%$2",
"No </defs> in %%beginsvg sequence":
"Falta </defs> em bloco %%beginsvg",
"No </style> in %%beginsvg sequence":
"Falta </style> em bloco %%beginsvg",
"No accidental after 'exp'": "Falta acidente após 'exp'",
"No end of decoration": "Decoração sem término",
"No end of grace note sequence": "Grupo de notinhas ornamentais não terminado",
"No end of chord symbol/annotation": "Acorde cifrado/anotação sem término",
"No end of repeat string": "Cadeia de repetição não terminada",
"No end of string in font family":
"Cadeia de caracteres incompleta em família de fonte",
"No end of tuplet": "Quiáltera incompleta",
"No end of tuplet in this music line":
"Falta terminar quiáltera nesta linha de música",
"No end of url in font family": "URL incompleta em família de fonte",
"No end of voice overlay": "Falta fim de divisão de vozes",
"No function for decoration '$1'": "Falta função para decoração '$1'",
"No note before '-'": "Falta nota antes de '-'",
"No note before '<'": "Falta nota antes de '<'",
"No note in voice overlay":
"Falta nota em superposição de vozes",
"Non standard note duration $1": "Duração não padronizada: $1",
"No read_file support": "A função read_file não existe",
"No start of !$1!": "Falta início de !$1!",
"Not an ASCII character": "Não é um caráter ASCII",
"Not enough measure bars for lyric line":
"Faltam barras de compasso na linha de palavras (letra)",
"Not enough measure bars for symbol line":
"Faltam barras de compasso na linha de símbolos",
"Not enough measures for %%repeat": "Faltam compassos para %%repeat",
"Not enough parameters in %%map":
"Parâmetros insuficientes para %%map",
"Not enough notes/rests for %%repeat": "Faltam notas/pausas para %%repeat",
"Note too long": "Duração muito longa",
"Note too short": "Duração muito curta",
"Start of slur without note": "Início de ligadura sem nota",
"s: without music": "s: sem música",
"There cannot be chord symbols on measure bars":
"Não pode haver cifra de acorde em barra de compasso",
"Too many elements in symbol line": "Excesso de elementos na linha de símbolos",
"Too many include levels": "Excessivos níveis de inclusão de arquivos",
"Too many ties": "Excesso de ligaduras de prolongamento",
"Too many words in lyric line": "Excesso de palavras",
"Unknown bagpipe-like key": "Armadura desconhecida para gaita de foles",
"Unknown clef '$1'": "Clave '$1' desconhecida",
"Unknown decoration '$1'": "Decoração '$1' desconhecida",
"Unknown font $1": "Fonte $1 desconhecida",
"Unknown glyph: '$1'": "Glifo '$1' desconhecido",
"Unknown keyword '$1' in %%multicol": "Palavra-chave '$1' desconhecida em %%multicol",
"Unsecure code": "Código inseguro",
"Unterminated string": "Cadeia de caracteres não terminada",
"Unterminated string in Q:": "Cadeia de caracteres não terminada em Q:",
"Variant ending on a left repeat bar":
"Variant ending on a left repeat bar",
"Voice overlay already started": "Divisão de vozes já se iniciou",
"w: without music": "w: sem música",
"Wrong duration in voice overlay":
"Duração incorreta na divisão de vozes",
}
|
Changes to font.js.
1 2 |
// abc2svg music font
var musicfont = 'url("data:application/octet-stream;base64,\
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | < | < < < | | | > | | < > > > | > > | < < | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | < < | > > | | | | | | | < < | > > | | | | | | | | | | | | > > | < < | | | | > > | < < | | | | | < < | | | | | | | | | | | | > > > | < | | | < > > > > > > | | | | | | < > | | | | | | | | > | | < < < < > > > | > > > > > > | | < < < < < < < < < < | | | | < | > | | > > > > > | > | | < | | < | > | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < | | > > | | | | | < | | | | < | < | > | | < | < < > | | | < > | < > | | < > | < < < < < | | < > | < | | < < < | < < < < < < < | > > > > > > | > > > > > > > | > > | < | > > | < | | | | | | | | | | | < | < < < > | | | | | | > > > | | | | < < < | > > > | | 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 |
// abc2svg music font
var musicfont = 'url("data:application/octet-stream;base64,\
AAEAAAAOAIAAAwBgRkZUTY1L868AAFgoAAAAHEdERUYAFQAUAABYDAAAABxPUy8yWMFdCgAAAWgA\
AABWY21hcFz/TQsAAAQIAAADemN2dCAAIgKIAAAHhAAAAARnYXNw//8AAwAAWAQAAAAIZ2x5Zg27\
S/YAAAiwAABGeGhlYWQTZto6AAAA7AAAADZoaGVhCWn/GwAAASQAAAAkaG10eNlp+7kAAAHAAAAC\
SGxvY2HP4L6kAAAHiAAAASZtYXhwANkBFgAAAUgAAAAgbmFtZdbpNH4AAE8oAAADJHBvc3SIfxKM\
AABSTAAABbUAAQAAAAEAAF56eDVfDzz1AAsEAAAAAADRlyIXAAAAAN4tda//OPzvBUsEiAAAAAgA\
AgAAAAAAAAABAAAEiPzvAFwEJf84/XQFSwABAAAAAAAAAAAAAAAAAAAAkgABAAAAkgDlAAUAAAAA\
AAIAAAABAAEAAABAAC4AAAAAAAEBgAGQAAUACAKZAswAAACPApkCzAAAAesAMwEJAAACAAUDAAAA\
AAAAAAAAARAAAAAAAAAAAAAAAFBmRWQAQAAA7LcDOP84AFwEiAMRAAAAAQAAAAAAAAF2ACIAAAAA\
AVUAAAGQAAACWAAAAFcAAAAjAAAAJQAAACT//wBkAAAEIwAABCUAAAHg/9wDXgB6AwsAAALSAAAC\
v/+6AdYAAAMLAAADDgAAAyf/yADIAAABaP//Aa4AAAEiAAABkAAAAXwAAAGQAAABkAAAAYEAAAGQ\
AAABkAAAAYEAAAGZAAkBmAAJAfQAAAEEABQBBAAKAmsAJAISAAABwgAAAUkAAAFAAAABSv/+ASwA\
AAIwAAABSgAAAUoAAABkAAABQAAAAUAAAAFAAAABQAAAAGQAAAE2AAAA5gAAATYAAAE7AAABOwAA\
ATsAAAE7AAABOwAAATsAAAE7AAABOwAAATsAAAE7AAABDQAAAMgAAAD/AAABCwAUAW4AAACMAAAA\
jAAAAQ0AMgFu//UAqQAAAToAAAFA//0AUAAAAVQAAABkAAABGAAAAlgAAAC2AAABkAAEAIIAAACC\
AAABLAAAASwAAADuAAAA/wAAAUkAAAGPAAAB2AAAAdgAAAIz//ADIP/hAXv/tAG4/9sBFv9+ARP/\
2wDcAAAA6P/kAr//tAIz/7QCv/+0Ayv/2wFf/9sCaf9+AV//fgJp/34BXwAAAf0ABQG1AAABtQAA\
AkQADQJEAA0BGAAAATYAAAEs//8BLAAAAPoAAADIAAABGP84APoAAADIAAAEDQAAAhwADAH0AAAB\
9AAAAfQAAAH0AAAB9AAAAfQAAAB4AAAALQAAAhwAAAD6AAAA+v/oAcIAAAFIAAABQAAAAgoAAAIK\
AAAAZAAAAAAAAwAAAAMAAAAcAAEAAAAAAnQAAwABAAAAHAAEAlgAAACSAIAABgASAAAAIOAA4DDg\
OeBD4EjgUOBc4GLgaeB+4IzgleCk4Kngs+EB4bnhu+Hn4fLh9OH34fnh/OIA4kniZOJr4oPkoOSi\
5KTkqOSs5MDkzuTR5OrlAeUl5S3lMeU55WflaeVt5YLl0OXi5hDmEuYU5hjmJOYw5lDmVekS6RXp\
GOkg6SXpXeoC6qTso+yl7Kfsqey3//8AAAAAACDgAOAw4DjgQ+BF4FDgXOBi4GngeuCA4JTgoOCp\
4LPhAeG54bvh5+Hy4fTh9+H54fzh/uJA4mDiauKA5KDkouSk5KjkrOTA5M7k0eTh5QDlIOUp5S/l\
OeVm5WnlbOWC5dDl4uYQ5hLmFOYY5iTmMOZQ5lXpEOkU6RjpIOkl6V3qAuqk7KLspeyn7Knst///\
AAP/5CAFH9Yfzx/GH8Ufvh+zH64fqB+YH5cfkB+GH4IfeR8sHnUedB5JHj8ePh48HjseOR44Hfkd\
4x3eHcobrhutG6wbqRumG5MbhhuEG3UbYBtCGz8bPhs3GwsbChsIGvQapxqWGmkaaBpnGmQaWRpO\
Gi8aKxdxF3AXbhdnF2MXLBaIFecT6hPpE+gT5xPaAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAQYAAAMAAAAAAAAAAQIAAAACAAAAAAAAAAAAAAAAAAAAAQAABAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiAogAAAAqACoAKgA2\
AD4AbgB6AIYAkgCwASQBgAHwAjICvgNQA7ADxARgBPIFSgWKBiQGRgZaBqwG/AccB2IHogfcCCgI\
aAiuCQgJHAlCCWgJmgm2CdgKBAoaCjQKagp4CoQKkAqiCr4K4AruCwILFAskC3ALgAuaC7QL7Awk\
DHIMvg0kDYYOBA58DqIOvA7sDxYPbg+ID6IPyBAiEEIQgBCoELwQyBDWEOYRDhE0EWwReBGEEZAR\
nBG+EeQSGhJoEsgTPBNiE5AT5BRYFKwU7BUwFYYWpBd+GBQYxhmOGiYa/hwYHQwdTh2SHdwd9h4a\
Hi4eQh5yHoIelB6wHsYe6h8aH/ggtCDcIPohLCFqIZwh3iHwIf4iGiI0IloifCKqIsQi7iMqIzwA\
AAACACIAAAEyAqoAAwAHAC6xAQAvPLIHBADtMrEGBdw8sgMCAO0yALEDAC88sgUEAO0ysgcGAfw8\
sgECAO0yMxEhESczESMiARDuzMwCqv1WIgJmAAABAAAAAAGRAZAAAwAAMREhEQGRAZD+cAABAAAA\
AAAAAAAAAAAAMQAAAQAAAAAAVwQDACAAABE1NjU0JyY1NDcGFRQXFhUUBxYVFAcGFRQXJjU0NzY1\
NDUjElc/FSVNTSUVP1cSIwIDAhhDNmA5NGY6MksiOWFNYRgYZkxgOSVKMjpmNDlgNkgAAQAAAAAA\
IwPoAAMAABEzESMjIwPo/BgAAQAAAfQAJQPoAAMAABEzESMlJQPo/gwAAf//A2QAJARgAAMAABEz\
ByMkASQEYPwAAgAAAUAAZAKeAAcADwAAEiImNDYyFhQCIiY0NjIWFEcqHR0qHR0qHR0qHQI6HSod\
HSr+6R0qHR0qAAAABQAAAAAEJAGuAC8ANwA/AEcAUwAAITUzHgEzMjY1NCcuBDU0NjMyFhc3Mxcj\
LgEjIgYVFB4DFx4BFRQGIyInByAiJjQ2MhYUBCImNDYyFhQBETMyNjQmIwM1MxEjNTMyFhUUIwJO\
HhVPMik7lBkaKhYRWT0kJxkeHgceD0owHzkQIhkyCE5NW09FLiMBmyodHSod/eoqHR0qHf6JKDxG\
RjzcRkbccYn6oDxLICEtKAcIFBQjFUNNCw4ZmzpIKBsPFw8JCwIVNzM6TiAgHSodHSodHSodHSoB\
af6YYaZh/noeAWgeZ2vSAAUAAAAABCQBrgAaACIAKgAyAD4AACEiJjU0NjMyFhc3MxcHJiMiBhQW\
MzI2NxcOATIiJjQ2MhYUBCImNDYyFhQBETMyNjQmIwM1MxEjNTMyFhUUIwMCZ3WCWiUpGx4eCCEk\
Xjg2Njg2TREjFFmxKh0dKh396iodHSod/okoPEZGPNxGRtxxifprZ2V3DBIepgSMbZhtST4KSlEd\
Kh0dKh0dKh0dKgFp/phhpmH+eh4BaB5na9IAAAAD/9wAAgHeArMABwAPAE0AAAAiJjQ2MhYUBCIm\
NDYyFhQXNDYzMhYVFAcWMzI2NTQvAQMnEy4BNTQ+ATc2MzIWFRQGIyImNTQ3JiMiBhUUHwETFwMe\
ARUUDgEHBiMiJgGeIBgYIBj+fiAYGCAYWxsUEx4sFykmNiZ7zyvRWkgcExQmMzA4GxQTHiwXKSY2\
JnrUK9VaSBwTFCYzMDgBUhggGBggVBggGBgg0xIcGhEdDhctJi0mZf7eIAElR3E4Fi0RERM4IRIc\
GhEdDhctJi0mZQEmH/7XR3I4Fi0RERM4AAUAev80A14CVAAXABsAHwAjACcAAAEzFR4BFzMVIw4B\
BxUjNS4BJyM1Mz4BNxEjFhc3FTY3JzMmJwc1BgcB2ChVeAeKigd4VShVeAeKigd4VXAFayhrBXBw\
BWsoawUCVIkIi2AoYIsIiYkIi2AoYokI/uW6DsjIDrooug7IyQ67AAAAAAQAAP1vAqcEiAALAEQA\
TgBjAAABBhUUFz4BNTQnDgETFxUUBiMiJjU0NjMyFhQGBxYzMjY9AScGIyImNTQ3PgY/ASY1NDY3\
FhUUBgcXNjMyFhUUJzQmIyIGIxM+AScOARUUFhcuATU0NycOAQceATMyNwFsBwVIdTY5QksXT01S\
X0AyL0E/Ly0YL0AXHA2Y2zoNJCAuHTESFxYNbEliXHkUFAtxiE5iUAIHAiFbQeI2RicdPT+mEY9s\
AQKheQoWA1M3LSNaMZVIcg0HXvts7ANMXFNBLUg7WDcBGTxGA+kCx52FZhcwJS0aJw4REJZmjKEH\
OuWIqV/PApxzzro+ZgH+nRJd8gtGMSBCEg5FR6kuvXKXZ42jAgACAAD9/ALSAgAAZABoAAABMjY1\
NCcmIyIHDgIHJicmJxEjETMRNjc2Nx4DFxYzMjY1NCcmIyIHFhcUFhUUBisBJjU0NzY3NjMyFxYX\
FRQGBwYjIicHFzYzMhYXFh0BBgcGIyImNTQ3MzIWFRQGFQYHFgEzESMB3j5KDRpJRjwCBgoEIhoe\
LhwcLh4aIgYUDBkPJyUxPRIkUi8xMg0CMyEFRAUaVScjXlU3CFpIHy00PyIiPzRCZh4oCDdWXUxy\
RAUhMwIPMDX+TXt7/iB4Si0tbEkFDhsKYicrH/4EBAD+ER8rJ2ILKhcdCRt7QjE2YhoQKAMNBB4r\
GTIUC0QZDU80UxJObxwNF0tKFz4sOUMSUzRQTjwyGSseBA4EJhAcA978AAAAA/+6/aUCwwD/ACoA\
NgBCAAA3NDYzMhYXFhUUBgcOAQc2Nz4BNzY1NCYnLgEjIgYHPgEzMhYVFAcGIyImBSImNTQ2MzIW\
FRQGJyImNTQ2MzIWFRQGE4tnVWsrL0ZVZs+V5YUxNBMKER0cNDM7YRYYIxsuPSchMTNFAoIWHRoU\
FR4aGhcbHBUUHBsdYoA0OT5yf7pPYE0IPYUxY1ArZkdQIyIXT0YeF0EvMiAeUYocFxYcHRUWHfIe\
GRUaGxQZHgAAAgAA/wYBcgD6AAMABwAANzMTIwMzEyPclAKW3JQClvr+DAH0/gwAAAQAAP4KAh8D\
qgAJACAAYgBtAAAlFhc+ATU0JiMiAwInDgEVFBcuATU0NjcmJw4BBx4BMzIXHgEfAR0BFCMiJjU0\
NjMyFhUUBgcWMzI2NTQvAQYjIiY1NDc+ATc+AjcmNTQ2Nx4BFRQGBx4BFzYzMhcWFRQHBgMGFRQX\
PgE1NCcGAUkTBk1HVkIODRgBLDkfICpMOwUJcVUBBW2CAyIDBgICejZTMyglNTEnFSIjLAENCRWN\
mS4OTB4FIycSDllALxlJYQIIBBIIXDkyYzZkAwY3XilfdcRbEk8zNlb+4AELEAk0JykmEkEpOE4Q\
PlpaeVNxfhogQBcXGwd/SDEkMzckIigBDDM1DwmNAZKKalEcUBgEICENwgdufxMzYltth0wRbiQC\
QzZidzAbA1YeIjkkJXszRiYmAAIAAP5jAkIBmgBjAGcAAAEyNjU0JyYjIgcOAQcmJyYnESMRMxE2\
NzY3HgMXFjMyNjU0JyYjIgcWFxQWFRQGKwEmNTQ3Njc2MzIXFhcVFAYHBiMiJwcXNjMyFhcWHQEG\
BwYjIiY1NDczMhYVFAYVBgcWATMRIwF+MjsKFTo4MAIMBB0TGCUWFiUYEx0EEQoTDCAdJzEOHEMl\
JygKAioaBDYEFUQjGElGLQZIOhglKzEbGzQoNVIYIAYtRkk9WzYEGioCDCYr/qNiYv6AYDskJFc7\
BR0LUhwiGf5qAzP+dBkiHFIIIhIXCBZiNSsoThUNIAILAxgiFCgQCTUVC0ArQQ4+WhYKEjw7EzIj\
LjUPQStAPzAoFCMYAwsDHw0WAxj8zQAAAAAD/8j+HgI2AMwAJgAvADsAADc0NjMyFxYVFAcOAQc2\
NzY3NjU0Jy4BIyIGBz4BMzIWFRQHBiMiJgUiJjQ2MhYUBiciJjU0NjMyFhUUBg9wUoI8I3hDxmnA\
XkceCS0YLSAwUgoSFhYlOSAZJSw5AgISFxQiGBUVEhYVEhEWFSFNXlczWsZsO1cGM2RKjC8pZjMa\
FEI2Fw08JigaGFN1FyQWFyIYwhgUERQVEBMZAAAAAAMAAAAAAMgA8AAJABUAKwAANwYVFBYzMjY1\
NCciBhUUHgEXNjU0JgciJjU0NjcuATU0NjMyFhUUBxYVFAZWLB4QERQCDhMKCRAlFDQlNSMiEQwo\
HikxNyM0dBAeFB4bEReFEQ4KEAgMCx0OF9woHhcaCw8TEBoiHx0lDhwfICYAAv////8BZwEDAC8A\
mwAAFyI1NDMyFRQGFRQzMjY1NCMiBiMiNTQ3NjM2MzIVFAcGBw4CBwYWNzYzMhYVFAYnIiY2OwEy\
NzY3NiMiBwYnJjc+BDMyFjMyNzYWBwYHBhUUMzIVFCtBItQ+GBsSHRcsHhMmAwsmBgkqQhQWHEYH\
BwIBAgQJDA4hIkX4BQUEBgkVBA8aCA4KBwwNCg8HGw8TDAQHGgcEBgwIA0QNAhUMDAEBAgEBAQEC\
AQEBAQECAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEJ\
EwE3IRsIFAcOQiMcGQ8WVAsBBxAHCg8BBgQICAgDAyUfKTgBCQkMI0UVCQ4GBRMJIxQXCg0CBAYI\
piQHAwgKCAAAAAACAAD/BgGuAPoACwAUAAAzFBYzMjY1NCYjIgYHNDYyFhQGIiaKKiMiKycmJSiK\
fbR9fbR9Ynh5YWV1dmFnkJHSkZIAAAEAAP8GASIA+gAJAAAxNzMRFxUjNTcRZH1B8EH6/j4eFBQe\
ASwAAAABAAD/BgGPAPoAPAAANzIVFAcOAwc2MzIWMzI3PgIzDgIHBgcGIyImIyIGIyI1NCc+BTU0\
JyIHMhYVFAYjIjU0PgHHyAUNNkBvNhMgG2QcGB4FEAwBAQUFAQcQGikadBUfVgIHAQIsPkc8KFNO\
GhwpNx5MPFj6fhoOIS4dRC0MIw4DDQsFFhYDKQ4YJyYQAQIhRTg8MjgYYgE1JR4fKWcoORkAAAEA\
AP8GAXUA+gA5AAA3MhYVFAYjIiY1NDc2MzIXFhUUBgceARUUBwYjIiYnJjQ2MzIWFRQGIxYzMjY1\
NCYnJjQ3PgE0JiMiZhsiJyEbMh8zWUYmREY9PlFLJE0nVxgjMiAiKiUbDD8kK0guFhYvSykkPKoc\
FxsjKyMvGioTIkguRAsLRS1DJxMWFB1MLiEbGR4pMScmOggEIgQJN1AwAAABAAD/BgGQAPoAEQAA\
BRcjNzUjNTY1MwEzPwERMxUjAUUyyDLhk6P++7ABY0tL0SkpMSjygP6OlpH+2SgAAAAAAQAA/wcB\
fgD6AC8AABc2MzIWFRQGIxYzMjc+ATU0JyYjIgcTIQ4BKwEHNjMyFx4BFRQHDgIjIicuATU0Ehwh\
GyogHBokMRwTCR4cKE5ICgFiCzUl1QY5QlMxIStDFkArJTwrEB5fICAXHCAhHhQfIDkcGjUBIiQ6\
eR4fFUElTy8QEAIUCTISIwAAAAACAAD/BgGBAPoACQAsAAAXMjY1NCYjIgcWExYVFAYjIiY1NDYz\
JiMiBhU+AjMyFhUUBiMiJic+ATMyFsgpLSooLDAH3RsjGB4iGxAWNzUvFRgtHkxPcUhhZgEBbFsw\
P9JFLCIwJZ4BnxomGSgeGwweI3hfCwoJQDZEWYJ4aZESAAEAAP8GAZAA+wAoAAA3Ig4DBzc+CDMy\
FjMyNjcOBBUjNjc2NzY3BiMiJmEUGhQJEQUKAQwCCwULCQ0QCS91Ixo7ERtFGh4IggEIEWgeLREe\
JWChBQ4JGwZ0AQsCCQEGAQMBJhcOQ6dBXEIrRRs2hyc5CigAAwAA/wYBhAD6AA4AHAA0AAAXDgEV\
FBYzMjY1NC4DNz4BNTQmIgYVFB4DBy4BNTQ2NzIWFRQGBx4BFRQGIyImNTQ2mjYsWCwqPw8gHTE+\
MyNEUjMKHBIxcDEpZkpLZSowOjJ1TUx2OSoZJBsdMCkfDhcSDRNaGiIcHTAoIA8XEwoVPxg8NTNN\
AUYyJzQXGjo1N0pIMCQ1AAACAAD/BgGBAPoACQAsAAA3IgYVFBYzMjcmAyY1NDYzMhYVFAYjFjMy\
NjUOAiMiJjU0NjMyFhcOASMiJrkpLSooLDAH3RsjGB4iGxAWNzUvFRgtHkxPcUhhZgEBbFswP9JF\
LCIwJZ7+YRomGSgeGwweI3hfCwoJQDZEWYJ4aZESAAEACf8KAZkA+QAwAAAlMBc2NTQmIw4BFRQX\
FjMyNzY3FB4BFQ4BByInJic0JjU0NzIWFxYVFAYjIiY1PgEzAS8SBDwfM0AnITArKBwqCQgbVVZP\
OzsEAdskQBEiJBwgKQIgGqQDBQgUHgJiao4zKiIYWAEEAwFVUAE5OWYCKwLmAh4UJyQlOS4cFiYA\
AgAJ/qIBmQFeADgAPwAAJTAXNjU0JiMiBxEWMzI3NjcUHgEVDgEHIxUjNSYnJic0JjU0NzUzFTI2\
MzIWFxYVFAYjIiY1PgEzAxEGFRQXFgEvEgQ8HwMQDAwrKBwqCQgbUVUBIz0uOwQBqyMDBwMkQBEi\
JBwgKQIgGno9JwqkAwUIFCIE/ksEIhhYAQQDAVRRAWhrCS05ZgIrAssZaWYBHhQnJCU5LhwWJv6X\
AZYukY4zDQAAAQAA/wYB9AD6AAsAADUzNTMVMxUjFSM1I9dG19dG1yPX10bX1wAAAAEAFP4GAOQC\
AAATAAATFgcGJyYCNTQSNzYXFgcGAhUUEtwHDQkFSWtrSQkLBwc8Rkf+FggFAwZXASB9fAEiVgsH\
BQlJ/ueIhv7lAAABAAr+AgDcAf0AEwAAEzYSNTQCJyY3NhcWEhUUAgcGJyYUO0dGPAkMCgdJa2tJ\
CAsG/hZJARuGiAEZSQsEBAlW/t58ff7gVwkJBAAABAAk/1YCTACqAAsADwATAB4AAAU0JiMiBhUU\
FjMyNjczESMBMxEjJBQGIyImNTQ2MzIBqFQ8IDRXPSEvcjIy/goyMgH1e2ZlfHloZiA1TicfNUsj\
6v6sAVT+rOZ4Rkk5P0MAAAIAAP8kAhIA3AADAA8AADcVITUlMxUhNTMRIzUhFSMeAdb+DB4B1h4e\
/ioeQYKCmzc3/kg3NwAAAgAA/38BwgCBAAsAEwAABTQmIyIGFRQWMzI+ARQGIiY0NjIBUVo2IDRd\
NyEvcX3IfX3IHjRPJx80TCN0bEtLbEsAAAACAAD/bAFIAJQADQAbAAAlJiMiBhUUFxYzMjY1NDcW\
FRQGIyInJjU0NjMyASQNJTyXBgsmPJcQD35ITyQPfkhPRBdhKwoJF2ErCRceHUNnQx4dQ2cAAAAA\
AQAA/3kBQACHAAsAACUUBiMiJjU0NjMyFgFAeVkyPHpYMjwoRmk4J0VqOAAB//7/bwFMAJEACwAA\
JzcXNxcHFwcnByc3AhuMjBuGhhyLixyGcSB2dSBwcCF1dSFwAAAABQAA/2oBLACWAAUACwARABcA\
HwAAFwcWMzI3LwEGFRQXPwEmIyIHHwE2NTQnBjQ2MhYUBiKWRx0qKR9dRx0dXEgfKSodXEcdHfJY\
fFhYfBJIHR1aSR8pKh1YSB0dWkgfKSodhXxYWHxYAAAAAQAA/wYCMAD6AAMAABUBMwEBuHj+R/oB\
9P4MAAEAAP90AUoAjAADAAAxNxcHpaWljIyMAAEAAP90AUoAjAACAAAVGwGlpYwBGP7oAAEAAP/O\
AGQAMgAHAAAWIiY0NjIWFEcqHR0qHTIdKh0dKgAAAAEAAP95AUACqAAPAAARIREUBiMiJjU0NjMy\
FxEhAUB5WTI8elgxH/7eAqj9gEZpOCdFahwBxQAAAQAA/3kBQAKoABMAABEhERQGIyImNTQ2MzIX\
ESE1ITUhAUB5WTI8elgxH/7eASL+3gKo/YBGaTgnRWocARF4PAAAAAABAAACMAFAAqgAAwAAESEV\
IQFA/sACqHgAAAAAAgAAAXwBQAKoAAMABwAAESEVIREhFSEBQP7AAUD+wAH0eAEseAAAAAEAAP/a\
AGQAPgAHAAAWIiY0NjIWFEcqHR0qHSYdKh0dKgAAAAEAAAMCATYDwAAFAAARIRUhFSMBNv7oHgPA\
HqAAAAAAAQAAAyoA5gQ4ADkAABMiJjU0NjMyFhUUDwEUMzI2NTQmKwEiNTQ7ATI2NTQmIyIVFBYV\
FCMiJjU0NjMyFhUUDgEVFBYVFAZQJykQDg8SCwwhFSQRDxIUFCgXJQ4OFQIhDBIlKyMtIyMUMwMq\
HhgOFhAMEgcHDSofDxkOECUVDRMNAwgIHBEMFR4iGhgjEwIBIg8jLQAAAAABAAADAgE2A8AABQAA\
ARUjNSE1ATYe/ugDwL6gHgAAAAEAAPzvATsAAAAPAAAVNTMeBBUUBzY1NCYnHgY/UVA3LhKRcO/v\
NXBlbIlJYGlBSY/fKgABAAAAAAE7AxEADwAAMTUzPgE1NCcWFRQOAwcecJITLjdQUT8G7x/hk0dI\
Z15Iim1ncTUAAgAA/UQBPAAAABgAJgAAGQEzHgYVFAcWFRQHNjU0LgMjNR4DFzQ2NTQuAx4GJzM7\
OC4cEhMeBSk+SEAWCURNVhUBKT5IQf6pAVcbOTM3Oj1IJSwrKSs2ORkhN2RFNBirJFRDXSkEDAQ3\
ZUUzGQAAAAIAAP//ATwCvAAYACYAABURMzI+AzU0JxYVFAcWFRQOBQc1Mj4DNTQmNQ4DHhZASD4p\
BR4TEhwuODszJwYWQUg+KQEVVk1EAQFXGDRFZDchGTk2KykrLCVIPTo3MzkbqxkzRWU3BAwDKV1D\
UwAAAAADAAD9KgE8AJEAGwApADcAABkBMx4GFRQHFhUUBxYVFAc2NTQuAiM1HgMXNDY1NC4CIyce\
Axc0NjU0LgIjHgYnMzs4LhwSEhITHgU9V1UcCURNVhUBPFZVHQIJRE1WFQE8VlUd/pACARs5Mzc6\
PUglLCsnLSwrKSs2ORkhRHdIKakkVEFdKQQNA0R2SCmrJFNCXSkEDQNEdkgpAAADAAD/VgE8Ar0A\
HAApADYAABEzMj4DNTQnFhUUBxYVFAcWFRQOBQcjNzI+AjU0JjUOAycyPgI1NCY1DgMeFkBIPikF\
HhMSEhIcLjg7MycGHh4dVVc9ARVWTUQJHVVXPQEVVk1EAVcYNEVkNyEZOTYrKSssLScrLCVIPTo3\
MzkbqilJeEQEDAQpXUNUhilJeEQDDQQpXUNUAAQAAP1CATwBVAAgAC4APABKAAAZATMeBhUUBxYV\
FAcWFRQHFhUUBzY1NC4DIzUeAxc0NjU0LgMnHgMXNDY1NC4DJx4DFzQ2NTQuAx4GJzM7OC4cEhIS\
EhITHgUpPkhAFglETVYVASk+SEEWCURNVhUBKT5IQRYJRE1WFQEpPkhB/qgCrBs5Mzc6PUglLCsn\
LSwrJy0sKykrNjkZITdkRTQYqyRUQ10pBAwEN2VFMxmrJFRDXSkDDgM3ZUUzGaskVENdKQQMBDdl\
RTMZAAQAAP6OATwCoAAfACwAOQBGAAAZATMyPgI1NCcWFRQHFhUUBxYVFAcWFRQOBQc1Mj4CNTQm\
NQ4DJzI+AjU0JjUOAycyPgI1NCY1DgMeHFVXPQUeExISEhISHC44OzMnBh1VVz0BFVZNRAkdVVc9\
ARVWTUQJHVVXPQEVVk1E/o4CrClId0QhGTk2KykrLC0nKywtJyssJUg9OjczORuqKUl4RAMNBCld\
Q1SGKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1QAAAAFAAD9VQE8AhIAJAAyAEAATgBcAAAZATMeBhUU\
BxYVFAcWFRQHFhUUBxYVFAc2NTQuAyM1HgMXNDY1NC4DJx4DFzQ2NTQuAyceAxc0NjU0LgMnHgMX\
NDY1NC4DHgYnMzs4LhwSEhISEhISEx4FKT5IQBYJRE1WFQEpPkhBFglETVYVASk+SEEWCURNVhUB\
KT5IQRYJRE1WFQEpPkhB/rsDVxs5Mzc6PUglLCsnLSwrJy0sKyctLCspKzY5GSE3ZEU0GKskVENd\
KQMNBDdlRTMZqyRUQ10pBAwEN2VFMxmrJFRDXSkDDgM3ZUUzGaskVENdKQQMBDdlRTMZAAAFAAD9\
vAE8AnkAIwAwAD0ASgBXAAAZATMyPgI1NCcWFRQHFhUUBxYVFAcWFRQHFhUUDgUHNTI+AjU0JjUO\
AycyPgI1NCY1DgMnMj4CNTQmNQ4DJzI+AjU0JjUOAx4cVVc9BR4TEhISEhISEhwuODszJwYdVVc9\
ARVWTUQJHVVXPQEVVk1ECR1VVz0BFVZNRAkdVVc9ARVWTUT9vANXKUh3RCEZOTYrKSssLScrLC0n\
KywtJyssJUg9OjczORuqKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1SGKUl4RAMNBCldQ1SGKUl4RAMN\
BCldQ1QAAAACAAD/ZADhAbAACgAWAAA3IgYdATY3NjU0JjcyFhUUBwYjETMRNmcUKyImKx0HIzlL\
UkQoI3omE7kPODsvGyYmMiNJTFICTP68NAAAAgAA/oYAxQF6AAMADAAAFzc1BxEVNxEjNQcRNxyQ\
kKkZrAFlLZYtAUnoNP3A4jMCQwEAAAIAAP6YAP8BaAADAB8AADcVNzUDIzUHNTc1BzU3NTMVNzUz\
FTcVBxU3FQcVIzUHU1paHjU1NTUeWh01NTU1HVpGpxun/jejD1wPpw9aD6ifHKujD1wPpw9aD6if\
HAAAAAEAFP+EAQsAegAeAAAXNSYnBzAVIzUzNycwIzUzFRYXNzA1MxUjBgcXMDMVwygMM0g5MzM5\
SCESNEg5IRM0OXw7Jg0zO0oyMkg5IhEzOUciETRIAAQAAP9qAWwBsAAOABwAKwA6AAA3DgEdATI3\
Njc2NTQnJiM3MhYVFAcGBwYjETMRNhcOAR0BMjc2NzY1NCcmIzcyFhUUBwYHDgEjETMRNk4RHg4e\
HwwEChARGR0rCRgrNS8fGdERHRAeHQsGCxAPFh8qCxkoFjcWHht9AR4QxikrNA0ZHhQVJjkhEiA5\
NEACRv7BMiYBHRHGKS8wExMcFhUmNiQWHD4vGyUCRv7BMgAAAQAA/wYAjAD6AA4AADcVBhUUFxUu\
AzQ+AoxQUBolMhsbMiX6FEOjpkAUDx86WnBaOh8AAAEAAP8GAIwA+gAOAAA1HgMUDgIHNTY1NCca\
JTIbGzIlGlBQ+g8fOlpwWjofDxRApqNDAAACADL/ZAENAbAACgAWAAA3IgYVFBcWFzU0JicyFxEz\
ESInJjU0NqsXIC4uGiozOiMjOlJPOXomGzBFQgPLEh4mNAFE/bRSUEUjMgAABP/1/2oBbAGwAA4A\
HQAsADsAADcjIgcGFRQXFhcWMzU0JicyFxEzESImJyYnJjU0NhcOAR0BMjc2NzY1NCcmIzcyFhUU\
BwYHDgEjETMRNlcBERAKBAwfHg4eKzAZHxY3FysYCSvpER0QHh0LBgsQDxYfKgsZKBY3Fh4bfRUU\
HhkNNCspxhAeJzIBP/26JRs0OSASITkmAR0RxikvMBMTHBYVJjYkFhw+LxslAkb+wTIAAAAAAQAA\
/sAAqQFAABMAABMzFTcVBxU3FQcVIzUHNTc1BzU3RB5HR0dHHkREREQBQKIOXA5/DloPqKIOXA5/\
DloPAAMAAP6YAToBaAAjACcAKwAANzUzFTcVBxU3FQcVIzUHFSM1DwEjNQc1NzUHNTc1MxU3NTMV\
AzUHFTcVNzXpHjMzMzMePR48AR4zMzMzHj0eHj1bPcCong9cD58PWg+1qhKspBCong9cD58PWg+1\
qhKspP79nhGfuJ4RnwAB//0AAAE/APQAGAAANwYjIiY1ND8BNi8BJjU0NjMyMRcFFhUUBxICAwcJ\
Bs8ODs0ICwcBAgEfDg4BARAICgNJBwZPAwsKEgFrBg4NBQAAAAEAAAAAAFAAUAAJAAA1NDYyFhQG\
IyImFyIXFxEQGCgRFxciFxgAAAABAAAAAAFUADIAAwAAMTUhFQFUMjIAAAABAAAAAABkARgAAwAA\
MwMzAygoZCgBGP7oAAAAAQAAAAABGAE1AAUAADEbASMnB4yMQVhaATX+y8bGAAACAAAAAAJYAUoA\
DgAZAAAxNDYzMh4CFSMuASIGByEiJjQ2MzIWFRQGs3k5a1UzDwui4KILARwXJSUXGSMjmLIsUYBN\
boaGbiQwJCQYGSMAAAEAAAAAALYBLQAXAAATMhYXFhUUBw4BIycmNTQ2NTQjLgE1NDZWGxsQGjIZ\
RBAGAUcUGygtAS0MER0wPTwdLQMBAghrEw8BJhweMQACAAT//wGOAfYAEQAjAAA3EzYzMhcWFRQH\
AwYjIicmNTQnEzYzMhcWFRQHAwYjIicmNTSYzQoLBAULBcwJCwQGC4vNCgsEBQsFzAkLBAYLIwHA\
EgIFCgcL/j8RAwYMBwcBwBICBQoHC/4/EQMGDAcAAQAA/wYAggD6AAMAADUzESOCgvr+DAAAAQAA\
AAAAggD6AAMAADUzFSOCgvr6AAAAAQAA/4MBLAAAAAMAADEhFSEBLP7UfQAAAQAAAAABLAB9AAMA\
ADUhFSEBLP7UfX0AAQAA/n4A6wGHABMAABMXBxcmIyIGFRQXJjU0NjMyFyc3Kb1nbDI0HyY4eDQl\
IiKHZAGH5dnPLiQdNTRLTSMtFby0AAABAAD/DQEAAMAAFgAANw4CIyImNTQ2MhYVFAcyNjc2MhcD\
J6sDGRoTKzcmOCkXIjMhAhUDljA8AQcEKSgfIB4ZHRshLAIC/m8QAAAAAQAA/gwBSADAACQAABcG\
IyImNTQ2MzIWFRQHMj8BBiMiJjU0NjMyFhUUBzI3NjIXAyerKCErNycbHCkXQQs8NhgrNycbHCkX\
SC4CFQPFLcQMKCggIB8ZHRsiygwpKB8gHhkdG00CAv1uDAAAAQAA/gwBjwHAADYAADcGIyImNTQ2\
MzIWFRQHMj8BIg4BIyImNTQ2MzIWFRQHMjc2MhcBJxMGIyImNTQ2MzIWFRQHMjf2KB8rNycbHCkX\
Pws6ASAcEys3JxscKRdILgEWA/70LVUoISs3JxscKRdBCzwMKCggIB8ZHRsiywkEKSgfIB4ZHRtN\
AgL8bgwBJAwoKCAgHxkdGyIAAAAAAQAA/QwB2gHAAEUAABMGIyImNTQ2MzIWFRQHMj8BBiMiJjU0\
NjMyFhUUBzI/AQYjIiY1NDYzMhYVFAcyPwEiDgEjIiY1NDYyFhUUBzI3NjIXASerKCErNycbHCkX\
QQs6KCErNycbHCkXQQs6KB8rNycbHCkXPws6ASAcEys3JjgpF0guAhUD/qkt/jwMKCggIB8ZHRsi\
ygwoKCAgHxkdGyLKDCgoICAfGR0bIssJBCkoHyAeGR0bTQIC+24MAAAAAQAA/QwCGQKuAFYAACUG\
IyImNTQ2MzIWFRQHMj8BBiMiJjU0NjMyFhUUBzI/ASIOASMiJjU0NjMyFhUUBzI3NjIXAScTBiMi\
JjU0NjMyFhUUBzI/AQYjIiY1NDYzMhYVFAcyNwE/KCErNycbHCkXQQs2KB8rNycbHCkXPws0ASAc\
Eys3JxscKRdILgEWA/5qLVUoISs3JxscKRdBCzooISs3JxscKRdBCzQMKCggIB8ZHRsixAwoKCAg\
HxkdGyLHCQQpKB8gHhkdG00CAvqADAEkDCgoICAfGR0bIsgMKCggIB8ZHRsiAAP/8P8GAiYA+gAH\
AA8AEwAANiImNDYyFhQAIiY0NjIWFAUBMwFQMiMjMiMBiDIjIzIj/dIBuH7+R0sjMiMjMv7PIzIj\
IzJaAfT+DAAE/+H/BgMHAPoABwAPABMAFwAANiImNDYyFhQAIiY0NjIWFAUBMwEzATMBQTIjIzIj\
AncyIyMyI/zjAbh7/kd5Abh7/kdLIzIjIzL+zyMyIyMyWgH0/gwB9P4MAAL/tP+IAXwBGAARADsA\
ADcWMzI2NzY1NCcmIyIGBwYVFBciJwczMhQrASI0OwETNjU0IyIOAwcGJjc2NzYzMhYXPgEzMhYV\
FAbFAgUSMg4NDwIEEjULDycqGS00CwvhCwtLaAYLCAwPCxkKBRsFMQ8XJSMkBx0mIx4tWSgBNSQg\
JiUFATMcJyQpLiB6Hh4BHRIMDwcUEiwQCA8JWBAZExoeDzQwSWsAAAH/2//2Ab4BGABTAAA3BgcG\
KwEiPwE2JiMiBgcGJjc+AzMyFzYzMhc+ATMyFhUUDwEGFRQzMjc+BTc2FgcOAiMiJjU0PwE2NTQj\
Ig8BBgcnBiY/ATY1NCMiB1AHCAQENQ0NQgQGCA0WJAUVBBQQIh8SNwskJC0JCykTGSQFLwQIAQQF\
CwcMAw0BBhUGEhctHxUZBTQBFRsIQQgPJg0IBEMBFRsIFREDARqnDQ8aOQgMCSUaMBIoKCgQGCMa\
Cw99CwkOAgMJBg8FEgEJDQsfHxoWEw0NiAIEDhSrFgEBAQ8IqwIEDhQAAAAB/37/YAFeAbgAQQAA\
ByImNTQ2MzIWFRQHBhUUMzI+BzcjIjU0OwE+ATMyFhUUBiMiJjU0NzY0IyIOBwczMhQrAQ4BMiAw\
FxMSFxIKGQsQDwsNCg4NFAo1ExFBFGk0IDAXExIXEgoZBwwKBwgFBgMGATYTEz8hdqAmIBoiFA8O\
CwcNDgYREyUkPDdVJxUTS18mIBoiFA8OCwYcBQsKFA0aDR4GKMXBAAAB/9sAAAETARMAKgAANz4B\
JiMiBg8BBgcGKwEiPwE2JiMiBgcGJjc+ATMyFhc2MzIWFRQjIiY1NNAFAwMFFCQJPwcIBAQ1DQ1C\
BAYIDhciBRUEITgiGx0EHyQaICsPG+cDBwQsGJwRAwEaow0PGjUIDAk8QBoNJx4ZNxYNFAAAAAEA\
AAAAANwBGAAxAAAzIiY1NDYyFhUUBxYzMjY1NC4CJyY1NDYzMhYVFAYjIiY1NDcmIyIGFRQeAhcW\
FRRQHjIVGhcQDBMWIQkLGAY6Ny0iNhYQDRYHDxEPGRESHgUwKxsQFhAMEhAQFhILDwcNBCUwIygk\
GBAYFA4DDhMRDQkTDBEDICtVAAAB/+T//ADnAQ8APAAAJwYuAT8BIgYjIiYOAQcGJyY3PgE3HgEz\
MjYzMhcWFA8BBhUUMzI2MzIXFjc2JyI1NDYzMhUUBisBLgEjIgoGCwEFsAUfDAMUDB8FDwQDCAwL\
AQ4vFSIrBAgFCweeAgIBDQYaIw0IBQckEg0mKB4dGCUIDgMECA0GwQYGAjIFDQsJEh4wAgEGCwEB\
EQenBgIDAxoKDg0DHQ4VNx4vAxgABf+0/4gFSwEYABEAIwC2AMgA2gAAJRYzMjY3NjU0JyYjIgYH\
BhUUBRYzMjY3NjU0JyYjIgYHBhUUFyInBzMyFCsBIjQ7ARM2NTQjIg4DBwYmNzY3NjMyFhc+ATMy\
Fz4BMzIWFz4BMzIXPgEzMhYXPgEzMhc+ATMyFhc+ATMyFhUUBiMiJwczMhQrASI0OwETNjU0IyIG\
BxUUBiMiJwczMhQrASI0OwETNjU0IyIGBxUUBiMiJwczMhQrASI0OwETNjU0IyIGBxUUBiUWMzI2\
NzY1NCcmIyIGBwYVFAUWMzI2NzY1NCcmIyIGBwYVFAIKAwQSMg4NDwMDEzQLD/7LAwQSMg4NDwMD\
EzQLDxMWGS00CwvhCwtLaAYLCAwPCxkKBRsFMQ8XJSMkBx0mIy8TEiIbIyQHHSYjLxMSIhsjJAcd\
JiMvExIiGyMkBx0mIx4ta0kWGS00CwvhCwtLaAYLDhQUa0kWGS00CwvhCwtLaAYLDhQUa0kWGS00\
CwvhCwtLaAYLDhQUawODAwQSMg4NDwMDEzQLD/7LAwQSMg4NDwMDEzQLDygBNSQhJSQGATMcJiUo\
BwE1JCElJAYBMxwmJSgvIHoeHgEdEA4PBxQSLBAIDwlYEBkTGh4PMhwWExoeDzIcFhMaHg8yHBYT\
Gh4PNDBHbSB6Hh4BHRAODxgjAUdtIHoeHgEdEA4PGCMBR20geh4eAR0QDg8YIwFHbSgBNSQhJSQG\
ATMcJiUoBwE1JCElJAYBMxwmJSgAAAAE/7T/iAQGARgAbwCBAJMApQAAISInBzMyFCsBIjQ7ARM2\
NTQjIgYHFRQGIyInBzMyFCsBIjQ7ARM2NTQjIgYHFRQGIyInBzMyFCsBIjQ7ARM2NTQjIg4DBwYm\
NzY3NjMyFhc+ATMyFz4BMzIWFz4BMzIXPgEzMhYXPgEzMhYVFAYnFjMyNjc2NTQnJiMiBgcGFRQF\
FjMyNjc2NTQnJiMiBgcGFRQFFjMyNjc2NTQnJiMiBgcGFRQDUhYZLTQLC+ELC0toBgsOFBRrSRYZ\
LTQLC+ELC0toBgsOFBRrSRYZLTQLC+ELC0toBgsIDA8LGQoFGwUxDxclIyQHHSYjLxMSIhsjJAcd\
JiMvExIiGyMkBx0mIx4ta0wDBBIyDg0PAwMTNAsP/ssDBBIyDg0PAwMTNAsP/ssDBBIyDg0PAwMT\
NAsPIHoeHgEdEA4PGCMBR20geh4eAR0QDg8YIwFHbSB6Hh4BHRAODwcUEiwQCA8JWBAZExoeDzIc\
FhMaHg8yHBYTGh4PNDBHbSgBNSQhJSQGATMcJiUoBwE1JCElJAYBMxwmJSgHATUkISUkBgEzHCYl\
KAAAA/+0/4gCwQEYAEwAXgBwAAAzIicHMzIUKwEiNDsBEzY1NCMiDgMHBiY3Njc2MzIWFz4BMzIX\
PgEzMhYXPgEzMhYVFAYjIicHMzIUKwEiNDsBEzY1NCMiBgcVFAYnFjMyNjc2NTQnJiMiBgcGFRQF\
FjMyNjc2NTQnJiMiBgcGFRTIFhktNAsL4QsLS2gGCwgMDwsZCgUbBTEPFyUjJAcdJiMvExIiGyMk\
Bx0mIx4ta0kWGS00CwvhCwtLaAYLDhQUa0wDBBIyDg0PAwMTNAsPAVUDBBIyDg0PAwMTNAsPIHoe\
HgEdEA4PBxQSLBAIDwlYEBkTGh4PMhwWExoeDzQwR20geh4eAR0QDg8YIwFHbSgBNSQhJSQGATMc\
JiUoBwE1JCElJAYBMxwmJSgAAv/b/4gDKwEYAHIAhAAAJTY3NjMyFhc+ATMyFhUUBiMiJwczMhQr\
ASI0OwETNjU0IyIOAwcOASMiJjU0PwE2NTQjIg8BBgcnBiY/ATY1NCMiDwEGBwYrASI/ATYmIyIG\
BwYmNz4DMzIXNjMyFz4BMzIWFRQPAQYVFDMyNz4BFxYzMjY3NjU0JyYjIgYHBhUUAa0xFBgiIyQH\
HSYjHi1rSRYZLTQLC+ELC0toBgsHDxIOGAgaPC0VGQU0ARUbCEEIDyYNCARDARUbCEQHCAQENQ0N\
QgQGCA0WJAUVBBQQIh8SNwskJC0JCykTGSQFLwQIAgMPJdEDBBIyDg0PAwMTNAsPd2wYHRMaHg80\
MEdtIHoeHgEdEA4PDR8bNRA2OBUUDA6IAwMOFKsWAQEBDwirAwMOFKwRAwEapw0PGjkIDAklGjAS\
KCgoEBgjGg0NfQsJDgIINTkBNSQhJSQGATMcJiUoAAAC/9v/YAMZAbgAUwCZAAA3BgcGKwEiPwE2\
JiMiBgcGJjc+AzMyFzYzMhc+ATMyFhUUDwEGFRQzMjc+BTc2FgcOAiMiJjU0PwE2NTQjIg8BBgcn\
BiY/ATY1NCMiBxMiJjU0NjMyFhUUBwYVFDMyPgc3IyImNTQ2OwE+ATMyFhUUBiMiJjU0NzY0IyIO\
BwczMhYUBisBDgFQBwgEBDUNDUIEBggNFiQFFQQUECIfEjcLJCQtCQspExkkBS8ECAIDBQsHDAMN\
AQYVBhIXLR8VGQU0ARUbCEEIDyYNCARDARUbCPUgMBcTEhcSChkLEA8LDQoODRQKNQkKCQhBFGk0\
IDAXExIXEgoZBwwKBwgFBgMGATYJCwsJPyF2FREDARqnDQ8aOQgMCSUaMBIoKCgQGCMaDQ19CwkO\
AgMJBg8FEgEJDQsfHxoVFAwOiAMDDhSrFgEBAQ8IqwMDDhT+nyYgGiIUDw4LBw0OBhETJSQ8N1Un\
DAkIC0tfJiAaIhQPDgsGHAULChQNGg0eBgwQDMXBAAAAAf9+/2ACaQG4AHgAACUjDgEjIiY1NDYz\
MhYVFAcGFRQzMj4HNyMiJjU0NjsBPgEzMhYVFAYjIiY1NDc2NCMiBwYHFz4BMzIWFRQGIyImNTQ3\
NjQjIg4HBzMyFhQGKwEOASMiJjU0NjMyFhUUBwYVFDMyPgcBX5shdl8gMBcTEhcSChkLEA8LDQoO\
DRQKNQkKCQhBFGk0IDAXExIXEgoZJhcDAZsUaTQgMBcTEhcSChkHDAoHCAUGAwYBNgkLCwk/IXZf\
IDAXExIXEgoZCxAPCw0KDw0U5sXBJiAaIhQPDgsHDQ4GERMlJDw3VScMCQgLS18mIBoiFA8OCwYc\
cwwGAUtfJiAaIhQPDgsGHAULChQNGg0eBgwQDMXBJiAaIhQPDgsHDQ4GERMlJDw3VQAAAAH/fv9g\
A3QBuACuAAATMz4BMzIWFRQGIyImNTQ3NjQjIgcGBxc+ATMyFhUUBiMiJjU0NzY0IyIOBwczMhYU\
BisBDgEjIiY1NDYzMhYVFAcGFRQzMj4HNyMOASMiJjU0NjMyFhUUBwYVFDMyPgc3Iw4BIyImNTQ2\
MzIWFRQHBhUUMzI+BzcjIiY1NDY7AT4BMzIWFRQGIyImNTQ3NjQjIg4CBwbMnBRpNCAwFxMSFxIK\
GSYXAwGbFGk0IDAXExIXEgoZBwwKBwgFBgMGATYJCgoJPyF2XyAwFxMSFxIKGQsQDwsNCg8NFAqb\
IXZfIDAXExIXEgoZCxAPCw0KDg0VCpshdl8gMBcTEhcSChkLEA8LDQoODRQKNQkKCQhBFGk0IDAX\
ExIXEgoZDhUOCAYCAQ5LXyYgGiIUDw4LBhxzDAYBS18mIBoiFA8OCwYcBQsKFA0aDR4GDBAMxcEm\
IBoiFA8OCwcNDgYREyUkPDdVJ8XBJiAaIhQPDgsHDQ4GERMlJDs4VSfFwSYgGiIUDw4LBw0OBhET\
JSQ8N1UnDAkIC0tfJiAaIhQPDgsGHBMnIhsKAAH/fv9gBIABuADkAAABFz4BMzIWFRQGIyImNTQ3\
NjQjIgcGBxc+ATMyFhUUBiMiJjU0NzY0IyIOBwczMhYUBisBDgEjIiY1NDYzMhYVFAcGFRQzMj4H\
NyMOASMiJjU0NjMyFhUUBwYVFDMyPgc3Iw4BIyImNTQ2MzIWFRQHBhUUMzI+BzcjDgEjIiY1NDYz\
MhYVFAcGFRQzMj4HNyMiJjU0NjsBPgEzMhYVFAYjIiY1NDc2NCMiBwYHFz4BMzIWFRQGIyImNTQ3\
NjQjIg4HAdicFGk0IDAXExIXEgoZJhcDAZsUaTQgMBcTEhcSChkHDAoHCAUGAwYBNgkKCgk/IXZf\
IDAXExIXEgoZCxAPCw0KDw0UCpshdl8gMBcTEhcSChkLEA8LDQoODRQKmyF2XyAwFxMSFxIKGQsQ\
DwsNCg8NFAqbIXZfIDAXExIXEgoZCxAPCw0KDg0UCjUJCgkIQRRpNCAwFxMSFxIKGSYXAwGbFGk0\
IDAXExIXEgoZBwwKBwgFBgMGAQ8BS18mIBoiFA8OCwYccwwGAUtfJiAaIhQPDgsGHAULChQNGg0e\
BgwQDMXBJiAaIhQPDgsHDQ4GERMlJDw3VSfFwSYgGiIUDw4LBw0OBhETJSM8N1YnxcEmIBoiFA8O\
CwcNDgYREyUkPDdVJ8XBJiAaIhQPDgsHDQ4GERMlJDw3VScMCQgLS18mIBoiFA8OCwYccwwGAUtf\
JiAaIhQPDgsGHAUKCxMOGQ4dAAAAAAMAAP9gAt8BuAA2AHIAuwAAMyImNTQ2MzIWFRQHFjMyNjU0\
LgMnLgI1NDYzMhYVFAYjIiY1NDcmIyIGFRQeAhceARUUJQYuAT8BJiMiBiMiDgEHBicmNz4BNxYz\
MjYzMhcWFA8BBhUUHgEXFj4BJy4BNTQ2MzIVFAYjIiMuASMiBSImNTQ2MzIWFRQHDgEeARUUFjI+\
BzcjIiY1NDY7AT4BMzIWFRQGIyImNTQ3NjQjIg4HBzMyFhQGKwEOAVAeMhIMDhcMBhgWIQMMBRcD\
FBgUNy0iNhYQDRYFEA4PGRESHgUbFwEmBgsBBa4KFAYcBgUQEgUQBQMHCwwBLR4gKAcJDQsHmgQa\
Kg0FCQUCAyQUDCYrIAMDFzUJE/60IDAXExIXEgQBAQIGFhAPCw0KDg0UCjUJCgkIQRRpNCAwFxMS\
FxIKGQcMCgcIBQYDBgE2CQoKCT8hdisbEBYNCxgMEhYSCQwNBA4CDRIeDyMtJBgQGBQOCAgUEQ0J\
EwwRAxIfFVoDBAgNBr8FARgfBA0LCBMeLgQDCAIBEQejBgQHAwcLAwQNBggIFAsTNx4qAg2yJiAa\
IhQPDgsCBQQGAwgGBhETJSQ8N1UnDAkIC0tfJiAaIhQPDgsGHAULChQNGg0eBgwQDMXBAAAAAgAF\
//sB/AGaAAkALAAAAQ8BBhUUMzI2NwcOASMiJjU0PwEjNTM/AQc3MhU2MzIWFRQGIiY1NDcGDwEj\
ATZ/OQIUGEQSDCkyHyIiAzdpcxZZJpgZIDUYHRggFgk3EEJIAQkHuAgDFRcPKBkUJBoLC7MgSi54\
Ci0pHBUSGxEOEhMPJ9gAAQAA//0BtQDUAC8AACUyNTQnBiImNT4BMzIWFRQHBiMiLwEmIyIVFBc2\
MzIWFRQGByInJjU0NzYzFh8BFgFwLRoQHBQBFwkkLSkXHiYeohoRLhkQDw0VFA0dGBwoFiIqF6Ic\
MTkgExAWDQ4WMzUzJBUVehI6IBIQFw4PEgIaIi0zJBMCEHoTAAEAAP/NAbUBAwA2AAAXIiY1NDc2\
MxYfATUzFRcWMzI2NTQnBiMiNT4BMzIWFRQHBiMiLwEVIzUnJiMiBhUUFzYzMhUUTSAtKBYgKBcu\
HlwiDxUcFhQSHAEPCSAtKRccJB4uHlwgDxYcFRQTHANDJjMkEwIQJGmARxcpHCcQDBsPFUImMyQV\
FSRsg0cWKB4nDwwdIAABAA0AAAJFAOAACwAANyc3FzcXNxcHJwcnIhWOZXhqTRaSaXRpLhmZfHx8\
VBehfHx8AAAAAQAN/8sCRQERABMAACUHJwcnNxc3NTMXNxc3FwcnBxUjARZAaUsVjmUWGwFGak8U\
kmkZG0ZGfE4ZmXwXlntKfFUYoXwblgAAAQAAAAABGAEYAAsAADM1IzUzNTMVMxUjFXt7eyJ7e3si\
e3siewAAAAEAAAAAATYBcgAKAAAxNT4ENzMUBiQxTDQ0Dx7APAcPKz1vSY7aAAAB//8AAAEtAKAA\
HQAANz4CMzIeARcWMzI3NhYHDgIjIi4BJyYjIgcGJgEJECkcGCYmDwkKHhgEDgIIESkcGCQlEgcI\
HR0FDUYZISAhMQoGJAYHBxkiHyExCgQjBggAAAABAAAAAAEsASwABwAAMREhESM1IxUBLCPmASz+\
1LS0AAEAAAAAAPoBwgAGAAAzAzMbATMDaWkoVVUoaQHC/pgBaP4+AAIAAAAAAMgAyAAHAA8AADYy\
NjQmIgYUFiImNDYyFhRFPiwsPix0Ujs7UjsZLD4sLD5FO1I7O1IAAf84AAAAyADIAAsAACM0NjIW\
FSM0JiIGFch2pHYeYJRgUnZ2UkpgYEoAAAACAAAAAAC0ASwABwAVAAA2MjY0JiIGFBc1LgE1NDYy\
FhUUBgcVSx4bGx4bGB0rN0Y3Kx14NTY1NTatZAg1Jyg8PCgnNQhkAAACAAAAAADIASwADwAfAAA3\
LgE1NDYyFhUUBgcdASM1Nz4BNTQmIgYVFBYXPQEzFVQkMDtSOzAkICAZIiw+LCIZIGYFOCUpOzsp\
JTgFAWVlGQYpGx8sLB8bKQYBSUkAAAAEAAD//AP0An8AhQCPAJsApQAANz4BNTQnLgE1ND4CPwIO\
ARUUMzI3Fw4BIyImNTQ+AjMyFhUUBiMiJic3HgEzMjU0LgInBwYVFB4CFRQGDwEeAjM6ATMyNyY1\
NDc2MzIWFRQHBgceATMyNjU0NjcuAj0BHgEVFAYjIicGIyIuAScOASImJyYjIg4BBwYjIjU0NgUi\
JjQ2MzIWFAYlPgE1NCcmIyIGFRQFNjU0JicOARUUmDZFBQNSAwQFAQI9YmogHh0aFSklHi0fPnBI\
fXIyLhw2EhgRFBQzDBxALRsJHSIdHxAQDikfDAMIAhAjIRwiTBsjCh08EyAbFjFDXSCBXrq0UUJB\
IyQ8ITMWDiwoIBscGhIKFBkGWiEKMANcCxMTCwwSEf4PMyQEBRUcLgE8WhcSPzBaGD8gCwsIdCIF\
Dg4MBASlBGMsIzwNQi8mGiFHRCxRNzA1MCsOHhEyChoiGgJCJBseNiEsFSZPFBQKKRoeNSg1JS4r\
ICETOTAXEioZUl8ZLFk0BgE8sWtGXzk6FRQSJhkWIC0LFQQ6Bw04TxIYEhIYEoAvLxsHDhI5Kx50\
BYEiSRUdWEQ/AAACAAwACgHTAc8ACgCPAAAlNCYjIgYUFjMyNicOASMiJjQ2MzIWFzY1NCcmIyIm\
NDYzMhceARcWMzI1NCcuATU0NjMyFhUUBgcUMzI3PgE3NjMyFhUUBiMiBgcGFRQzMjYzMhYUBiMi\
JiMiBhUUFx4BFxYVFAYjIicuAScmIyIVFBYVFAYjIiY0NjU0IyIHDgEHBiMiJjU0NzYzMjc2NTQB\
FhgPEBUWDxAXiRkmDhkbGhkNKhglDBQYHRwZFxIQCwMUCxIUAQInHhQSGyMBFhANEQENDBoTHhsS\
GxUNECEbKw4cGx0ZDycUFxILFDgNDhkXExQMARMRChIqIBMSHSYXDQ4SAxESDBQaDQwWIxIN7hAU\
EyIWFQoBJRkqGyUCAxYOChMcKB0MCz4WDRgNCBcnDxcaGxYRIxkqEBM4Dw4bFBEjBgsODxYnHSga\
JggKFgoSAwsNGRMbDgs5FQ8fHjATFBgaJDEXJA4SPQwHFhQYDg0SDQwaAAAAAwAA/wYB9AD6AAcA\
DwAXAAA2FBYyNjQmIgI0NjIWFAYiNiImNDYyFhQteKp4eKqlktCSktCBMiMjMiNVqnh4qnj+y9CS\
|
| ︙ | ︙ | |||
352 353 354 355 356 357 358 | HAAAJSYjIgYVFBcWMzI2NTQTMxEUBiMiJyY1NDYzMhcBJA0lPJcGCyY8lwIdfkhPJA9+SEAkRBdh\ KwoJF2ErCQJu/W5DZ0MeHUNnLQAAAAABAAD/eQFAAqgADQAAATMRFAYjIiY1NDYzMhcBIh55WTI8\ elgxHwKo/YBGaTgnRWocAAAAAQAA/3kCCgKoABoAAAERFAYjIiY1NDYzMhcRNTMeBBUUBzY1NAFA\ eVkyPHpYMR8eBi45OCUyEgG5/m9GaTgnRWocAU7vNVxHTnVJSHJBSe8AAAAAAgAA/3kCCwKoAB8A\ KAAAJTURMx4EFRQHFhUUBzY1NCYjERQGIyImNTQ2MzITHgEXNDY1NCYBIh4JMDg2IxUWIgV2OHlZ\ Mjx6WDE9DoUbAXZr5gFXJEc7QlgzJTIwJC5BGSFfnv7WRmk4J0VqAXY7ojUDDgNfnwAAAQAA/84A\ ZAAyAAcAABYiJjQ2MhYURyodHSodMh0qHR0qAAAAAAAOAK4AAQAAAAAAAACDAQgAAQAAAAAAAQAH\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 |
HAAAJSYjIgYVFBcWMzI2NTQTMxEUBiMiJyY1NDYzMhcBJA0lPJcGCyY8lwIdfkhPJA9+SEAkRBdh\
KwoJF2ErCQJu/W5DZ0MeHUNnLQAAAAABAAD/eQFAAqgADQAAATMRFAYjIiY1NDYzMhcBIh55WTI8\
elgxHwKo/YBGaTgnRWocAAAAAQAA/3kCCgKoABoAAAERFAYjIiY1NDYzMhcRNTMeBBUUBzY1NAFA\
eVkyPHpYMR8eBi45OCUyEgG5/m9GaTgnRWocAU7vNVxHTnVJSHJBSe8AAAAAAgAA/3kCCwKoAB8A\
KAAAJTURMx4EFRQHFhUUBzY1NCYjERQGIyImNTQ2MzITHgEXNDY1NCYBIh4JMDg2IxUWIgV2OHlZ\
Mjx6WDE9DoUbAXZr5gFXJEc7QlgzJTIwJC5BGSFfnv7WRmk4J0VqAXY7ojUDDgNfnwAAAQAA/84A\
ZAAyAAcAABYiJjQ2MhYURyodHSodMh0qHR0qAAAAAAAOAK4AAQAAAAAAAACDAQgAAQAAAAAAAQAH\
AZwAAQAAAAAAAgAHAbQAAQAAAAAAAwAjAgQAAQAAAAAABAAHAjgAAQAAAAAABQAJAlQAAQAAAAAA\
BgAHAm4AAwABBAkAAAEGAAAAAwABBAkAAQAOAYwAAwABBAkAAgAOAaQAAwABBAkAAwBGAbwAAwAB\
BAkABAAOAigAAwABBAkABQASAkAAAwABBAkABgAOAl4AQwBvAHAAeQByAGkAZwBoAHQAIABcADIA\
NQAxACAAMgAwADEAOAAtADIAMAAxADkAIABKAGUAYQBuAC0ARgByAGEAbgBjAG8AaQBzACAATQBv\
AGkAbgBlAC4AIABUAGgAaQBzACAAZgBvAG4AdAAgAGkAcwAgAGwAaQBjAGUAbgBzAGUAZAAgAHUA\
bgBkAGUAcgAgAHQAaABlACAAUwBJAEwAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBz\
AGUAIABcACgAaAB0AHQAcAA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8A\
RgBMAFwAKQAuAABDb3B5cmlnaHQgXDI1MSAyMDE4LTIwMTkgSmVhbi1GcmFuY29pcyBNb2luZS4g\
VGhpcyBmb250IGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBTSUwgT3BlbiBGb250IExpY2Vuc2UgXCho\
dHRwOi8vc2NyaXB0cy5zaWwub3JnL09GTFwpLgAAYQBiAGMAMgBzAHYAZwAAYWJjMnN2ZwAAUgBl\
AGcAdQBsAGEAcgAAUmVndWxhcgAARgBvAG4AdABGAG8AcgBnAGUAIAAyAC4AMAAgADoAIABhAGIA\
YwAyAHMAdgBnACAAOgAgADEAMgAtADIALQAyADAAMgAyAABGb250Rm9yZ2UgMi4wIDogYWJjMnN2\
ZyA6IDEyLTItMjAyMgAAYQBiAGMAMgBzAHYAZwAAYWJjMnN2ZwAAVgBlAHIAcwBpAG8AbgAgACAA\
AFZlcnNpb24gIAAAYQBiAGMAMgBzAHYAZwAAYWJjMnN2ZwAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAACSAAAAAQACAQIAAwEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMB\
FAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEw\
ATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwB\
TQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFp\
AWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8BgAGBAYIBgwGEAYUB\
hgGHAYgBiQGKAYsBjAGNAY4BjwYubm9kZWYHdW5pRTAwMAd1bmlFMDMwB3VuaUUwMzgHdW5pRTAz\
OQd1bmlFMDQzB3VuaUUwNDUHdW5pRTA0Ngd1bmlFMDQ3B3VuaUUwNDgHdW5pRTA1MAd1bmlFMDVD\
B3VuaUUwNjIHdW5pRTA2OQd1bmlFMDdBB3VuaUUwN0IHdW5pRTA3Qwd1bmlFMDdEB3VuaUUwN0UH\
dW5pRTA4MAd1bmlFMDgxB3VuaUUwODIHdW5pRTA4Mwd1bmlFMDg0B3VuaUUwODUHdW5pRTA4Ngd1\
bmlFMDg3B3VuaUUwODgHdW5pRTA4OQd1bmlFMDhBB3VuaUUwOEIHdW5pRTA4Qwd1bmlFMDk0B3Vu\
aUUwOTUHdW5pRTBBMAd1bmlFMEExB3VuaUUwQTIHdW5pRTBBMwd1bmlFMEE0B3VuaUUwQTkHdW5p\
RTBCMwd1bmlFMTAxB3VuaUUxQjkHdW5pRTFCQgd1bmlFMUU3B3VuaUUxRjIHdW5pRTFGNAd1bmlF\
MUY3B3VuaUUxRjkHdW5pRTFGQwd1bmlFMUZFB3VuaUUxRkYHdW5pRTIwMAd1bmlFMjQwB3VuaUUy\
NDEHdW5pRTI0Mgd1bmlFMjQzB3VuaUUyNDQHdW5pRTI0NQd1bmlFMjQ2B3VuaUUyNDcHdW5pRTI0\
OAd1bmlFMjQ5B3VuaUUyNjAHdW5pRTI2MQd1bmlFMjYyB3VuaUUyNjMHdW5pRTI2NAd1bmlFMjZh\
B3VuaUUyNmIHdW5pRTI4MAd1bmlFMjgxB3VuaUUyODIHdW5pRTI4Mwd1bmlFNEEwB3VuaUU0QTIH\
dW5pRTRBNAd1bmlFNEE4B3VuaUU0QUMHdW5pRTRDMAd1bmlFNENFB3VuaUU0RDEHdW5pRTRFMQd1\
bmlFNEUyB3VuaUU0RTMHdW5pRTRFNAd1bmlFNEU1B3VuaUU0RTYHdW5pRTRFNwd1bmlFNEU4B3Vu\
aUU0RTkHdW5pRTRFQQd1bmlFNTAwB3VuaUU1MDEHdW5pRTUyMAd1bmlFNTIxB3VuaUU1MjIHdW5p\
RTUyMwd1bmlFNTI0B3VuaUU1MjUHdW5pRTUyOQd1bmlFNTJBB3VuaUU1MkIHdW5pRTUyQwd1bmlF\
NTJEB3VuaUU1MkYHdW5pRTUzMAd1bmlFNTMxB3VuaUU1MzkHdW5pRTU2Ngd1bmlFNTY3B3VuaUU1\
NjkHdW5pRTU2Qwd1bmlFNTZEB3VuaUU1ODIHdW5pRTVEMAd1bmlFNUUyB3VuaUU2MTAHdW5pRTYx\
Mgd1bmlFNjE0B3VuaUU2MTgHdW5pRTYyNAd1bmlFNjMwB3VuaUU2NTAHdW5pRTY1NQd1bmlFOTEw\
B3VuaUU5MTEHdW5pRTkxMgd1bmlFOTE0B3VuaUU5MTUHdW5pRTkxOAd1bmlFOTIwB3VuaUU5MjUH\
dW5pRTk1RAd1bmlFQTAyB3VuaUVBQTQHdW5pRUNBMgd1bmlFQ0EzB3VuaUVDQTUHdW5pRUNBNwd1\
bmlFQ0E5B3VuaUVDQjcAAAAAAAAB//8AAgABAAAAAAAAAAwAFAAEAAAAAgAAAAEAAAABAAAAAAAB\
AAAAAN2HW+gAAAAA0ZciFwAAAADeLXWv\
") format("truetype")'
|
Changes to font/abc2svg.sfd.
1 2 3 4 5 6 7 8 9 10 | SplineFontDB: 3.2 FontName: abc2svg FullName: abc2svg FamilyName: abc2svg Weight: Regular Copyright: Copyright \\251 2018-2019 Jean-Francois Moine. This font is licensed under the SIL Open Font License \\(http://scripts.sil.org/OFL\\). Version: ItalicAngle: 0 UnderlinePosition: 0 UnderlineWidth: 0 | | | | | 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 | SplineFontDB: 3.2 FontName: abc2svg FullName: abc2svg FamilyName: abc2svg Weight: Regular Copyright: Copyright \\251 2018-2019 Jean-Francois Moine. This font is licensed under the SIL Open Font License \\(http://scripts.sil.org/OFL\\). Version: ItalicAngle: 0 UnderlinePosition: 0 UnderlineWidth: 0 Ascent: 824 Descent: 200 InvalidEm: 0 LayerCount: 2 Layer: 0 1 "Back" 1 Layer: 1 0 "Fore" 0 XUID: [1021 296 1430826605 13506888] OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 0 CreationTime: 1433498007 ModificationTime: 1644676399 PfmFamily: 17 TTFWeight: 400 TTFWidth: 5 LineGap: 92 VLineGap: 92 Panose: 2 0 5 3 0 0 0 0 0 0 OS2TypoAscent: 0 |
| ︙ | ︙ | |||
46 47 48 49 50 51 52 | Encoding: Custom Compacted: 1 UnicodeInterp: none NameList: Adobe Glyph List DisplaySize: -96 AntiAlias: 1 FitToEm: 1 | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | Encoding: Custom Compacted: 1 UnicodeInterp: none NameList: Adobe Glyph List DisplaySize: -96 AntiAlias: 1 FitToEm: 1 WinInfo: 80 8 2 BeginPrivate: 0 EndPrivate TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 BeginChars: 143 143 StartChar: .nodef Encoding: 0 0 0 Width: 400 Flags: M LayerCount: 2 Fore |
| ︙ | ︙ | |||
127 128 129 130 131 132 133 | 0 1000 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE038 Encoding: 4 57400 4 | | | | | | | | | | | 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 | 0 1000 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE038 Encoding: 4 57400 4 Width: 37 Flags: HMW LayerCount: 2 Fore SplineSet 0 1000 m 1 37 1000 l 1 37 500 l 1 0 500 l 1 0 1000 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE039 Encoding: 5 57401 5 Width: 36 Flags: HMW LayerCount: 2 Fore SplineSet 0 1120 m 1 36 1120 l 1 35 868 l 1 -1 868 l 1 0 1120 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE043 Encoding: 6 57411 6 Width: 100 |
| ︙ | ︙ | |||
734 735 736 737 738 739 740 | StartChar: uniE07D Encoding: 18 57469 18 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 | StartChar: uniE07D Encoding: 18 57469 18 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 86 116 m 1 58 106 42 90 42 70 c 4 42 42 68 20 88 20 c 0 113 20 125 44 125 64 c 0 125 84 109 99 86 116 c 1 123 220 m 0 105 220 90 209 90 189 c 0 90 169 102 161 125 143 c 1 148 150 162 159 162 183 c 0 162 199 150 220 123 220 c 0 90 0 m 0 41 0 0 30 0 70 c 0 0 104 32 118 69 130 c 1 49 148 40 157 40 180 c 0 40 215 70 240 110 240 c 0 163 240 200 220 200 180 c 0 200 156 183 139 145 129 c 1 169 110 180 90 180 70 c 0 180 27 140 0 90 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE07E Encoding: 19 57470 19 Width: 360 Flags: HMW LayerCount: 2 Fore SplineSet 212 -1 m 0 166 -1 150 22 150 54 c 0 150 73 158 87 174 87 c 0 189 87 201 79 201 60 c 0 201 45 183 39 183 25 c 0 183 13 200 11 212 11 c 0 243 11 279 66 279 112 c 0 279 131 272 140 249 140 c 0 217 140 201 115 189 115 c 0 180 115 178 118 178 130 c 0 178 140 198 196 216 236 c 24 219 242 224 247 231 247 c 0 273 248 297 248 339 248 c 0 347 248 359 250 359 241 c 0 359 229 349 222 337 218 c 0 300 205 276 201 239 193 c 0 224 190 224 186 222 174 c 0 220 164 220 157 233 161 c 0 241 163 250 164 259 164 c 0 305 164 326 135 326 96 c 0 326 39 269 -1 212 -1 c 0 9 0 m 0 -2.48824948263 1.68260667765e-07 -3.48824945257 18.0000001683 9 18 c 0 12 17.9999999596 14 18 18 18 c 0 27 18 39 19 43 30 c 0 62 75 65 84 84 134 c 0 89 147 90 155 78 155 c 0 69 155 66 152 61 146 c 0 54 138 46 133 36 138 c 0 25 144 34 153 41 162 c 0 76 207 112 259 125 259 c 0 140 259 150 246 165 246 c 0 168 246 172 247 175 248 c 0 191 253 196 249 192 238 c 0 155 148 122 67 111 36 c 0 109.509271996 31.8259615875 108.551888787 28.5408311683 108.551888787 25.9855943378 c 0 108.551888787 19.9703983902 113.857348821 18 130 18 c 4 137.838821814 18 142.400463498 13.0842298053 142.400463498 8.39053563394 c 0 142.400463498 4.10259784076 138.593413823 -8.881784197e-16 130 0 c 0 95.3333333333 0 76.6666666667 -3.45002388166e-07 52.3703703704 -3.45002388166e-07 c 0 40.2222222222 -3.45002388166e-07 26.6666666667 -2.58751791125e-07 9 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE080 Encoding: 20 57472 20 Width: 430 Flags: HMW LayerCount: 2 Fore SplineSet 138 0 m 1 138 -130 168 -218 215 -218 c 1 260 -218 292 -130 292 0 c 1 292 130 268 218 215 218 c 1 165 218 138 130 138 0 c 1 0 3 m 1 0 140 95 250 215 250 c 1 335 250 430 140 430 0 c 1 430 -140 335 -250 215 -250 c 1 95 -250 0 -140 0 3 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE081 Encoding: 21 57473 21 Width: 290 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 100 250 l 25 |
| ︙ | ︙ | |||
801 802 803 804 805 806 807 | 115 100 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE082 | | | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | 115 100 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE082 Encoding: 22 57474 22 Width: 400 Flags: HMW HStem: -250 500 VStem: 0 400 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
836 837 838 839 840 841 842 | 28 25 0 60 0 128 c 0 0 213 102 250 199 250 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE083 | | | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 | 28 25 0 60 0 128 c 0 0 213 102 250 199 250 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE083 Encoding: 23 57475 23 Width: 380 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 102 170 m 1 |
| ︙ | ︙ | |||
873 874 875 876 877 878 879 | 252 177 223 213 175 213 c 0 131 213 109 193 102 170 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE084 | | | 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 | 252 177 223 213 175 213 c 0 131 213 109 193 102 170 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE084 Encoding: 24 57476 24 Width: 400 Flags: HMW HStem: -250 500 VStem: 0 400 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
904 905 906 907 908 909 910 | 325 -160 l 5 325 -209 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE085 | | | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 | 325 -160 l 5 325 -209 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE085 Encoding: 25 57477 25 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 18 -95 m 0 |
| ︙ | ︙ | |||
939 940 941 942 943 944 945 | 25 -217 0 -176 0 -152 c 0 0 -135 3 -113 18 -95 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE086 | | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | 25 -217 0 -176 0 -152 c 0 0 -135 3 -113 18 -95 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE086 Encoding: 26 57478 26 Width: 385 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 200 -210 m 0 |
| ︙ | ︙ | |||
969 970 971 972 973 974 975 | 1 133 74 250 200 250 c 0 257 250 298 244 340 205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE087 | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | 1 133 74 250 200 250 c 0 257 250 298 244 340 205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE087 Encoding: 27 57479 27 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 97 161 m 0 |
| ︙ | ︙ | |||
992 993 994 995 996 997 998 | 305 125 280 121 268 121 c 0 194 121 173 161 97 161 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE088 | | | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | 305 125 280 121 268 121 c 0 194 121 173 161 97 161 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE088 Encoding: 28 57480 28 Width: 400 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 154 -42 m 1 |
| ︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | 93 -250 0 -194 0 -130 c 0 0 -77 50 -44 108 -16 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE089 | | | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 | 93 -250 0 -194 0 -130 c 0 0 -77 50 -44 108 -16 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE089 Encoding: 29 57481 29 Width: 385 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 185 210 m 0 |
| ︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 | 384 -133 311 -250 185 -250 c 0 128 -250 87 -244 45 -205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE08A | | | 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | 384 -133 311 -250 185 -250 c 0 128 -250 87 -244 45 -205 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE08A Encoding: 30 57482 30 Width: 409 Flags: HMW LayerCount: 2 Fore SplineSet 303 164 m 1 311 163 315 162 321 161 c 1 |
| ︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 | 244 130 265 164 302 164 c 2 303 164 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08B | | | 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 | 244 130 265 164 302 164 c 2 303 164 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08B Encoding: 31 57483 31 Width: 408 Flags: MW LayerCount: 2 Fore SplineSet 303 164 m 1 311 163 315 162 321 161 c 1 |
| ︙ | ︙ | |||
1130 1131 1132 1133 1134 1135 1136 | 119 -58 126 -133 158 -175 c 0 165 -184 172 -191 180 -197 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08C | | | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 | 119 -58 126 -133 158 -175 c 0 165 -184 172 -191 180 -197 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE08C Encoding: 32 57484 32 Width: 500 Flags: HMW HStem: -250 500 LayerCount: 2 Fore SplineSet 0 35 m 25 |
| ︙ | ︙ | |||
1155 1156 1157 1158 1159 1160 1161 | 0 -35 l 25 0 35 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE094 | | | | | 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 | 0 -35 l 25 0 35 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE094 Encoding: 33 57492 33 Width: 260 Flags: MW HStem: -250 500 LayerCount: 2 Fore SplineSet 220 -490 m 0 228 -500 208 -509 200 -500 c 4 105 -388 20 -171 20 0 c 0 20 170 105 388 200 500 c 0 211 513 231 503 220 490 c 0 136 388 90 170 90 0 c 0 90 -169 138 -388 220 -490 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE095 Encoding: 34 57493 34 Width: 260 Flags: HMW LayerCount: 2 Fore SplineSet 20 -490 m 0 102 -388 150 -169 150 0 c 0 150 170 104 388 20 490 c 0 9 503 29 513 40 500 c 0 135 388 220 170 220 0 c 0 220 -171 135 -388 40 -500 c 0 32 -509 12 -500 20 -490 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A0 Encoding: 35 57504 35 Width: 619 Flags: HMW LayerCount: 2 Fore SplineSet 424 -32 m 0 424 38 361 99 280 99 c 0 |
| ︙ | ︙ | |||
1223 1224 1225 1226 1227 1228 1229 | 87 85 176 130 312 130 c 0 448 130 537 80 537 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A1 | | | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | 87 85 176 130 312 130 c 0 448 130 537 80 537 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE0A1 Encoding: 36 57505 36 Width: 530 Flags: HMW LayerCount: 2 Fore SplineSet 30 65 m 25 30 -65 l 25 |
| ︙ | ︙ | |||
1252 1253 1254 1255 1256 1257 1258 | 0 -220 l 25 0 220 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE0A2 | | | | 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 | 0 -220 l 25 0 220 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE0A2 Encoding: 37 57506 37 Width: 450 Flags: HMW LayerCount: 2 Fore SplineSet 337 -30 m 4 337 40 264 101 193 101 c 4 154 101 109 75 109 31 c 4 109 -40 186 -97 257 -97 c 4 298 -97 337 -75 337 -30 c 4 450 0 m 4 450 -70 361 -129 225 -129 c 4 89 -129 0 -70 0 0 c 4 0 70 89 129 225 129 c 4 361 129 450 70 450 0 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE0A3 Encoding: 38 57507 38 Width: 329 Flags: MW LayerCount: 2 Fore SplineSet 292 68 m 4 283 84 264 91 242 91 c 4 |
| ︙ | ︙ | |||
1298 1299 1300 1301 1302 1303 1304 | 0 70 105 148 198 148 c 4 245 148 288 128 313 81 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE0A4 | | | | 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 | 0 70 105 148 198 148 c 4 245 148 288 128 313 81 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE0A4 Encoding: 39 57508 39 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 320 40 m 4 320 -51 231 -135 110 -135 c 4 40 -135 0 -90 0 -40 c 4 0 50 90 135 210 135 c 4 280 135 320 90 320 40 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE0A9 Encoding: 40 57513 40 Width: 330 Flags: HMW LayerCount: 2 Fore SplineSet -2 113 m 1 25 145 l 1 |
| ︙ | ︙ | |||
1338 1339 1340 1341 1342 1343 1344 | 132 -0 l 1 -2 113 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE0B3 | | | 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 | 132 -0 l 1 -2 113 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE0B3 Encoding: 41 57523 41 Width: 300 Flags: HMW LayerCount: 2 Fore SplineSet 150 -18 m 1 79 -90 l 1 |
| ︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 | 300 -83 233 -150 150 -150 c 24 67 -150 0 -83 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE101 | | | | | | | | 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 | 300 -83 233 -150 150 -150 c 24 67 -150 0 -83 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE101 Encoding: 42 57601 42 Width: 560 Flags: W LayerCount: 2 Fore SplineSet 0 -250 m 5 440 250 l 5 560 250 l 5 119 -250 l 5 0 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE1B9 Encoding: 43 57785 43 Width: 330 Flags: W HStem: -140 280 VStem: 0 330 LayerCount: 2 Fore SplineSet 0 0 m 1 165 140 l 1 330 0 l 1 165 -140 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE1BB Encoding: 44 57787 44 Width: 330 Flags: W HStem: -140 280 VStem: 0 330 LayerCount: 2 Fore SplineSet 0 -140 m 29 165 140 l 25 330 -140 l 29 0 -140 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE1E7 Encoding: 45 57831 45 Width: 100 Flags: MW LayerCount: 2 Fore SplineSet 50 -50 m 3 22 -50 0 -28 0 0 c 3 0 28 22 50 50 50 c 3 78 50 100 28 100 0 c 3 100 -28 78 -50 50 -50 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE1F2 Encoding: 46 57842 46 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 0 680 m 1 320 680 l 1 320 40 l 2 320 -51 231 -135 110 -135 c 0 40 -135 0 -90 0 -40 c 0 0 50 90 135 210 135 c 0 244 135 271 124 290 107 c 1 290 560 l 1 0 560 l 1 0 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE1F4 Encoding: 47 57844 47 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 0 680 m 1 320 680 l 1 |
| ︙ | ︙ | |||
1487 1488 1489 1490 1491 1492 1493 | 0 560 l 1 0 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE1F7 | | | | | | | 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 1617 1618 1619 1620 1621 1622 1623 1624 | 0 560 l 1 0 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE1F7 Encoding: 48 57847 48 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 0 680 m 25 320 680 l 29 320 560 l 25 0 560 l 25 0 680 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE1F9 Encoding: 49 57849 49 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 0 500 m 25 320 500 l 25 320 380 l 25 0 380 l 29 0 500 l 25 0 680 m 25 320 680 l 25 320 560 l 25 0 560 l 25 0 680 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE1FC Encoding: 50 57852 50 Width: 100 Flags: HMW LayerCount: 2 Fore SplineSet 50 -38 m 7 22 -38 0 -16 0 12 c 7 0 40 22 62 50 62 c 7 78 62 100 40 100 12 c 7 100 -16 78 -38 50 -38 c 7 EndSplineSet Validated: 1 EndChar StartChar: uniE1FE Encoding: 51 57854 51 Width: 310 Flags: HMW LayerCount: 2 Fore SplineSet 0 960 m 29 310 960 l 29 310 930 l 29 30 930 l 29 30 770 l 29 0 770 l 29 0 960 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE1FF Encoding: 52 57855 52 Width: 230 Flags: HMW LayerCount: 2 Fore SplineSet 80 810 m 0 27 810 0 833 0 864 c 0 |
| ︙ | ︙ | |||
1592 1593 1594 1595 1596 1597 1598 | 160 933 180 916 180 890 c 0 180 847 149 810 80 810 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE200 | | | | | | 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 | 160 933 180 916 180 890 c 0 180 847 149 810 80 810 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE200 Encoding: 53 57856 53 Width: 310 Flags: HMW LayerCount: 2 Fore SplineSet 310 960 m 25 310 770 l 25 280 770 l 25 280 930 l 25 0 930 l 25 0 960 l 25 310 960 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE240 Encoding: 54 57920 54 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -239 m 13 0 0 l 5 30 0 l 5 51 -195 315 -321 315 -584 c 4 315 -643 302 -710 269 -785 c 5 282 -738 287 -691 287 -647 c 4 287 -452 175 -294 30 -239 c 5 0 -239 l 13 EndSplineSet Validated: 1 EndChar StartChar: uniE241 Encoding: 55 57921 55 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 239 l 1 30 239 l 1 178 280 288 445 288 642 c 0 288 688 282 736 269 785 c 1 302 711 315 647 315 588 c 0 315 328 51 195 30 0 c 0 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE242 Encoding: 56 57922 56 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -343 m 13 0 0 l 5 |
| ︙ | ︙ | |||
1673 1674 1675 1676 1677 1678 1679 | 291 -485 292 -479 292 -472 c 4 292 -278 101 -171 30 -171 c 5 EndSplineSet Validated: 1 EndChar StartChar: uniE243 | | | 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 | 291 -485 292 -479 292 -472 c 4 292 -278 101 -171 30 -171 c 5 EndSplineSet Validated: 1 EndChar StartChar: uniE243 Encoding: 57 57923 57 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -1 m 9 0 342 l 1 |
| ︙ | ︙ | |||
1698 1699 1700 1701 1702 1703 1704 | 292 479 291 484 291 491 c 1 226 365 56 278 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE244 | | | 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | 292 479 291 484 291 491 c 1 226 365 56 278 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE244 Encoding: 58 57924 58 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -368 m 9 0 145 l 1 |
| ︙ | ︙ | |||
1731 1732 1733 1734 1735 1736 1737 | 292 -135 105 -28 32 -28 c 0 31 -28 31 -28 30 -28 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE245 | | | 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 | 292 -135 105 -28 32 -28 c 0 31 -28 31 -28 30 -28 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE245 Encoding: 59 57925 59 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 343 m 17 30 343 l 1 |
| ︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 | 292 480 291 486 291 493 c 1 226 367 56 280 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE246 | | | 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 | 292 480 291 486 291 493 c 1 226 367 56 280 30 171 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE246 Encoding: 60 57926 60 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -344 m 9 0 340 l 1 |
| ︙ | ︙ | |||
1799 1800 1801 1802 1803 1804 1805 | 291 -145 292 -139 292 -132 c 0 292 62 101 169 30 169 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE247 | | | 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 | 291 -145 292 -139 292 -132 c 0 292 62 101 169 30 169 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE247 Encoding: 61 57927 61 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -370 m 9 0 314 l 1 |
| ︙ | ︙ | |||
1836 1837 1838 1839 1840 1841 1842 | 292 450 291 457 291 464 c 1 226 338 56 251 30 142 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE248 | | | 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 | 292 450 291 457 291 464 c 1 226 338 56 251 30 142 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE248 Encoding: 62 57928 62 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -325 m 9 0 530 l 1 |
| ︙ | ︙ | |||
1879 1880 1881 1882 1883 1884 1885 | 291 45 292 51 292 58 c 0 292 252 101 359 30 359 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE249 | | | 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 | 291 45 292 51 292 58 c 0 292 252 101 359 30 359 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE249 Encoding: 63 57929 63 Width: 315 Flags: HMW LayerCount: 2 Fore SplineSet 0 -580 m 9 0 275 l 1 |
| ︙ | ︙ | |||
1922 1923 1924 1925 1926 1927 1928 | 292 411 291 418 291 425 c 1 226 299 56 213 30 103 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE260 | | | 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 | 292 411 291 418 291 425 c 1 226 299 56 213 30 103 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE260 Encoding: 64 57952 64 Width: 269 Flags: HMW LayerCount: 2 Fore SplineSet 103 122 m 0 77 122 40 90 40 65 c 2 |
| ︙ | ︙ | |||
1947 1948 1949 1950 1951 1952 1953 | 40 108 l 1 63 142 93 160 133 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE261 | | | 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 | 40 108 l 1 63 142 93 160 133 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE261 Encoding: 65 57953 65 Width: 200 Flags: MW LayerCount: 2 Fore SplineSet 28 -101 m 1 172 -56 l 1 |
| ︙ | ︙ | |||
1973 1974 1975 1976 1977 1978 1979 | 1 377 l 1 28 378 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE262 | | | 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 | 1 377 l 1 28 378 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE262 Encoding: 66 57954 66 Width: 255 Flags: HMW LayerCount: 2 Fore SplineSet 83 70 m 21 83 -97 l 5 |
| ︙ | ︙ | |||
2018 2019 2020 2021 2022 2023 2024 | 83 -189 l 5 83 -360 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE263 | | | 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 | 83 -189 l 5 83 -360 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE263 Encoding: 67 57955 67 Width: 267 Flags: MW LayerCount: 2 Fore SplineSet 195 -124 m 9 195 -65 l 25 |
| ︙ | ︙ | |||
2054 2055 2056 2057 2058 2059 2060 | 267 -124 l 1 195 -124 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE264 | | | 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 | 267 -124 l 1 195 -124 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE264 Encoding: 68 57956 68 Width: 366 Flags: HMW LayerCount: 2 Fore SplineSet 78 125 m 1 55 124 31 100 31 78 c 2 |
| ︙ | ︙ | |||
2101 2102 2103 2104 2105 2106 2107 | 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE26a | | | | | 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 | 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE26a Encoding: 69 57962 69 Width: 140 Flags: HMW LayerCount: 2 Fore SplineSet 140 250 m 9 140 230 l 17 110 205 60 145 60 0 c 0 60 -145 110 -206 140 -230 c 9 140 -250 l 17 90 -220 0 -160 0 0 c 0 0 160 90 220 140 250 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE26b Encoding: 70 57963 70 Width: 140 Flags: HMW LayerCount: 2 Fore SplineSet 0 250 m 17 50 220 140 160 140 0 c 0 140 -160 50 -220 0 -250 c 9 0 -230 l 17 30 -206 80 -145 80 0 c 0 80 145 30 205 0 230 c 9 0 250 l 17 EndSplineSet Validated: 1 EndChar StartChar: uniE280 Encoding: 71 57984 71 Width: 269 Flags: HMW LayerCount: 2 Fore SplineSet 171 122 m 0 140 122 116 92 116 57 c 0 |
| ︙ | ︙ | |||
2162 2163 2164 2165 2166 2167 2168 | 76 -20 50 28 50 75 c 0 50 124 97 160 141 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE281 | | | 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 | 76 -20 50 28 50 75 c 0 50 124 97 160 141 160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE281 Encoding: 72 57985 72 Width: 366 Flags: HMW LayerCount: 2 Fore SplineSet 87 125 m 1 86 125 l 2 |
| ︙ | ︙ | |||
2209 2210 2211 2212 2213 2214 2215 | 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE282 | | | 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 | 219 113 l 1 235 143 256 163 291 163 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE282 Encoding: 73 57986 73 Width: 169 Flags: HMW LayerCount: 2 Fore SplineSet 68 320 m 8 98 320 l 1 |
| ︙ | ︙ | |||
2241 2242 2243 2244 2245 2246 2247 | 68 152 l 1 68 320 l 8 EndSplineSet Validated: 1 EndChar StartChar: uniE283 | | | 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | 68 152 l 1 68 320 l 8 EndSplineSet Validated: 1 EndChar StartChar: uniE283 Encoding: 74 57987 74 Width: 314 Flags: HMW LayerCount: 2 Fore SplineSet 233 192 m 17 233 360 l 1 |
| ︙ | ︙ | |||
2299 2300 2301 2302 2303 2304 2305 | 233 101 l 1 172 83 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE4A0 | | | 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 | 233 101 l 1 172 83 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE4A0 Encoding: 75 58528 75 Width: 320 Flags: W HStem: 0 244<5 15> VStem: -3 322 LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
2326 2327 2328 2329 2330 2331 2332 | 319 109 314 101 305 98 c 1 18 1 l 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4A2 | | | | | | | 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 | 319 109 314 101 305 98 c 1 18 1 l 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4A2 Encoding: 76 58530 76 Width: 80 Flags: HMW LayerCount: 2 Fore SplineSet 0 40 m 24 0 63 17 80 40 80 c 24 62 80 80 63 80 40 c 24 80 18 63 0 40 0 c 24 18 0 0 18 0 40 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE4A4 Encoding: 77 58532 77 Width: 340 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 0 50 l 25 340 50 l 25 340 0 l 25 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE4A8 Encoding: 78 58536 78 Width: 100 Flags: HMW LayerCount: 2 Fore SplineSet 40 0 m 25 0 280 l 25 100 280 l 25 60 0 l 25 40 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE4AC Encoding: 79 58540 79 Width: 280 Flags: W HStem: 0 309 VStem: 0 280 LayerCount: 2 Fore SplineSet 0 0 m 1 140 309 l 25 280 0 l 1 215 0 l 1 127 198 l 25 37 0 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4C0 Encoding: 80 58560 80 Width: 600 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 214 150 330 300 330 c 3 |
| ︙ | ︙ | |||
2417 2418 2419 2420 2421 2422 2423 | 332 120 359 92 359 60 c 3 359 27 333 0 299 0 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE4CE | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 | 332 120 359 92 359 60 c 3 359 27 333 0 299 0 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE4CE Encoding: 81 58574 81 Width: 182 Flags: HMW LayerCount: 2 Fore SplineSet 86 301 m 0 123 301 136 294 156 272 c 0 175 251 182 226 182 195 c 0 182 152 162 110 132 74 c 0 97 34 43 0 23 0 c 0 21 0 19 2 17 3 c 0 16 4 16 5 16 6 c 0 16 26 87 105 87 140 c 0 87 149 81 155 67 155 c 0 32 156 -0 184 -0 222 c 0 -0 258 27 301 86 301 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE4D1 Encoding: 82 58577 82 Width: 400 Flags: HMW LayerCount: 2 Fore SplineSet 152 35 m 2 357 483 l 2 363.701063819 494.913002345 369.847754103 501.282269343 377.916665809 501.282269343 c 0 380.684870018 501.282269343 383.679314405 500.532624121 387 499 c 0 394.855750978 495.072124511 397.988581796 490.19966499 397.988581796 483.852591655 c 0 397.988581796 478.888330538 396.072124511 473.021998882 393 466 c 2 189 17 l 2 183.913450587 6.82690117401 177.770860973 -0.178077048204 169.421173872 -0.178077048204 c 0 166.280201006 -0.178077048204 162.826901174 0.813199329137 159 3 c 0 151.569978236 7.33417936247 147.973652542 13.5852067603 147.973652542 20.8036006853 c 0 147.973652542 25.2434131355 149.334179362 30.0491902446 152 35 c 2 9 35 m 2 214 483 l 2 220.701063819 494.913002345 226.847754103 501.282269343 234.916665809 501.282269343 c 0 237.684870018 501.282269343 240.679314405 500.532624121 244 499 c 0 251.855750978 495.072124511 254.988581796 490.19966499 254.988581796 483.852591655 c 0 254.988581796 478.888330538 253.072124511 473.021998882 250 466 c 2 46 17 l 2 40.913450587 6.82690117401 34.7708609728 -0.178077048204 26.4211738717 -0.178077048204 c 0 23.2802010063 -0.178077048204 19.826901174 0.813199329137 16 3 c 0 8.56997823576 7.33417936247 4.97365254215 13.5852067603 4.97365254215 20.8036006853 c 0 4.97365254215 25.2434131355 6.33417936247 30.0491902446 9 35 c 2 EndSplineSet EndChar StartChar: uniE4E1 Encoding: 83 58593 83 Width: 130 Flags: HMW LayerCount: 2 Fore SplineSet 0 250 m 1 130 250 l 1 130 -250 l 5 0 -250 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E2 Encoding: 84 58594 84 Width: 130 Flags: MW LayerCount: 2 Fore SplineSet 0 250 m 1 130 250 l 1 130 0 l 1 0 0 l 1 0 250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E3 Encoding: 85 58595 85 Width: 300 Flags: MW LayerCount: 2 Fore SplineSet 0 0 m 1 300 0 l 1 300 -125 l 1 0 -125 l 1 0 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E4 Encoding: 86 58596 86 Width: 300 Flags: MW LayerCount: 2 Fore SplineSet 0 125 m 1 300 125 l 1 300 0 l 1 0 0 l 1 0 125 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E5 Encoding: 87 58597 87 Width: 238 Flags: MW LayerCount: 2 Fore SplineSet 41 391 m 1 230 162 l 1 |
| ︙ | ︙ | |||
2527 2528 2529 2530 2531 2532 2533 | 122 193 l 1 41 391 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E6 | | | 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 | 122 193 l 1 41 391 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E6 Encoding: 88 58598 88 Width: 255 Flags: W HStem: 48 33<112 170.038> VStem: 0 135<81.9955 177.625> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
2551 2552 2553 2554 2555 2556 2557 | 58 -227 l 1 171 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E7 | | | 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 | 58 -227 l 1 171 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E7 Encoding: 89 58599 89 Width: 329 Flags: MW LayerCount: 2 Fore SplineSet 171 -196 m 1 151 -202 140 -208 98 -208 c 0 |
| ︙ | ︙ | |||
2580 2581 2582 2583 2584 2585 2586 | 86 -488 l 1 171 -196 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E8 | | | 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 | 86 -488 l 1 171 -196 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E8 Encoding: 90 58600 90 Width: 399 Flags: MW LayerCount: 2 Fore SplineSet 246 60 m 1 226 54 217 48 175 48 c 0 |
| ︙ | ︙ | |||
2616 2617 2618 2619 2620 2621 2622 | 158 -176 182 -160 188 -142 c 1 246 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E9 | | | 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 | 158 -176 182 -160 188 -142 c 1 246 60 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4E9 Encoding: 91 58601 91 Width: 472 Flags: MW LayerCount: 2 Fore SplineSet 171 -452 m 1 151 -458 140 -464 98 -464 c 0 |
| ︙ | ︙ | |||
2659 2660 2661 2662 2663 2664 2665 | 86 -744 l 1 171 -452 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4EA | | | 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 | 86 -744 l 1 171 -452 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE4EA Encoding: 92 58602 92 Width: 472 Flags: MW LayerCount: 2 Fore SplineSet 319 52 m 1 299 46 288 40 246 40 c 0 |
| ︙ | ︙ | |||
2708 2709 2710 2711 2712 2713 2714 | 210 -138 205 -157 187 -178 c 1 233 -178 257 -162 263 -144 c 1 319 52 l 1 EndSplineSet Validated: 1 EndChar | < < < < < < < < < < < < < < < < < < < < < < < < < < | | 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 | 210 -138 205 -157 187 -178 c 1 233 -178 257 -162 263 -144 c 1 319 52 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE500 Encoding: 93 58624 93 Width: 563 Flags: MW LayerCount: 2 Fore SplineSet 55 75 m 3 22 75 -5 102 -5 135 c 3 |
| ︙ | ︙ | |||
2761 2762 2763 2764 2765 2766 2767 | 109 -250 l 1 -16 -250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE501 | | | 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 | 109 -250 l 1 -16 -250 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE501 Encoding: 94 58625 94 Width: 800 Flags: W HStem: -195 120<659.745 752.255> 75 120<-6.25464 86.2546> VStem: -20 120<88.7454 181.255> 646 120<-181.255 -88.7454> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
2794 2795 2796 2797 2798 2799 2800 | 334 -250 l 5 212 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE520 | | | 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 | 334 -250 l 5 212 -250 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE520 Encoding: 95 58656 95 Width: 379 Flags: HMW LayerCount: 2 Fore SplineSet 197 40 m 0 199 39 201 39 204 39 c 0 |
| ︙ | ︙ | |||
2832 2833 2834 2835 2836 2837 2838 | 341 280 380 248 380 180 c 0 380 87 319 0 220 0 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE521 | | | 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 | 341 280 380 248 380 180 c 0 380 87 319 0 220 0 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniE521 Encoding: 96 58657 96 Width: 440 Flags: MW LayerCount: 2 Fore SplineSet 80 21 m 4 76 11 74 1 57 0 c 4 |
| ︙ | ︙ | |||
2880 2881 2882 2883 2884 2885 2886 | 170 213 153 206 148 193 c 4 80 21 l 4 EndSplineSet Validated: 1 EndChar StartChar: uniE522 | | | 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 | 170 213 153 206 148 193 c 4 80 21 l 4 EndSplineSet Validated: 1 EndChar StartChar: uniE522 Encoding: 97 58658 97 Width: 278 Flags: HMW LayerCount: 2 Fore SplineSet -50 -160 m 0 -90 -160 -130 -135 -130 -90 c 0 |
| ︙ | ︙ | |||
2916 2917 2918 2919 2920 2921 2922 | 233 230 229 230 196 230 c 1 153 -26 80 -160 -50 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE523 | | | 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 | 233 230 229 230 196 230 c 1 153 -26 80 -160 -50 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE523 Encoding: 98 58659 98 Width: 275 Flags: HMW LayerCount: 2 Fore SplineSet 208 231 m 0 218 237 218 245 208 245 c 0 |
| ︙ | ︙ | |||
2945 2946 2947 2948 2949 2950 2951 | 212 165 190 182 190 200 c 0 190 216 196 224 208 231 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE524 | | | 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 | 212 165 190 182 190 200 c 0 190 216 196 224 208 231 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE524 Encoding: 99 58660 99 Width: 220 Flags: HMW LayerCount: 2 Fore SplineSet 80 0 m 0 41 0 0 33 0 70 c 0 |
| ︙ | ︙ | |||
2975 2976 2977 2978 2979 2980 2981 | 186 137 200 115 200 85 c 0 200 26 156 0 80 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE525 | | | 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 | 186 137 200 115 200 85 c 0 200 26 156 0 80 0 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE525 Encoding: 100 58661 100 Width: 232 Flags: HMW LayerCount: 2 Fore SplineSet -10 3 m 0 -22 -6 -34 16 -23 26 c 0 |
| ︙ | ︙ | |||
3011 3012 3013 3014 3015 3016 3017 | 56 2 50 23 31 23 c 0 19 23 6 15 -10 3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE529 | | | 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 | 56 2 50 23 31 23 c 0 19 23 6 15 -10 3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE529 Encoding: 101 58665 101 Width: 703 Flags: HMW LayerCount: 2 Fore SplineSet 522 40 m 0 524.179123831 39.0525548563 526.555731167 38.5988184777 529.0907001 38.5988184777 c 0 |
| ︙ | ︙ | |||
3127 3128 3129 3130 3131 3132 3133 | 835.665333312 135.693575703 831.068143327 108.945807045 831.068143327 87.1471403297 c 0 831.068143327 62.5417301443 836.925393958 44.2419393862 847 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52A | | | 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 | 835.665333312 135.693575703 831.068143327 108.945807045 831.068143327 87.1471403297 c 0 831.068143327 62.5417301443 836.925393958 44.2419393862 847 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52A Encoding: 102 58666 102 Width: 563 Flags: W HStem: -120 30<-74.2249 10 108 169.668 250.775 335 433 494.668 575.775 660 758 819.668> 0 38.5988<191.014 237.319 516.014 562.319 841.014 887.319> 240 40<80.1149 147.5 239.117 318 404.386 472.5 564.117 643 729.386 797.5 889.117 973> VStem: 120.421 60.6474<87.1471 224.606> 298.898 81.1023<108.679 217.246> 445.421 60.6474<87.1471 224.606> 623.898 81.1023<108.679 217.246> 770.421 60.6474<87.1471 224.606> 948.898 81.1023<108.462 239.669> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
3219 3220 3221 3222 3223 3224 3225 | 185.665333312 135.693575703 181.068143327 108.945807045 181.068143327 87.1471403297 c 0 181.068143327 62.5417301443 186.925393958 44.2419393862 197 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52B | | | 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 | 185.665333312 135.693575703 181.068143327 108.945807045 181.068143327 87.1471403297 c 0 181.068143327 62.5417301443 186.925393958 44.2419393862 197 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52B Encoding: 103 58667 103 Width: 703 Flags: HMW LayerCount: 2 Fore SplineSet 200 0 m 0 183 0 173 6 153 32 c 1 |
| ︙ | ︙ | |||
3283 3284 3285 3286 3287 3288 3289 | 510.665333312 135.693575703 506.068143327 108.945807045 506.068143327 87.1471403297 c 0 506.068143327 62.5417301443 511.925393958 44.2419393862 522 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52C | | | 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 | 510.665333312 135.693575703 506.068143327 108.945807045 506.068143327 87.1471403297 c 0 506.068143327 62.5417301443 511.925393958 44.2419393862 522 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52C Encoding: 104 58668 104 Width: 811 Flags: HMW LayerCount: 2 Fore SplineSet 429 119 m 0 480 232 500 280 556 280 c 0 |
| ︙ | ︙ | |||
3355 3356 3357 3358 3359 3360 3361 | 616.665333312 135.693575703 612.068143327 108.945807045 612.068143327 87.1471403297 c 0 612.068143327 62.5417301443 617.925393958 44.2419393862 628 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52D | | | 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 | 616.665333312 135.693575703 612.068143327 108.945807045 612.068143327 87.1471403297 c 0 612.068143327 62.5417301443 617.925393958 44.2419393862 628 40 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52D Encoding: 105 58669 105 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 80 21 m 0 76 11 74 1 57 0 c 0 |
| ︙ | ︙ | |||
3428 3429 3430 3431 3432 3433 3434 | 676 230 672 230 639 230 c 1 596 -26 523 -160 393 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52F | | | 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 | 676 230 672 230 639 230 c 1 596 -26 523 -160 393 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE52F Encoding: 106 58671 106 Width: 617 Flags: HMW LayerCount: 2 Fore SplineSet 351 230 m 9 196 230 l 1 |
| ︙ | ︙ | |||
3482 3483 3484 3485 3486 3487 3488 | 192 -120 202 -124 217 -124 c 0 280 -124 284 -35 351 230 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE530 | | | 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 | 192 -120 202 -124 217 -124 c 0 280 -124 284 -35 351 230 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE530 Encoding: 107 58672 107 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 204 270 m 9 360 270 l 1 |
| ︙ | ︙ | |||
3554 3555 3556 3557 3558 3559 3560 | 295 400 285 404 270 404 c 0 228 404 217 332 204 270 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE531 | | | 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 | 295 400 285 404 270 404 c 0 228 404 217 332 204 270 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE531 Encoding: 108 58673 108 Width: 617 Flags: HMW LayerCount: 2 Fore SplineSet 472 271 m 9 628 270 l 1 |
| ︙ | ︙ | |||
3644 3645 3646 3647 3648 3649 3650 | 562 400 552 404 537 404 c 0 495 404 485 332 472 271 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE539 | | | 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 | 562 400 552 404 537 404 c 0 495 404 485 332 472 271 c 9 EndSplineSet Validated: 1 EndChar StartChar: uniE539 Encoding: 109 58681 109 Width: 351 Flags: HMW LayerCount: 2 Fore SplineSet 80 0 m 0xd8 41 0 0 33 0 70 c 0xe8 |
| ︙ | ︙ | |||
3722 3723 3724 3725 3726 3727 3728 | 465 230 461 230 428 230 c 1 385 -26 312 -160 182 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE566 | | | 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 | 465 230 461 230 428 230 c 1 385 -26 312 -160 182 -160 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE566 Encoding: 110 58726 110 Width: 509 Flags: HMW LayerCount: 2 Fore SplineSet 310 265 m 1 183 258 l 1 |
| ︙ | ︙ | |||
3762 3763 3764 3765 3766 3767 3768 | 230 0 l 1 242 40 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE567 | | | 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 | 230 0 l 1 242 40 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE567 Encoding: 111 58727 111 Width: 437 Flags: W HStem: -3 72<49.5596 110.739> 0 49<319.775 397.094> 141 71<327.059 386.441> 161 47<36.904 118.027> VStem: 0 24<64.6579 145.71> 413 24<63.9568 143.617> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
3799 3800 3801 3802 3803 3804 3805 | 323 68 l 1 342 55 353 49 368 49 c 0x5c EndSplineSet Validated: 1 EndChar StartChar: uniE569 | | | 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 | 323 68 l 1 342 55 353 49 368 49 c 0x5c EndSplineSet Validated: 1 EndChar StartChar: uniE569 Encoding: 112 58729 112 Width: 437 Flags: HMW LayerCount: 2 Fore SplineSet 77 -3 m 0 33 -3 0 54 0 102 c 0 |
| ︙ | ︙ | |||
3841 3842 3843 3844 3845 3846 3847 | 92 61 102 51 102 32 c 0 102 11 93 -1 77 -3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE56C | | | 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 | 92 61 102 51 102 32 c 0 102 11 93 -1 77 -3 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE56C Encoding: 113 58732 113 Width: 580 Flags: W HStem: 0 224 LayerCount: 2 Fore SplineSet 34 46 m 13 |
| ︙ | ︙ | |||
3866 3867 3868 3869 3870 3871 3872 | 109 124 l 5 34 46 l 13 EndSplineSet Validated: 1 EndChar StartChar: uniE56D | | | 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 | 109 124 l 5 34 46 l 13 EndSplineSet Validated: 1 EndChar StartChar: uniE56D Encoding: 114 58733 114 Width: 580 Flags: W HStem: -53 326<278 305> 0 21G<197.065 232.286 418.065 453.137> VStem: 278 27<-53 70 150 273> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
3900 3901 3902 3903 3904 3905 3906 | 278 -53 l 25 278 70 l 1xa0 EndSplineSet Validated: 1 EndChar StartChar: uniE582 | | | 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 | 278 -53 l 25 278 70 l 1xa0 EndSplineSet Validated: 1 EndChar StartChar: uniE582 Encoding: 115 58754 115 Width: 280 Flags: HMW LayerCount: 2 Fore SplineSet 123 0 m 25 123 123 l 25 |
| ︙ | ︙ | |||
3924 3925 3926 3927 3928 3929 3930 | 157 0 l 25 123 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE5D0 | | | | 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | 157 0 l 25 123 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE5D0 Encoding: 116 58832 116 Width: 310 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 1 0 60 l 1 93 79 229 114 280 370 c 1 310 370 l 1 310 175 152 13 0 0 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE5E2 Encoding: 117 58850 117 Width: 300 Flags: W HStem: 0 62<198.921 262.211> 96 64<38.8054 112.592> VStem: 283 16<88.1179 101.401> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
3964 3965 3966 3967 3968 3969 3970 | 55 96 32 79 17 61 c 0 10 53 -2 61 1 70 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE610 | | | | | | | 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 | 55 96 32 79 17 61 c 0 10 53 -2 61 1 70 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE610 Encoding: 118 58896 118 Width: 300 Flags: HMW LayerCount: 2 Fore SplineSet 0 0 m 25 0 300 l 25 300 300 l 25 300 0 l 25 265 0 l 25 265 180 l 25 35 180 l 29 35 0 l 29 0 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE612 Encoding: 119 58898 119 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 105 0 m 29 0 450 l 25 40 450 l 25 125 90 l 25 210 450 l 25 250 450 l 25 145 0 l 25 105 0 l 29 EndSplineSet Validated: 1 EndChar StartChar: uniE614 Encoding: 120 58900 120 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 100 25 m 28 141 25 175 59 175 100 c 28 175 141 141 175 100 175 c 28 59 175 25 141 25 100 c 28 25 59 59 25 100 25 c 28 100 0 m 28 45 0 0 45 0 100 c 28 0 155 45 200 100 200 c 28 155 200 200 155 200 100 c 28 200 45 155 0 100 0 c 28 EndSplineSet Validated: 1 EndChar StartChar: uniE618 Encoding: 121 58904 121 Width: 280 Flags: HMW LayerCount: 2 Fore SplineSet -200 0 m 1 -200 110 -110 200 0 200 c 24 110 200 200 110 200 0 c 1 170 0 l 1 170 99 99 170 0 170 c 24 -99 170 -170 99 -170 0 c 1 -200 0 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE624 Encoding: 122 58916 122 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 90 120 m 0 110 120 132 165 132 200 c 28 |
| ︙ | ︙ | |||
4066 4067 4068 4069 4070 4071 4072 | 108 0 l 25 72 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE630 | | | 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 | 108 0 l 25 72 0 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniE630 Encoding: 123 58928 123 Width: 200 Flags: HMW LayerCount: 2 Fore SplineSet 84 102 m 1 37 109 -0 150 0 200 c 24 |
| ︙ | ︙ | |||
4097 4098 4099 4100 4101 4102 4103 | 116 127 l 1 116 126 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE650 | | | 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 | 116 127 l 1 116 126 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniE650 Encoding: 124 58960 124 Width: 1037 Flags: W HStem: -2 60<361.035 435.033 953.253 1010.82> 0 49<543.265 652.027> 286 36<514.943 580.797> 359 66<58.4784 125.129> 402 58<367.211 444.917> 607 32<177.106 261> VStem: 0 57<406 505.924> 148 26<463.933 475.584> 200 67<410.241 442> 274.641 84.3586<205.588 329> 425 56<126.64 255.856> 452 64<466.983 558.522> 585 40<194.878 284.873> 675 60<72.5613 225.441> 887 59<79.8865 267.532> 952 60<-0.820206 56.8202> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
4176 4177 4178 4179 4180 4181 4182 | 758 262 735 202 735 117 c 0 735 73 753 50 797 40 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE655 | | | 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 | 758 262 735 202 735 117 c 0 735 73 753 50 797 40 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE655 Encoding: 125 58965 125 Width: 540 Flags: W HStem: 68 93<79.5149 155.133> 182 17<220 222.173 252.655 264.303> 192 94<18.5323 100.176 375.888 460.387> 230 56<60.9363 133.273> 230 18<300.618 361.695> 274 18<213.64 227.572 256.894 258> 315 97<73.5817 155.121 322.704 406.413> VStem: 179 23<209.875 223.47 254.181 264.625> 192 98<17.9339 97.9009 381.276 451.65> 230 18<113.95 174.519 300.936 363.797> 278 17<212.458 224.186 254.5 261> LayerCount: 2 Fore SplineSet |
| ︙ | ︙ | |||
4249 4250 4251 4252 4253 4254 4255 | 173 186 179 196 179 204 c 0 179 219 166 230 141 230 c 0xcb40 EndSplineSet Validated: 1 EndChar StartChar: uniE910 | | | 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 | 173 186 179 196 179 204 c 0 179 219 166 230 141 230 c 0xcb40 EndSplineSet Validated: 1 EndChar StartChar: uniE910 Encoding: 126 59664 126 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 45 0 m 28 45 -113 137 -205 250 -205 c 28 |
| ︙ | ︙ | |||
4275 4276 4277 4278 4279 4280 4281 | 283 60 310 33 310 0 c 7 310 -33 283 -60 250 -60 c 7 EndSplineSet Validated: 1 EndChar StartChar: uniE911 | | | | 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 | 283 60 310 33 310 0 c 7 310 -33 283 -60 250 -60 c 7 EndSplineSet Validated: 1 EndChar StartChar: uniE911 Encoding: 127 59665 127 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 45 0 m 24 45 -113 137 -205 250 -205 c 24 363 -205 455 -113 455 0 c 24 455 113 363 205 250 205 c 24 137 205 45 113 45 0 c 24 0 0 m 24 0 139 111 250 250 250 c 24 388 250 500 139 500 0 c 24 500 -138 389 -250 250 -250 c 24 112 -250 0 -138 0 0 c 24 EndSplineSet Validated: 1 EndChar StartChar: uniE912 Encoding: 128 59666 128 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 228 350 m 5 273 350 l 5 |
| ︙ | ︙ | |||
4326 4327 4328 4329 4330 4331 4332 | 455 105 375 193 273 204 c 5 273 -204 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE914 | | | 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 | 455 105 375 193 273 204 c 5 273 -204 l 5 EndSplineSet Validated: 1 EndChar StartChar: uniE914 Encoding: 129 59668 129 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 463 130 m 0 464 127 465 123 465 120 c 0 |
| ︙ | ︙ | |||
4359 4360 4361 4362 4363 4364 4365 | 283 60 310 33 310 0 c 3 310 -33 283 -60 250 -60 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE915 | | | 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 | 283 60 310 33 310 0 c 3 310 -33 283 -60 250 -60 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE915 Encoding: 130 59669 130 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 463 130 m 0 464 127 465 123 465 120 c 0 |
| ︙ | ︙ | |||
4387 4388 4389 4390 4391 4392 4393 | 0 139 111 250 250 250 c 0 344 250 420 210 463 130 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE918 | | | 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 | 0 139 111 250 250 250 c 0 344 250 420 210 463 130 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniE918 Encoding: 131 59672 131 Width: 500 Flags: HMW LayerCount: 2 Fore SplineSet 273 249 m 1 356 243 424 203 463 130 c 0 |
| ︙ | ︙ | |||
4424 4425 4426 4427 4428 4429 4430 | 125 193 45 106 45 0 c 0 45 -106 125 -193 228 -204 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE920 | | | | | 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 | 125 193 45 106 45 0 c 0 45 -106 125 -193 228 -204 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniE920 Encoding: 132 59680 132 Width: 120 Flags: HMW LayerCount: 2 Fore SplineSet 60 -60 m 3 27 -60 0 -33 0 0 c 3 0 33 27 60 60 60 c 3 93 60 120 33 120 0 c 3 120 -33 93 -60 60 -60 c 3 EndSplineSet Validated: 1 EndChar StartChar: uniE925 Encoding: 133 59685 133 Width: 45 Flags: HMW LayerCount: 2 Fore SplineSet 45 350 m 9 45 -350 l 1 0 -350 l 9 0 350 l 1 45 350 l 9 EndSplineSet Validated: 1 EndChar StartChar: uniE95D Encoding: 134 59741 134 Width: 540 Flags: HMW LayerCount: 2 Fore SplineSet 30 70 m 25 30 -70 l 25 |
| ︙ | ︙ | |||
4485 4486 4487 4488 4489 4490 4491 | 0 -190 l 25 0 190 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEA02 | | | 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 | 0 -190 l 25 0 190 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEA02 Encoding: 135 59906 135 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 0 65 m 25 137 250 l 25 |
| ︙ | ︙ | |||
4509 4510 4511 4512 4513 4514 4515 | 32 41 l 25 0 65 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEAA4 | | | 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 | 32 41 l 25 0 65 l 25 EndSplineSet Validated: 1 EndChar StartChar: uniEAA4 Encoding: 136 60068 136 Width: 250 Flags: HMW LayerCount: 2 Fore SplineSet 0 270 m 0 30 300 45 311 85 311 c 0 |
| ︙ | ︙ | |||
4533 4534 4535 4536 4537 4538 4539 | -17 226 -24 227 -24 234 c 0 -24 241 -17 253 0 270 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniECA2 | | | | 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 | -17 226 -24 227 -24 234 c 0 -24 241 -17 253 0 270 c 0 EndSplineSet Validated: 1 EndChar StartChar: uniECA2 Encoding: 137 60578 137 Width: 450 Flags: HMW LayerCount: 2 Fore SplineSet 337 -20 m 4 337 50 264 111 193 111 c 4 154 111 109 85 109 41 c 4 109 -30 186 -87 257 -87 c 4 298 -87 337 -65 337 -20 c 4 450 10 m 4 450 -60 361 -119 225 -119 c 4 89 -119 0 -60 0 10 c 4 0 80 89 139 225 139 c 4 361 139 450 80 450 10 c 4 EndSplineSet Validated: 1 EndChar StartChar: uniECA3 Encoding: 138 60579 138 Width: 328 Flags: HMW LayerCount: 2 Fore SplineSet 292 68 m 0 283 84 264 91 242 91 c 0 |
| ︙ | ︙ | |||
4581 4582 4583 4584 4585 4586 4587 | 237 148 273 134 298 103 c 1 299 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniECA5 | | | | 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 | 237 148 273 134 298 103 c 1 299 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniECA5 Encoding: 139 60581 139 Width: 320 Flags: HMW LayerCount: 2 Fore SplineSet 290 680 m 1 320 680 l 1 320 40 l 2 320 -51 231 -135 110 -135 c 0 40 -135 0 -90 0 -40 c 0 0 50 90 135 210 135 c 0 244 135 271 124 290 107 c 1 290 680 l 1 EndSplineSet Validated: 1 EndChar StartChar: uniECA7 Encoding: 140 60583 140 Width: 522 Flags: HMW LayerCount: 2 Fore SplineSet 320 441 m 1 320 40 l 2 |
| ︙ | ︙ | |||
4624 4625 4626 4627 4628 4629 4630 | 485 57 490 104 490 148 c 0 490 258 462 396 320 441 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniECA9 | | | 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 | 485 57 490 104 490 148 c 0 490 258 462 396 320 441 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniECA9 Encoding: 141 60585 141 Width: 522 Flags: HMW LayerCount: 2 Fore SplineSet 290 107 m 1 290 337 l 1 |
| ︙ | ︙ | |||
4654 4655 4656 4657 4658 4659 4660 | 494 242 495 248 495 255 c 0 495 388 391 509 320 509 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniECB7 | | | 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 | 494 242 495 248 495 255 c 0 495 388 391 509 320 509 c 1 EndSplineSet Validated: 1 EndChar StartChar: uniECB7 Encoding: 142 60599 142 Width: 100 Flags: HMW LayerCount: 2 Fore SplineSet 50 -50 m 3 22 -50 0 -28 0 0 c 3 |
| ︙ | ︙ |
Changes to modules/MIDI.js.
1 2 | // MIDI.js - module to handle the %%MIDI parameters // | | > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 |
// MIDI.js - module to handle the %%MIDI parameters
//
// Copyright (C) 2019-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%MIDI" appears in a ABC source.
//
// Parameters (see abcMIDI for details)
// %%MIDI channel n
// %%MIDI program [channel] n
// %%MIDI control k v
// %%MIDI drummap ABC_note MIDI_pitch
// %%MIDI temperamentequal nedo
// %%MIDI chordname <chord_type> <list of MIDI pitches>
// %%MIDI chordprog <#MIDI program> [octave=<n>]
// %%MIDI chordvol <volume>
// %%MIDI gchordon
// %%MIDI gchordoff
// Using %%MIDI drummap creates a voicemap named "MIDIdrum".
// This name must be used if some print map is required:
// %%MIDI drummap g 42
// %%map MIDIdrum g heads=x
// A same effect may be done by
// %%percmap g 42 x
// but this is not abcMIDI compatible!
abc2svg.MIDI = {
// parse %%MIDI commands
do_midi: function(parm) {
// build the equal temperament as a b40 float array
function tb40(qs) {
// b40 C D E F G A B
// [ 2, 8, 14, 19, 25, 31, 37 ]
var i,
// C G D A E B ^F ^C ^G ^D ^A ^E ^B^^F^^C^^G^^D^^A^^E^^B
n1 = [2,25, 8,31,14,37,20, 3,26, 9,32,15,38,21, 4,27,10,33,16,39],
|
| ︙ | ︙ | |||
162 163 164 165 166 167 168 |
// // M:6/8 fzcfzc
// // M:9/8 fzcfzcfzc
// break
case "gchordon": // %%MIDI gchordon
case "gchordoff": // %%MIDI gchordoff
if (!cfmt.chord)
cfmt.chord = {}
| < < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
// // M:6/8 fzcfzc
// // M:9/8 fzcfzcfzc
// break
case "gchordon": // %%MIDI gchordon
case "gchordoff": // %%MIDI gchordoff
if (!cfmt.chord)
cfmt.chord = {}
if (abc.parse.state >= 2
&& abc.get_curvoice()) {
s = abc.new_block("midigch")
s.play = true
s.on = a[1][7] == 'n'
} else {
cfmt.chord.gchon = a[1][7] == 'n'
|
| ︙ | ︙ | |||
196 197 198 199 200 201 202 | // channel 10 is bank 128 abc2svg.MIDI.do_midi.call(abc, "MIDI control 0 1") // MSB bank abc2svg.MIDI.do_midi.call(abc, "MIDI control 32 0") // LSB bank break case "drummap": //fixme: should have a 'MIDIdrum' per voice? | < | | | > | > | | > > | | 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 |
// channel 10 is bank 128
abc2svg.MIDI.do_midi.call(abc, "MIDI control 0 1") // MSB bank
abc2svg.MIDI.do_midi.call(abc, "MIDI control 32 0") // LSB bank
break
case "drummap":
//fixme: should have a 'MIDIdrum' per voice?
v = Number(a[3])
if (isNaN(v)) {
abc.syntax(1, abc.errs.bad_val, "%%MIDI drummap")
break
}
n = ["C","^C","D","_E","E","F","^F","G","^G","A","_B","B"][v % 12]
while (v < 60) {
n += ','
v += 12
}
while (v > 72) {
n += "'"
v -= 12
}
this.do_pscom("map MIDIdrum " + a[2] + " play=" + n)
abc.set_v_param("mididrum", "MIDIdrum")
break
case "program":
if (a[3] != undefined) { // with a channel
abc2svg.MIDI.do_midi.call(abc, "MIDI channel " + a[2])
v = a[3]
} else {
|
| ︙ | ︙ |
Changes to modules/ambitus.js.
1 2 | // ambitus.js - module to insert an ambitus at start of a voice // | | > > > > > > > > > > > > > > > | 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 |
// ambitus.js - module to insert an ambitus at start of a voice
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%ambitus" appears in a ABC source.
//
// Parameters
// %%ambitus 1
abc2svg.ambitus = {
|
| ︙ | ︙ |
Changes to modules/break.js.
1 2 | // break.js - module to handle the %%break command // | | > > > > > > > > > > > > > > > | 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 |
// break.js - module to handle the %%break command
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%break" appears in a ABC source.
//
// Parameters
// %%break measure_nb [":" num "/" den] [" " measure ...]*
abc2svg.break = {
|
| ︙ | ︙ |
Changes to modules/capo.js.
1 2 | // capo.js - module to add a capo chord line // | | > > > > > > > > > > > > > > > | 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 |
// capo.js - module to add a capo chord line
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%capo" appears in a ABC source.
//
// Parameters
// %%capo n 'n' is the capo fret number
abc2svg.capo = {
|
| ︙ | ︙ |
Changes to modules/chordnames.js.
1 2 3 | // abc2svg - chordnames.js - change the names of the chord symbols // // Copyright (C) 2020-2021 Jean-Francois Moine | | > > > > > > > > > > > > > > > | | | > > > > > | < | < | | < < < > | > > | | | > > > > > > > > | > | > > | 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 |
// abc2svg - chordnames.js - change the names of the chord symbols
//
// Copyright (C) 2020-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded by %%chordnames.
//
// Parameters
// 1st syntax:
// %%chordnames <comma separated list of chord names>
// Each name replace one chord. The order is:
// CDEFGAB<N.C.>
// 2nd syntax:
// %%chordnames <comma separated list of key ':' value>
// The key may be a chord letter ('A') with/or an accidental
// Example:
// %%chordnames Bb:B,B:H,b:s % German chords
abc2svg.chordnames = {
gch_build: function(of, s) {
var gch, ix, t,
cfmt = this.cfmt()
if (s.a_gch && cfmt.chordnames) {
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
t = gch.text
if (gch.type != 'g' || !t)
continue
if (t[0] == 'n' || t[0] == 'N')
t = 'N'
gch.text = t.replace(cfmt.chordnames.re,
function(c){return cfmt.chordnames.o[c]})
}
}
of(s)
}, // gch_build()
gimpl: 'CDEFGABN',
set_fmt: function(of, cmd, parm) {
var i, v,
re = [],
o = {},
cfmt = this.cfmt()
if (cmd == "chordnames") {
parm = parm.split(',')
if (parm[0].indexOf(':') > 0) { // by object
for (i = 0; i < parm.length; i++) {
v = parm[i].split(':')
if (!v[1]) // (no ':')
continue
o[v[0]] = v[1]
re.push(v[0])
}
} else { // implicit
for (i = 0; i < parm.length; i++) {
v = abc2svg.chordnames.gimpl[i]
o[v] = parm[i]
re.push(v)
}
}
cfmt.chordnames = {re: new RegExp(re.join('|'), 'g'), o: o}
return
}
of(cmd, parm)
}, // set_fmt()
set_hooks: function(abc) {
abc.gch_build = abc2svg.chordnames.gch_build.bind(abc, abc.gch_build)
|
| ︙ | ︙ |
Changes to modules/clair.js.
1 2 | // clair.js - module to output Clairnote sheets (https:clairnote.org) // | | > > > > > > > > > > > > > > > | 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 |
// clair.js - module to output Clairnote sheets (https:clairnote.org)
//
// Copyright (C) 2019-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%clairnote" appears in a ABC source.
//
// Parameters (none)
// %%clairnote 1
abc2svg.clair = {
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
}
of()
},
// set a format parameter
set_fmt: function(of, cmd, param) {
if (cmd == "clairnote") {
this.set_v_param("clair", true);
this.set_v_param("stafflines", "|-|---|-|")
this.set_v_param("staffscale", .8)
return
}
of(cmd, param)
},
| > > | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
}
of()
},
// set a format parameter
set_fmt: function(of, cmd, param) {
if (cmd == "clairnote") {
if (!this.get_bool(param))
return
this.set_v_param("clair", true);
this.set_v_param("stafflines", "|-|---|-|")
this.set_v_param("staffscale", .8)
return
}
of(cmd, param)
},
|
| ︙ | ︙ |
Changes to modules/clip.js.
1 2 | // clip.js - module to handle the %%clip command // | | > > > > > > > > > > > > > > > | 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 |
// clip.js - module to handle the %%clip command
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%clip" appears in a ABC source.
//
// Parameters
// %%clip start_measure_nb [":" num "/" den] "-" end_measure_nb [":" num "/" den]
abc2svg.clip = {
|
| ︙ | ︙ |
Changes to modules/combine.js.
1 2 | // combine.js - module to add a combine chord line // | | > > > > > > > > > > > > > > > | < | | > | 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 |
// combine.js - module to add a combine chord line
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%voicecombine" appears in a ABC source.
//
// Parameters
// %%voicecombine n 'n' is the combine level
abc2svg.combine = {
// function called at start of the generation when multi-voices
comb_v: function() {
var C = abc2svg.C,
sy
// check if voice combine may occur
function may_combine(s) {
var nhd2,
s2 = s.ts_next
if (!s2 || (s2.type != C.NOTE && s2.type != C.REST))
return false
if (s2.st != s.st
|| s2.time != s.time
|| s2.dur != s.dur
|| sy.voices[s2.v].range != sy.voices[s.v].range + 1) // next voice only
return false
if (s.combine <= 0
&& s2.type != s.type)
return false
// if (s2.a_dd) { //fixme: should check the double decorations
// return false
// }
|
| ︙ | ︙ | |||
82 83 84 85 86 87 88 |
s.notes[nhd].tie_ty = C.SL_ABOVE | (type & C.SL_DOTTED)
} // combine_notes()
// combine 2 voices
function do_combine(s) {
var s2, nhd, nhd2, type
| > | > > > > > > < | > | > < < < < < < < < < < < < < < < < < < < < < > > > < < < < < | 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 |
s.notes[nhd].tie_ty = C.SL_ABOVE | (type & C.SL_DOTTED)
} // combine_notes()
// combine 2 voices
function do_combine(s) {
var s2, nhd, nhd2, type
s2 = s.ts_next
// there may be more voices
if (!s.in_tuplet
&& s2.combine != undefined && s2.combine >= 0
&& may_combine.call(this, s2))
do_combine.call(this, s2)
nhd = s.nhd;
nhd2 = s2.nhd
if (s.type != s2.type) { // if note and rest
if (s2.type != C.REST) {
s2 = s;
s = s2.ts_next
}
} else if (s.type == C.REST) {
if (s.invis
&& !s2.invis)
delete s.invis
} else {
combine_notes.call(this, s, s2)
if (s2.ti1)
s.ti1 = true
if (s2.ti2)
s.ti2 = true
}
if (s2.sls) {
if (s.sls)
Array.prototype.push.apply(s.sls, s2.sls)
else
s.sls = s2.sls
}
if (s2.sl1)
s.sl1 = true
if (s2.a_gch)
s.a_gch = s2.a_gch
if (s2.a_dd) {
if (!s.a_dd)
s.a_dd = s2.a_dd
else
Array.prototype.push.apply(s.a_dd, s2.a_dd)
}
this.unlksym(s2) // remove the next symbol
} // do_combine()
// code of comb_v()
var s, s2, g, i, r
for (s = this.get_tsfirst(); s; s = s.ts_next) {
switch (s.type) {
case C.REST:
if (s.combine == undefined || s.combine < 0)
continue
if (may_combine.call(this, s))
do_combine.call(this, s)
continue
case C.STAVES:
sy = s.sy
// fall thru
default:
continue
case C.NOTE:
if (s.combine == undefined || s.combine <= 0)
continue
break
}
if (!s.beam_st)
continue
s2 = s
while (1) {
if (!may_combine.call(this, s2)) {
s2 = null
break
}
|
| ︙ | ︙ | |||
195 196 197 198 199 200 201 |
if (s2.beam_end)
break
do {
s2 = s2.next
} while (s2.type != C.NOTE && s2.type != C.REST)
}
}
| < < < < < < | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
if (s2.beam_end)
break
do {
s2 = s2.next
} while (s2.type != C.NOTE && s2.type != C.REST)
}
}
}, // comb_v()
do_pscom: function(of, text) {
if (text.slice(0, 13) == "voicecombine ")
this.set_v_param("combine", text.split(/[ \t]/)[1])
else
of(text)
|
| ︙ | ︙ |
Changes to modules/diag.js.
1 2 | // diag.js - module to insert guitar chord diagrams // | | > > > > > > > > > > > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | | < < < < < | | < < < < | | < | < < | | | > > > > > > | > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > | | > | > > > > | | > > > > > > > > > > > > > > > > > > > > | 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 |
// diag.js - module to insert guitar chord diagrams
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%diagram" or "%%setdiag" appear in a ABC source.
//
// The command %%diagram draws a chord diagram above the chord symbols.
//
// Parameters
// %%diagram [ <#diagram> | 0 ]
// with
// <#diagram> identifier of the diagram type (number)
// ('1' is for the 6 strings guitar)
//
// The command %%setdiag defines the chord diagram of a chord symbol
// for the current diagram type.
//
// Parameters
// %%setdiag <chord> <dots> <label[,pos]> <fingers> [barre=<num>-<num>]
// with
// <chord> = chord symbol
// <dots> = list of diagram offset of dots on the strings - '0 or 'x': no dot
// <label> = text to write on the left of the <pos>th fret
// (<pos> default = 1, fret #0 is no text)
// <fingers> = finger numbers ou 'x' (mute) or '0'/'y' (no finger)
// barre=<num>-<num> draw a bar between the two string numbers in the first fret
// (numbering order 654321 for E,A,D,GBe)
abc2svg.diag = {
cd4: {},
// common diagrams by Guido Gonzato from http://www.guitar-chord.org/ (2021-08-27)
cd6: {
C: "x32010 ,0 x32010",
Cm: "x03320 fr3 x03420 barre=5-1",
C7: "x32310 ,0 x32410",
Cm7: "003020 fr3 x03020 barre=5-1",
CM7: "032000 ,0 x21000",
Csus4: "x03340 fr3 x02340 barre=5-1",
D: "000232 ,0 x00132",
Dm: "000231 ,0 x00231",
D7: "000212 ,0 x00312",
Dm7: "000211 ,0 xx0211",
DM7: "000222 ,0 xx0111",
Dsus4: "000233 ,0 xx0134",
E: "022100 ,0 023100",
Em: "022000 ,0 023000",
E7: "020100 ,0 020100",
Em7: "022030 ,0 023040",
EM7: "021100 ,0 031200",
Esus4: "022200 ,0 023400",
F: "033200 fr1 034200 barre=6-1",
Fm: "033000 fr1 034000 barre=6-1",
F7: "030200 fr1 030200 barre=6-1",
Fm7: "030000 fr1 030000 barre=6-1",
FM7: "xx3210 ,0 xx3210",
Fsus4: "033300 fr1 023400 barre=6-1",
G: "320003 ,0 230004",
Gm: "033000 fr3 034000 barre=6-1",
G7: "320001 ,0 320001",
Gm7: "030000 fr3 030000 barre=6-1",
GM7: "320002 ,0 310002",
Gsus4: "033300 fr3 023400 barre=6-1",
A: "002220 ,0 002340",
Am: "002210 ,0 002310",
A7: "002020 ,0 002030",
Am7: "002010 ,0 002010",
AM7: "002120 ,0 x02130",
Asus4: "x02230 ,0 x02340",
B: "x03330 fr2 002340 barre=5-1",
Bm: "x03320 fr2 003410 barre=5-1",
B7: "021202 ,0 x21304",
Bm7: "003020 fr2 x03020 barre=5-1",
BM7: "003230 fr2 x03240 barre=5-1",
Bsus4: "x03340 fr2 x02340 barre=5-1",
}, // cd6{}
// function called before tune generation
// n = number of strings
do_diag: function(n) {
var glyphs = this.get_glyphs(),
voice_tb = this.get_voice_tb(),
decos = this.get_decos()
// create the base decorations if not done yet
if (!glyphs.ddot) {
this.add_style("\
\n.fng {font:6px sans-serif}\
\n.frn {font:italic 7px sans-serif}")
glyphs.ddot = '<circle id="ddot" class="fill" r="1.5"/>'
}
if (!glyphs["fb" + n]) {
if (n == 4) {
glyphs.fb4 = '<g id="fb4">\n\
<path class="stroke" stroke-width="0.4" d="\
M-6 -34h12m0 6h-12\
m0 6h12m0 6h-12\
m0 6h12"/>\n\
<path class="stroke" stroke-width="0.5" d="\
M-6 -34v24m4 0v-24\
m4 0v24m4 0v-24"/>\n\
</g>'
glyphs.nut4 =
'<path id="nut4" class="stroke" stroke-width="1.6" d="\
M-6.2 -34.5h12.4"/>'
} else {
glyphs.fb6 = '<g id="fb6">\n\
<path class="stroke" stroke-width="0.4" d="\
M-10 -34h20m0 6h-20\
m0 6h20m0 6h-20\
m0 6h20"/>\n\
<path class="stroke" stroke-width="0.5" d="\
M-10 -34v24m4 0v-24\
m4 0v24m4 0v-24\
m4 0v24m4 0v-24"/>\n\
</g>'
glyphs.nut6 =
'<path id="nut6" class="stroke" stroke-width="1.6" d="\
M-10.2 -34.5h20.4"/>'
}
}
// convert the chord symbol to a "better known" one
function ch_cnv(t) {
var a = t.match(/[A-G][#♯b♭]?([^/]*)\/?/) // a[1] = chord type
if (a && a[1]) {
a[2] = abc2svg.ch_alias[a[1]]
if (a[2] != undefined)
t = t.replace(a[1], a[2])
}
return t.replace('/', '.')
} // ch_cnv()
// add a decoration and display the diagram
function diag_add(nm) { // chord name
var dc, i, l, x,
d = abc2svg.diag["cd" + n][nm] // definition of the diagram
if (!d)
return // no diagram of this chord
nm = n + nm
d = d.split(' ')
x = 2 - 2 * n
dc = '<g id="' + nm + '">\n\
<use xlink:href="#fb' + n + '"/>\n'
l = d[1].split(',') // label,position
if (!l[0] || l[0].slice(-1) == l[1])
dc += '<use xlink:href="#nut' + n + '"/>\n'
if (l[0])
dc += '<text x="' + (x - 10).toString()
+ '" y="' + ((l[1] || 1) * 6 - 35)
+ '" class="frn">' + l[0] + '</text>\n'
decos[nm] = "3 " + nm + " 40 " + (l[0] ? "30" : "10") + " 0"
// fingers
dc += '<text x="' + (n == 6 ? '-12,-8,-4,0,4,8'
: '-8,-4,0,4')
+ '" y="-36" class="fng">'
+ d[2].replace(/[y0]/g, ' ')
+ '</text>\n'
// dots
for (i = 0; i < n; i++) {
l = d[0][i]
if (l && l != 'x' && l != '0')
dc += '<use x="' + (i * 4 + x)
+ '" y="' + (l * 6 - 37)
+ '" xlink:href="#ddot"/>\n'
}
// barre
if (d[3]) {
l = d[3].match(/barre=(\d)-(\d)/)
if (l)
dc += '<path id="barre" class="stroke"\
stroke-width="1.4" d="M' + ((n - l[1]) * 4 + x - 2)
+ ' -31h' + ((l[1] - l[2]) * 4 + 4) + '"/>'
}
dc += '</g>'
glyphs[nm] = dc
} // diag_add()
var s, i, gch, nm
for (s = voice_tb[0].sym; s; s = s.next) {
if (!s.a_gch)
continue
for (i = 0; i < s.a_gch.length; i++) {
gch = s.a_gch[i]
if (!gch || gch.type != 'g' || gch.capo)
continue
nm = ch_cnv(gch.text)
if (!decos[n + nm]) // if no decoration yet
diag_add(nm)
this.deco_put(n + nm, s) // insert diag as decoration
}
}
}, // do_diag()
output_music: function(of) {
var n = this.cfmt().diag
if (n)
abc2svg.diag.do_diag.call(this, n)
of()
},
set_fmt: function(of, cmd, param) {
var a, d, n,
cfmt = this.cfmt()
switch (cmd) {
case "diagram":
n = param
if (n == '0')
n = ''
else if (n != '4')
n = '6'
cfmt.diag = n
return
case "setdiag":
n = cfmt.diag
if (!n)
n = "6" // default = 6 strings guitar
a = param.match(/(\S*)\s+(.*)/)
if (a && a.length == 3) {
d = a[2].split(' ')
if (d && d.length >= 3) {
abc2svg.diag["cd" + n][a[1].replace('/', '.')]
= a[2]
return
}
}
this.syntax(1, this.errs.bad_val, "%%setdiag")
return
}
of(cmd, param)
},
set_hooks: function(abc) {
abc.output_music = abc2svg.diag.output_music.bind(abc, abc.output_music);
|
| ︙ | ︙ |
Changes to modules/equalbars.js.
1 2 | // equalbars.js - module to set equal spaced measure bars // | | > > > > > > > > > > > > > > > | 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 |
// equalbars.js - module to set equal spaced measure bars
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%equalbars" appears in a ABC source.
//
// Parameters
// %%equalbars bool
abc2svg.equalbars = {
|
| ︙ | ︙ |
Changes to modules/gamelan.js.
1 2 | // gamelan.js - module to output Gamelan (indonesian) music sheets // | | > > > > > > > > > > > > > > > | 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 | // gamelan.js - module to output Gamelan (indonesian) music sheets // // Copyright (C) 2020-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%gamelan" appears in a ABC source. // // Parameters (none) // %%gamelan 1 // scale: // - sléndro - 5 equal tones |
| ︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
s.beam_on = true
while (--n >= 0) {
s2 = {
type: C.REST,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: d,
dur_orig: d_orig,
stem: 1,
multi: 0,
nhd: 0,
notes: [{
pit: s.notes[0].pit,
| > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
s.beam_on = true
while (--n >= 0) {
s2 = {
type: C.REST,
v: s.v,
p_v: s.p_v,
st: s.st,
fmt: s.fmt,
dur: d,
dur_orig: d_orig,
stem: 1,
multi: 0,
nhd: 0,
notes: [{
pit: s.notes[0].pit,
|
| ︙ | ︙ | |||
146 147 148 149 150 151 152 |
}
s.notes[0].jn = 8
s.notes[0].jo = 2
} // do_tie()
function set_sym(p_v) {
var s, s2, note, pit, nn, p, a, m, i,
| | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
}
s.notes[0].jn = 8
s.notes[0].jo = 2
} // do_tie()
function set_sym(p_v) {
var s, s2, note, pit, nn, p, a, m, i,
sf = p_v.key.k_sf,
delta = abc2svg.gamelan.cgd2cde[sf + 7] - 2
p_v.key.k_a_acc = [] // no accidental
// no (visible) clef
p_v.clef.invis = true
|
| ︙ | ︙ | |||
224 225 226 227 228 229 230 |
// change the dots and the long notes
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
| | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
// change the dots and the long notes
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
abc.deco_put("gstc", s)
s.a_dd[i] = s.a_dd.pop()
}
}
}
}
} // set_sym()
|
| ︙ | ︙ | |||
367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
}, // draw_symbols()
// set some parameters
set_fmt: function(of, cmd, param) {
if (cmd == "gamelan") {
var cfmt = this.cfmt()
cfmt.gamelan = true
cfmt.staffsep = 20
cfmt.sysstaffsep = 14
this.set_v_param("stafflines", "...")
cfmt.tuplets = [0, 1, 0, 1] // [auto, slur, number, above]
return
}
| > > | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
}, // draw_symbols()
// set some parameters
set_fmt: function(of, cmd, param) {
if (cmd == "gamelan") {
var cfmt = this.cfmt()
if (!this.get_bool(param))
return
cfmt.gamelan = true
cfmt.staffsep = 20
cfmt.sysstaffsep = 14
this.set_v_param("stafflines", "...")
cfmt.tuplets = [0, 1, 0, 1] // [auto, slur, number, above]
return
}
|
| ︙ | ︙ | |||
397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
case C.NOTE:
s.ymx = 20 * s.nhd + (s.nflags > 0 ? 30 : 24)
if (s.notes[s.nhd].jo > 2) {
s.ymx += 3
if (s.notes[s.nhd].jo > 3)
s.ymx += 2
}
break
}
}
}, // set_pitch()
// set the width of some symbols
set_width: function(of, s) {
| > | 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
case C.NOTE:
s.ymx = 20 * s.nhd + (s.nflags > 0 ? 30 : 24)
if (s.notes[s.nhd].jo > 2) {
s.ymx += 3
if (s.notes[s.nhd].jo > 3)
s.ymx += 2
}
s.ys = s.ymx // (for tuplets)
break
}
}
}, // set_pitch()
// set the width of some symbols
set_width: function(of, s) {
|
| ︙ | ︙ |
Changes to modules/grid.js.
|
| | | > > > > > > > > > > > > > > > | > | | > > > > | 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 |
// abc2svg - grid.js - module to insert a chord grid before or after a tune
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%grid" appears in a ABC source.
//
// Parameters
// %%grid <n> [include=<list>] [nomusic] [norepeat] [repbrk] [parts]
// <n> = number of columns (1: auto)
// > 0: above the tune, < 0: under the tune
// <list> = comma separated list of (continuous) measure numbers
// 'nomusic' displays only the grid
// 'norepeat' omits the ':' indications
// 'repbrk' starts a new grid line on start/stop repeat
// 'parts' displays the parts on the left side of the grid
// %%gridfont font_name size (default: 'serif 16')
abc2svg.grid = {
pl: '<path class="stroke" stroke-width="1" d="M',
// generate the grid
block_gen: function(of, s) {
if (s.subtype != "grid") {
of(s)
return
}
var abc = this,
img, cls,
cfmt = abc.cfmt(),
grid = cfmt.grid
// generate the grid
function build_grid(s, font) {
var i, k, l, nr, bar, w, hr, x0, x, y, yl, ps,
lc = '',
chords = s.chords,
bars = s.bars,
parts = s.parts || [],
wmx = s.wmx,
cells = [],
nc = grid.n
// set some chord(s) in each cell
function set_chords() {
var i, ch,
pch = '-'
|
| ︙ | ︙ | |||
114 115 116 117 118 119 120 |
set_chords()
// build the content of the cells
if (!grid.ls) {
cells = chords
} else { // with list of mesure numbers
bar = bars;
| | > > > > | 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 |
set_chords()
// build the content of the cells
if (!grid.ls) {
cells = chords
} else { // with list of mesure numbers
bar = bars;
bars = [ ]
ps = parts
parts = []
for (i = 0; i < grid.ls.length; i++) {
l = grid.ls[i]
if (l.indexOf('-') < 0)
l = [l, l]
else
l = l.split('-')
for (k = l[0] - 1; k < l[1]; k++) {
if (!chords[k]) // error
break
cells.push(chords[k]);
bars.push(bar[k])
parts.push(ps[k])
}
}
bars.push(bar[k]) // ending bar
}
// get the number of columns
if (nc < 0)
nc = -nc
if (nc < 3) // auto
nc = cells.length % 6 == 0 ? 6 : 8
|
| ︙ | ︙ | |||
158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
y = -1 + font.size * .6
nr = 0
x0 = (x0 / cfmt.scale - w) / 2
for (i = 0; i < cells.length; i++) {
if (i == 0
|| (grid.repbrk
&& (bars[i].slice(-1) == ':' || bars[i][0] == ':'))
|| k >= nc) {
y -= hr // new row
yl -= hr
x = x0 + wmx / 2
k = 0
nr++
}
| > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
y = -1 + font.size * .6
nr = 0
x0 = (x0 / cfmt.scale - w) / 2
for (i = 0; i < cells.length; i++) {
if (i == 0
|| (grid.repbrk
&& (bars[i].slice(-1) == ':' || bars[i][0] == ':'))
|| parts[i]
|| k >= nc) {
y -= hr // new row
yl -= hr
x = x0 + wmx / 2
k = 0
nr++
}
|
| ︙ | ︙ | |||
188 189 190 191 192 193 194 |
abc.out_svg('M')
abc.out_sxsy(x, ' ', -1)
abc.out_svg('v' + (hr * nr).toFixed(1) + '\n')
x += wmx
}
abc.out_svg('"/>\n')
| | | > > > > > > > > | 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 |
abc.out_svg('M')
abc.out_sxsy(x, ' ', -1)
abc.out_svg('v' + (hr * nr).toFixed(1) + '\n')
x += wmx
}
abc.out_svg('"/>\n')
// show the repeat signs and the parts
y = -1 + font.size * .7
x = x0
for (i = 0; i < bars.length; i++) {
bar = bars[i]
if (bar[0] == ':') {
abc.out_svg('<text class="' + cls + '" x="')
abc.out_sxsy(x - 5, '" y="', y)
abc.out_svg('" style="font-weight:bold;font-size:' +
(font.size * 1.5).toFixed(1) + 'px">:</text>\n')
}
if (i == 0
|| (grid.repbrk
&& (bar.slice(-1) == ':' || bar[0] == ':'))
|| parts[i]
|| k >= nc) {
y -= hr; // new row
x = x0
k = 0
if (parts[i]) {
w = abc.strwh(parts[i])[0]
abc.out_svg('<text class="' + cls + '" x="')
abc.out_sxsy(x - 2 - w, '" y="', y)
abc.out_svg('" style="font-weight:bold">' +
parts[i] + '</text>\n')
}
}
k++
if (bar.slice(-1) == ':') {
abc.out_svg('<text class="' + cls + '" x="')
abc.out_sxsy(x + 5, '" y="', y)
abc.out_svg('" style="font-weight:bold;font-size:' +
(font.size * 1.5).toFixed(1) + 'px">:</text>\n')
|
| ︙ | ︙ | |||
247 248 249 250 251 252 253 |
if (font.style)
f2.style = font.style
f2.class = font.class
abc.add_style("\n.mid {text-anchor:middle}")
// create the grid
abc.blk_flush()
| | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
if (font.style)
f2.style = font.style
f2.class = font.class
abc.add_style("\n.mid {text-anchor:middle}")
// create the grid
abc.blk_flush()
build_grid(s, font)
abc.blk_flush()
}, // block_gen()
set_stems: function(of) {
var C = abc2svg.C,
abc = this,
tsfirst = abc.get_tsfirst(),
voice_tb = abc.get_voice_tb(),
grid = abc.cfmt().grid
function get_beat(s) {
|
| ︙ | ︙ | |||
276 277 278 279 280 281 282 283 284 285 286 287 |
} // get_beat()
// build the arrays of chords and bars
function build_chords(sb) { // block 'grid'
var s, i, w, bt, rep,
bars = [],
chords = [],
chord = [],
beat = get_beat(voice_tb[0].meter),
wm = voice_tb[0].meter.wmeasure,
cur_beat = 0,
beat_i = 0,
| > | > | > > | | > > > | | | < > | | | | < | > > > > > > > > > > > > > > > > > > > > > > > | < | | > > < < | > > | > | 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 |
} // get_beat()
// build the arrays of chords and bars
function build_chords(sb) { // block 'grid'
var s, i, w, bt, rep,
bars = [],
chords = [],
parts = [],
chord = [],
beat = get_beat(voice_tb[0].meter),
wm = voice_tb[0].meter.wmeasure,
cur_beat = 0,
beat_i = 0,
wmx = 0,
some_chord = 0
// scan the music symbols
bars.push('|')
for (s = tsfirst; s; s = s.ts_next) {
while (s.time > cur_beat) {
if (beat_i < 3) // only 2, 3 or 4 beats / measure...
beat_i++
cur_beat += beat
}
if (s.part)
parts[chords.length] = s.part.text
switch (s.type) {
case C.NOTE:
case C.REST:
if (!s.a_gch || chord[beat_i])
break
bt = abc2svg.cs_filter(s.a_gch,
abc.cfmt().altchord)
if (!bt)
break
chord[beat_i] = bt
for (i = 0; i < s.a_gch.length; i++) {
if (s.a_gch[i].type == 'g')
break
}
abc.set_font(s.a_gch[i].font)
w = abc.strwh(bt)[0]
if (w > wmx)
wmx = w
break
case C.BAR:
i = s.bar_num // check if normal measure bar
bt = s.bar_type
while (s.ts_next && s.ts_next.time == s.time) {
if (s.ts_next.dur)
break
s = s.ts_next
if (s.type == C.METER) {
beat = get_beat(s)
wm = s.wmeasure
continue
}
if (s.type != C.BAR)
continue
if (s.bar_type[0] == ':'
&& bt[0] != ':')
bt = ':' + bt
if (s.bar_type.slice(-1) == ':'
&& bt.slice(-1) != ':')
bt += ':'
if (s.bar_num)
i = s.bar_num
if (s.part)
parts[chords.length + 1] = s.part.text
}
if (grid.norep)
bt = '|'
if (s.time < wm) { // if anacrusis
if (chord.length) {
chords.push(chord)
bars.push(bt)
} else {
bars[0] = bt
}
} else {
if (!i) // if not normal measure bar
break
chords.push(chord)
bars.push(bt)
}
if (chord.length)
some_chord++
chord = []
cur_beat = s.time // synchronize in case of error
beat_i = 0
if (bt.indexOf(':') >= 0)
rep = true // some repeat
break
case C.METER:
beat = get_beat(s)
wm = s.wmeasure
break
}
}
if (chord.length) {
bars.push('')
chords.push(chord)
}
if (!some_chord)
return // no chord in this tune
wmx += abc.strwh(rep ? ' ' : ' ')[0]
sb.chords = chords
sb.bars = bars
if (grid.parts && parts.length)
sb.parts = parts
sb.wmx = wmx
} // build_chords
// -------- set_stems --------
// create a specific block
if (grid) {
var C = abc2svg.C,
tsfirst = this.get_tsfirst(),
fmt = tsfirst.fmt,
voice_tb = this.get_voice_tb(),
p_v = voice_tb[this.get_top_v()],
s = {
type: C.BLOCK,
subtype: 'grid',
dur: 0,
time: 0,
|
| ︙ | ︙ | |||
405 406 407 408 409 410 411 412 413 | s.next = p_v.sym s.ts_next = tsfirst tsfirst.ts_prev = s this.set_tsfirst(s) p_v.sym.prev = s p_v.sym = s } } of() | > | > > | | 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 |
s.next = p_v.sym
s.ts_next = tsfirst
tsfirst.ts_prev = s
this.set_tsfirst(s)
p_v.sym.prev = s
p_v.sym = s
}
s.fmt = s.prev ? s.prev.fmt : fmt
}
of()
}, // set_stems()
set_fmt: function(of, cmd, parm) {
if (cmd == "grid") {
if (!parm)
parm = "1";
parm = parm.split(/\s+/)
var grid = {n: Number(parm.shift())}
if (isNaN(grid.n)) {
if (parm.length) {
this.syntax(1, this.errs.bad_val, "%%grid")
return
}
grid.n = 1
}
while (parm.length) {
var item = parm.shift()
if (item == "norepeat")
grid.norep = true
else if (item == "nomusic")
grid.nomusic = true
else if (item == "parts")
grid.parts = true
else if (item == "repbrk")
grid.repbrk = true
else if (item.slice(0, 8) == "include=")
grid.ls = item.slice(8).split(',')
}
this.cfmt().grid = grid
return
}
of(cmd, parm)
},
set_hooks: function(abc) {
abc.block_gen = abc2svg.grid.block_gen.bind(abc, abc.block_gen)
abc.set_stems = abc2svg.grid.set_stems.bind(abc, abc.set_stems)
abc.set_format = abc2svg.grid.set_fmt.bind(abc, abc.set_format)
}
} // grid
abc2svg.modules.hooks.push(abc2svg.grid.set_hooks);
// the module is loaded
abc2svg.modules.grid.loaded = true
|
Changes to modules/grid2.js.
1 2 | // grid2.js - module to replace a voice in the music by a chord grid // | | > > > > > > > > > > > > > > > | 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 | // grid2.js - module to replace a voice in the music by a chord grid // // Copyright (C) 2018-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%grid2" appears in a ABC source. // // Parameters // %%grid2 y // This command must appear in a voice. |
| ︙ | ︙ |
Changes to modules/grid3.js.
1 2 | // grid3.js - module to insert a manual chords // | | > > > > > > > > > > > > > > > | | 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 |
// grid3.js - module to insert a manual chords
//
// Copyright (C) 2020-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%begingrid" appears in a ABC source.
//
// Parameters
// %%begingrid [ chord-define [ noprint ] ]
// list of chords, '-' or '.', measure bars ('|') and ':' for repeat
// %%endgrid
//
// %%gridfont font_name size (default: 'serif 16')
//
// When this command appears inside a tune and when 'chord-define' is present,
// the chords are used to define the chord symbols that are displayed
// above the staff system.
// When 'noprint' is also present, the grid itself is not displayed.
abc2svg.grid3 = {
// generate the grid
block_gen: function(of, s) {
if (s.subtype != "grid3") {
of(s)
return
}
var abc = this,
cfmt = abc.cfmt(),
img = abc.get_img(),
|
| ︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
}
return "\u266d"
})
if (opt.indexOf("chord-define") >= 0)
this.cfmt().csdef = txt
if (opt.indexOf("noprint") < 0) {
if (this.parse.state >= 2) {
s = this.new_block(type)
s.text = txt
} else {
abc2svg.grid3.block_gen.call(this, null, {
subtype: type,
text: txt
| > | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
}
return "\u266d"
})
if (opt.indexOf("chord-define") >= 0)
this.cfmt().csdef = txt
if (opt.indexOf("noprint") < 0) {
type += "3"
if (this.parse.state >= 2) {
s = this.new_block(type)
s.text = txt
} else {
abc2svg.grid3.block_gen.call(this, null, {
subtype: type,
text: txt
|
| ︙ | ︙ | |||
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 |
fname: ss.fname,
istart: ss.istart,
iend: ss.iend,
v: p_vc.v,
p_v: p_vc,
time: ntim,
st: 0,
dur: 0,
dur_orig: 0,
invis: true,
seqst: true,
nhd: 0,
notes: [{
pit: 18,
dur: 0
}]
}
if (ch != '.' && ch != '-') {
abc.set_a_gch(s, [{ // define the chord symbol
type: 'g',
text: ch,
otext: ch,
istart: ss.istart,
iend: ss.iend,
| > | > | 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 |
fname: ss.fname,
istart: ss.istart,
iend: ss.iend,
v: p_vc.v,
p_v: p_vc,
time: ntim,
st: 0,
fmt: ss.fmt,
dur: 0,
dur_orig: 0,
invis: true,
seqst: true,
nhd: 0,
notes: [{
pit: 18,
dur: 0
}]
}
if (ch != '.' && ch != '-') {
abc.set_a_gch(s, [{ // define the chord symbol
type: 'g',
text: ch,
otext: ch,
istart: ss.istart,
iend: ss.iend,
font: abc.get_font("gchord"),
pos: p_vc.pos.gch || C.SL_ABOVE
}])
}
// insert the rest
if (!p_vc.last_sym) {
p_vc.sym = s
} else {
|
| ︙ | ︙ | |||
416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
next: s,
ts_next: s,
prev: s.prev,
ts_prev: s.ts_prev
}
if (!s)
break
if (s.seqst) {
ss.seqst = true
delete s.seqst
}
ss.prev.next =
ss.ts_prev.ts_next =
s.prev =
| > | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
next: s,
ts_next: s,
prev: s.prev,
ts_prev: s.ts_prev
}
if (!s)
break
ss.fmt = s.fmt
if (s.seqst) {
ss.seqst = true
delete s.seqst
}
ss.prev.next =
ss.ts_prev.ts_next =
s.prev =
|
| ︙ | ︙ |
Changes to modules/jazzchord.js.
1 2 | // abc2svg - jazzchord.js - Adds jazz chord styling to chord symbols // | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | | > | | < < < < < < < < < | | < < < < < < < | | | | < | < < | | | > | > | > | > > > > > > > > > > > < < | > > | | > > > > > > > > | > > > | | > | | < | 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 |
// abc2svg - jazzchord.js - Adds jazz chord styling to chord symbols
//
// Copyright (C) 2020-2022 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// Code adapted from Chris Fargen.
// https://gist.github.com/chrisfargen/4324c6cf6fed2c8f9a6eae1680e53169
//
// This module is loaded by %%jazzchord.
//
// Parameters
// %%jazzchord [ string '=' replacement-string ]*
abc2svg.jazzchord = {
// default replacements
defrep: {
"-": "–",
"°": "o",
"º": "o",
"ᵒ": "o",
"0": "ø",
// "6/9": "⁶⁄₉",
// "maj": "Δ",
// "M": "Δ",
// "min": "–",
// "m": "–",
"^": "∆"
},
gch_build: function(of, s) {
var gch, ix, t,
fmt = s.fmt
if (!fmt.jazzchord) {
of(s)
return
}
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
t = gch.text
if (gch.type != 'g'
|| t.indexOf('$') >= 0) // if some formatting already
continue
switch (t) {
case "/": gch.text = "\ue101"; continue
case "%": gch.text = "\ue500"; continue
case "%%": gch.text = "\ue501"; continue
}
if (fmt.jzreg) { // if replacement list
t = t.replace(fmt.jzRE,
function(x) {
return fmt.jzrep[x]
})
}
if (fmt.jazzchord == 1) {
if (t[0] == '(')
t = t.slice(1, -1)
a = t.match(/([A-G])([#♯b♭]?)([^/]*)\/?(.*)/)
// a[1]=note, a[2]=acc, a[3]=quality, a[4]=bass
if (!a)
continue
t = a[1] + "$7" + (a[2] || '')
if (a[3])
t += "$8" + a[3]
if (a[4])
t += "$0/$9" + a[4]
t += "$0"
}
if (gch.text[0] == '(')
gch.text = '(' + t + ')'
else
gch.text = t
}
of(s) // build the chord symbols
}, // gch_build()
set_fmt: function(of, cmd, parm) {
var i, k, s,
cfmt = this.cfmt()
if (cmd == "jazzchord") {
cfmt.jazzchord = this.get_bool(parm)
if (!cfmt.jazzchord)
return
if (parm[0] == '2')
cfmt.jazzchord = 2 // no style
if(!cfmt.jzreg) { // if new definition
// cfmt.jzreg = "-|°|º|ᵒ|0|6/9|maj|M|min|m|\\^"
cfmt.jzreg = "-|°|º|ᵒ|0|\\^"
cfmt.jzrep = Object.create(abc2svg.jazzchord.defrep)
cfmt.jzRE = new RegExp(cfmt.jzreg, 'g')
}
if (parm && parm.indexOf('=') > 0) {
parm = parm.split(/[\s]+/)
for (cmd = 0; cmd < parm.length; cmd++) {
k = parm[cmd].split('=')
if (k.length != 2)
//fixme: error
continue
s = k[1] // replacement
k = k[0] // key
i = cfmt.jzreg.indexOf(k)
if (i >= 0) { // if old key
if (s) { // new value
cfmt.jzrep[k] = s
} else {
cfmt.jzreg = cfmt.jzreg.replace(k, '')
cfmt.jzreg = cfmt.jzreg.replace('||', '|')
delete cfmt.jzrep[k]
}
} else {
cfmt.jzreg += '|' + k
cfmt.jzrep[k] = s
}
cfmt.jzRE = new RegExp(cfmt.jzreg, 'g')
}
}
return
}
of(cmd, parm)
}, // set_fmt()
set_hooks: function(abc) {
abc.gch_build = abc2svg.jazzchord.gch_build.bind(abc, abc.gch_build)
abc.set_format = abc2svg.jazzchord.set_fmt.bind(abc, abc.set_format)
abc.add_style("\
\n.jc7{baseline-shift:10%;font-size:90%;letter-spacing:-0.05em}\
\n.jc8{baseline-shift:25%;font-size:75%;letter-spacing:-0.05em}\
\n.jc9{font-size:75%;letter-spacing:-0.05em}\
")
abc.param_set_font("setfont-7", "* * class=jc7")
abc.param_set_font("setfont-8", "* * class=jc8")
abc.param_set_font("setfont-9", "* * class=jc9")
} // set_hooks()
} // jazzchord
abc2svg.modules.hooks.push(abc2svg.jazzchord.set_hooks)
|
| ︙ | ︙ |
Changes to modules/jianpu.js.
1 2 | // jianpu.js - module to output jiănpŭ (简谱) music sheets // | | > > > > > > > > > > > > > > > > > > > > > > > | 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 |
// jianpu.js - module to output jiănpŭ (简谱) music sheets
//
// Copyright (C) 2020-2022 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%jianpu" appears in a ABC source.
//
// Parameters (none)
// %%jianpu 1
abc2svg.jianpu = {
k_tb: [ "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C",
"G", "D", "A", "E", "B", "F#", "C#" ],
cde2fcg: new Int8Array([0, 2, 4, -1, 1, 3, 5]),
cgd2cde: new Int8Array([0, -4, -1, -5, -2, -6, -3,
0, -4, -1, -5, -2, -6, -3, 0]),
acc2: new Int8Array([-2, -1, 3, 1, 2]),
acc_tb: ["\ue264", "\ue260", , "\ue262", "\ue263", "\ue261"],
// don't calculate the beams
calc_beam: function(of, bm, s1) {
if (!this.cfmt().jianpu)
return of(bm, s1)
// return 0
}, // calc_beam()
// change %%staves and %%score
do_pscom: function(of, p) {
if (this.cfmt().jianpu)
switch (p.match(/\w+/)[0]) {
case 'staves':
case 'score':
p = p.replace(/\(|\)/g, '')
break
}
of(p)
|
| ︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
// output the key and time signatures
function set_head() {
var tsfirst = abc.get_tsfirst(),
p_v = voice_tb[0],
mt = p_v.meter.a_meter[0],
sk = p_v.key,
s = {
type: C.BLOCK,
subtype: "text",
dur: 0,
v: 0,
p_v: p_v,
st: 0,
seqst: true,
text: (sk.k_mode + 1) + "=" +
(abc2svg.jianpu.k_tb[sk.k_sf + 7 +
| > > | < < > > | 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 |
// output the key and time signatures
function set_head() {
var tsfirst = abc.get_tsfirst(),
p_v = voice_tb[0],
mt = p_v.meter.a_meter[0],
sk = p_v.key,
s2 = voice_tb[0].sym,
s = {
type: C.BLOCK,
subtype: "text",
dur: 0,
v: 0,
p_v: p_v,
st: 0,
fmt: s2.fmt,
seqst: true,
text: (sk.k_mode + 1) + "=" +
(abc2svg.jianpu.k_tb[sk.k_sf + 7 +
abc2svg.jianpu.cde2fcg[sk.k_mode]]),
font: abc.get_font("text")
}
if (mt)
s.text += ' ' + (mt.bot ? (mt.top + '/' + mt.bot) : mt.top)
s2.prev = s
s.next = s2
voice_tb[0].sym = s
|
| ︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
if (s.dur >= C.BLEN)
n = 3
else if (s.dur == C.BLEN / 2)
n = 1
else
n = 2
while (--n >= 0) {
s2 = {
type: C.REST,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: C.BLEN / 4,
dur_orig: C.BLEN / 4,
stem: 0,
multi: 0,
nhd: 0,
notes: [{
pit: s.notes[0].pit,
jn: 8
}],
| > > > | 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 |
if (s.dur >= C.BLEN)
n = 3
else if (s.dur == C.BLEN / 2)
n = 1
else
n = 2
s.dur = s.dur_orig = C.BLEN / 4
delete s.fmr
while (--n >= 0) {
s2 = {
type: C.REST,
v: s.v,
p_v: s.p_v,
st: s.st,
dur: C.BLEN / 4,
dur_orig: C.BLEN / 4,
fmt: s.fmt,
stem: 0,
multi: 0,
nhd: 0,
notes: [{
pit: s.notes[0].pit,
jn: 8
}],
|
| ︙ | ︙ | |||
125 126 127 128 129 130 131 | s2.ts_prev = s3 if (s2.ts_next) s2.ts_next.ts_prev = s2 s3.ts_next = s2 break } } | < | > | > > > > | 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 |
s2.ts_prev = s3
if (s2.ts_next)
s2.ts_next.ts_prev = s2
s3.ts_next = s2
break
}
}
s = s2
}
} // slice()
function set_sym(p_v) {
var s, s2, note, pit, nn, p, a, m, i,
sf = p_v.key.k_sf,
delta = abc2svg.jianpu.cgd2cde[sf + 7] - 2
p_v.key.k_a_acc = [] // no accidental
// no (visible) clef
s = p_v.clef
s.invis = true
s.clef_type = 't'
s.clef_line = 2
// scan the voice
for (s = p_v.sym; s; s = s.next) {
s.st = p_v.st
switch (s.type) {
case C.CLEF:
s.invis = true
s.clef_type = 't'
s.clef_line = 2
// continue
default:
continue
case C.KEY:
delta = abc2svg.jianpu.cgd2cde[s.k_sf + 7] - 2
s.a_gch = [{
type: '@',
|
| ︙ | ︙ | |||
221 222 223 224 225 226 227 |
if (s.dur >= C.BLEN / 2)
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
| | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
if (s.dur >= C.BLEN / 2)
slice(s)
// replace the staccato dot
if (s.a_dd) {
for (i = 0; i < s.a_dd.length; i++) {
if (s.a_dd[i].glyph == "stc") {
abc.deco_put("gstc", s)
s.a_dd[i] = s.a_dd.pop()
}
}
}
}
} // set_sym()
|
| ︙ | ︙ | |||
287 288 289 290 291 292 293 |
}
} // draw_dur()
function out_mus(x, y, p) {
out_svg('<text x="')
out_sxsy(x, '" y="', y)
out_svg('">' + p + '</text>\n')
| | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
}
} // draw_dur()
function out_mus(x, y, p) {
out_svg('<text x="')
out_sxsy(x, '" y="', y)
out_svg('">' + p + '</text>\n')
} // out_mus()
function out_txt(x, y, p) {
out_svg('<text class="fj" x="')
out_sxsy(x, '" y="', y)
out_svg('">' + p + '</text>\n')
} // out_txt()
function draw_hd(s, x, y) {
var m, note, ym
|
| ︙ | ︙ | |||
315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
out_mus(x - 1, y + 22, dot)
}
} else if (note.jo < 2) {
ym = y + 4
if (m == 0 && s.nflags > 0)
ym -= 2.5 * s.nflags
out_mus(x - 1, ym, dot)
}
y += 20
}
} // draw_hd()
// -- draw_symbols --
| > > > > | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
out_mus(x - 1, y + 22, dot)
}
} else if (note.jo < 2) {
ym = y + 4
if (m == 0 && s.nflags > 0)
ym -= 2.5 * s.nflags
out_mus(x - 1, ym, dot)
if (note.jo < 1) {
ym -= 3
out_mus(x - 1, ym, dot)
}
}
y += 20
}
} // draw_hd()
// -- draw_symbols --
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
x = s.x
y = staff_tb[s.st].y
draw_hd(s, x, y)
if (s.nflags >= 0 && s.dots)
out_mus(x + 8, y + 13, dot)
if (s.nflags > 0) {
//fixme: ko with rests because no beam_st /_end
if (s.beam_st || s.type == C.REST) {
nl = s.nflags
s2 = s
while (1) {
if (s2.nflags && s2.nflags > nl)
nl = s2.nflags
| > > | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
x = s.x
y = staff_tb[s.st].y
draw_hd(s, x, y)
if (s.nflags >= 0 && s.dots)
out_mus(x + 8, y + 13, dot)
if (s.nflags > 0) {
if (s.time == p_voice.sym.time)
s.beam_st = 1 // beam continuation
//fixme: ko with rests because no beam_st /_end
if (s.beam_st || s.type == C.REST) {
nl = s.nflags
s2 = s
while (1) {
if (s2.nflags && s2.nflags > nl)
nl = s2.nflags
|
| ︙ | ︙ | |||
366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
}, // draw_symbols()
// set some parameters
set_fmt: function(of, cmd, param) {
if (cmd == "jianpu") {
var cfmt = this.cfmt()
cfmt.jianpu = true
cfmt.staffsep = 20
cfmt.sysstaffsep = 14
this.set_v_param("stafflines", "...")
cfmt.tuplets = [0, 1, 0, 1] // [auto, slur, number, above]
return
}
| > > | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
}, // draw_symbols()
// set some parameters
set_fmt: function(of, cmd, param) {
if (cmd == "jianpu") {
var cfmt = this.cfmt()
if (!this.get_bool(param))
return
cfmt.jianpu = true
cfmt.staffsep = 20
cfmt.sysstaffsep = 14
this.set_v_param("stafflines", "...")
cfmt.tuplets = [0, 1, 0, 1] // [auto, slur, number, above]
return
}
|
| ︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
s.wl = 14
}
break
}
}, // set_width()
set_hooks: function(abc) {
abc.do_pscom = abc2svg.jianpu.do_pscom.bind(abc, abc.do_pscom)
abc.draw_symbols = abc2svg.jianpu.draw_symbols.bind(abc, abc.draw_symbols)
abc.output_music = abc2svg.jianpu.output_music.bind(abc, abc.output_music)
abc.set_format = abc2svg.jianpu.set_fmt.bind(abc, abc.set_format)
abc.set_pitch = abc2svg.jianpu.set_pitch.bind(abc, abc.set_pitch)
abc.set_width = abc2svg.jianpu.set_width.bind(abc, abc.set_width)
// big staccato dot
abc.get_glyphs().gstc = '<circle id="gstc" cx="0" cy="-3" r="2"/>'
abc.get_decos().gstc = "0 gstc 5 1 1"
| > | | 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 |
s.wl = 14
}
break
}
}, // set_width()
set_hooks: function(abc) {
abc.calculate_beam = abc2svg.jianpu.calc_beam.bind(abc, abc.calculate_beam)
abc.do_pscom = abc2svg.jianpu.do_pscom.bind(abc, abc.do_pscom)
abc.draw_symbols = abc2svg.jianpu.draw_symbols.bind(abc, abc.draw_symbols)
abc.output_music = abc2svg.jianpu.output_music.bind(abc, abc.output_music)
abc.set_format = abc2svg.jianpu.set_fmt.bind(abc, abc.set_format)
abc.set_pitch = abc2svg.jianpu.set_pitch.bind(abc, abc.set_pitch)
abc.set_width = abc2svg.jianpu.set_width.bind(abc, abc.set_width)
// big staccato dot
abc.get_glyphs().gstc = '<circle id="gstc" cx="0" cy="-3" r="2"/>'
abc.get_decos().gstc = "0 gstc 5 1 1"
abc.add_style("\n.fj{font:15px sans-serif}")
} // set_hooks()
} // jianpu
abc2svg.modules.hooks.push(abc2svg.jianpu.set_hooks)
// the module is loaded
abc2svg.modules.jianpu.loaded = true
|
Changes to modules/mdnn.js.
1 2 3 | // mdnn.js - module to output Modernised Diatonic Numerical Notation // (https://medium.com/@info_70544/the-case-for-numerical-music-notation-part-1-introduction-and-history-5f1543ca8a95) // | | > > > > > > > > > > > > > > > | 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 | // mdnn.js - module to output Modernised Diatonic Numerical Notation // (https://medium.com/@info_70544/the-case-for-numerical-music-notation-part-1-introduction-and-history-5f1543ca8a95) // // Copyright (C) 2020-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%mdnn" appears in a ABC source. // // Parameters // (none) // //fixme:nsk |
| ︙ | ︙ | |||
183 184 185 186 187 188 189 | } note = s.notes[0] // note head p = note.pit pit = p + delta nn = ((pit + 77) % 7) + 1 // note number | < < | | < | < < < | < | < < | < < < | | | 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 |
}
note = s.notes[0]
// note head
p = note.pit
pit = p + delta
nn = ((pit + 77) % 7) + 1 // note number
abc.dh_put('n' + nn, s, note)
// display the note as C5 with stem up
note.pit = 23 // 'c'
s.stem = 1
// octave
nn = (pit / 7) | 0
if (nn > prev_oct) {
if (prev_oct != -10)
abc.dh_put('q', s, note)
prev_oct = nn
} else if (nn < prev_oct) {
abc.dh_put('c', s, note)
prev_oct = nn
}
// half and whole notes
if (s.dur >= C.BLEN / 2)
abc.dh_put(s.dur >= C.BLEN ? 'w' : 'h', s, note)
// accidentals
a = note.acc
if (a) {
note.acc = 0
nn = abc2svg.mdnn.cde2fcg[(p + 5 + 16 * 7) % 7] - sf
if (a != 3)
nn += a * 7
nn = ((((nn + 1 + 21) / 7) | 0) + 2 - 3 + 32 * 5) % 5
abc.dh_put(abc2svg.mdnn.acc_tb[nn], s, note)
}
// set the slurs and ties up
if (s.sls) {
for (i = 0; i < s.sls.length; i++)
s.sls[i].ty = C.SL_ABOVE
}
if (note.sls) {
for (i = 0; i < note.sls.length; i++)
note.sls[i].ty = C.SL_ABOVE
}
if (note.tie_ty != undefined)
note.tie_ty = C.SL_ABOVE
}
of()
}, // output_music()
set_fmt: function(of, cmd, param) {
if (cmd == "mdnn")
this.cfmt().mdnn = param
else
of(cmd, param)
}, // set_fmt()
// don't display the key signature at start of staff
set_pitch: function(of, last_s) {
of(last_s)
|
| ︙ | ︙ |
Added modules/nns.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
// abc2svg - nns.js - module to output chords in the NNS
// (Nashville Notation System)
//
// Copyright (C) 2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%nns" appears in a ABC source.
//
// Parameters
// %%nns [n] [include=<list>] [nomusic] [repbrk] [roman]
// <n> = number of chords per line (1: auto)
// > 0: above the tune, < 0: under the tune
// <list> = comma separated list of (continuous) measure numbers
// 'nomusic' displays only the chord
// 'repbrk' starts a new grid line on start/stop repeat
// 'roman' Roman Numeral Notation
// %%nnsfont font_name size (default: 'monospace 16')
abc2svg.nns = {
note_nm: "CDEFGAB",
// Nashville
nns_nm: ["1", "♯1", "2", "♭3", "3", "4", "♯4",
"5", "♯5", "6", "♭7", "7"],
nns_nm_m: ["1", "♭2", "2", "3", "♯3", "4", "♭5",
"5", "6", "♯6", "7", "♯7"],
// Roman
rnn_nm: ["I", "♯I", "II", "♭III", "III", "IV", "♯IV",
"V", "♯V", "VI", "♭VII", "VII"],
rnn_nm_m: ["I", "♭II", "II", "III", "♯III", "IV", "♭V",
"V", "VI", "♯VI", "VII", "♯VII"],
// inversions: 1st: (upper)6, 2nd: (upper)6 (lower) 4
// generate the grid
block_gen: function(of, s) {
if (s.subtype != "nns") {
of(s)
return
}
var abc = this,
img,
cfmt = abc.cfmt(),
nns = cfmt.nns
// generate the chord list
function build_nns(s, font) {
var i, k, l, nr, bar, w, hr, x, y, row,
chords = s.chords,
bars = s.bars,
parts = s.parts || [],
cells = [],
nc = nns.n
// set the chord(s) in each measure
function set_chords() {
var i, ch,
pch = '-'
for (i = 0; i < chords.length; i++) {
ch = chords[i]
if (!ch[0])
ch[0] = pch
switch (ch.length) {
case 0:
continue
case 1:
pch = ch[0]
continue
case 2:
pch = ch[1]
continue
case 3:
pch = ch[2]
continue
}
pch = ch[3]
}
} // set_chords()
// get the original length of chord symbol
function get_l(p) {
var i,
l = 0
for (i = 0; i < p.length; i++) {
if (p[i] == '<') {
while (p[i] != '>')
i++
continue
}
l++
}
return l
} // get_l()
function build_cell(c) {
var i, j, k,
u = '',
t = ''
row += ' '
if (c.length == 1) {
row += c[0] // one chord in the measure
return
}
i = 0
while (i < 4) {
t += c[i]
k = get_l(c[i])
j = k
while (--j >= 0)
u += ' ' //
if (i < 3 && !c[i + 1]) {
while (i < 3 && !c[i + 1])
i++
i++
if (i < 4 && c[i])
t += ' '
} else {
j = k
t += '<tspan dx="-'
+ (j * .6).toFixed(1)
+ 'em" dy=".2em">'
while (--j >= 0)
t += '_'
t += '</tspan>'
i++
if (i < 4 && c[i])
t += '<tspan dy="-.2em"> </tspan>'
else
t += '<tspan dx="-.6em" dy="-.2em"> </tspan>'
}
}
row += t + '<tspan dx="-'
+ (.6 * u.length).toFixed(1)
+ 'em" text-decoration="underline">'
+ u
+ '</tspan>'
} // build_cell()
// ------- build_nns() -------
// set some chords in each measure
set_chords()
// build the content of the measures
if (!nns.ls) {
cells = chords
} else { // with list of mesure numbers
bar = bars
bars = [ ]
for (i = 0; i < nns.ls.length; i++) {
l = nns.ls[i]
if (l.indexOf('-') < 0)
l = [l, l]
else
l = l.split('-')
for (k = l[0] - 1; k < l[1]; k++) {
if (!chords[k]) // error
break
cells.push(chords[k])
bars.push(bar[k])
}
}
bars.push(bar[k]) // ending bar
}
// get the number of columns
if (nc < 0)
nc = -nc
if (nc < 3) { // auto
nc = cells.length % 6 == 0 ? 6 : 8
if (nc == 8 && cells.length < 12)
nc = 4
}
if (nc > cells.length)
nc = cells.length
// generate the rows
abc.set_font('nns')
x = img.lm + 30
y = -1 + font.size * .6
nr = 0
hr = font.size * 2
for (i = 0; i < cells.length; i++) {
if (i == 0
|| (nns.repbrk
&& (bars[i].slice(-1) == ':' || bars[i][0] == ':'))
|| parts[i]
|| k >= nc) {
if (row) {
abc.out_svg('<text class="'
+ abc.font_class(font)
+ '" x="')
abc.out_sxsy(x, '" y="', y)
abc.out_svg('">' + row + '</text>\n')
}
row = ''
y -= hr // new row
k = 0
nr++
if (parts[i]) {
w = font.size * parts[i].length * .6 + 10
if (w < 50)
w = 50
abc.out_svg('<text class="'
+ abc.font_class(font)
+ ' box'
+ '" x="')
abc.out_sxsy(x - w, '" y="', y)
abc.out_svg('">' + parts[i] + '</text>\n')
}
}
k++
if (bars[i].slice(-1) == ':')
row += ' |:'
build_cell(cells[i])
if (bars[i + 1][0] == ':')
row += ' :|'
}
if (row) {
abc.out_svg('<text class="'
+ abc.font_class(font)
+ '" x="')
abc.out_sxsy(x, '" y="', y)
abc.out_svg('">' + row + '</text>\n')
}
abc.vskip(hr * nr + 6)
} // build_nns()
// ----- block_gen() -----
var p_voice, n, font, f2
img = abc.get_img()
// set the text style
if (!cfmt.nnsfont)
abc.param_set_font("nnsfont", "monospace 16")
font = abc.get_font('nns')
// create the chord list
abc.blk_flush()
build_nns(s, font)
abc.blk_flush()
}, // block_gen()
// hook before the generation
set_stems: function(of) {
var C, tsfirst, voice_tb, fmt, p_v, s, s2, mode,
abc = this,
nns = abc.cfmt().nns
function get_beat(s) {
var beat = C.BLEN / 4
if (!s.a_meter[0] || s.a_meter[0].top[0] == 'C'
|| !s.a_meter[0].bot)
return beat
beat = C.BLEN / s.a_meter[0].bot[0] |0
if (s.a_meter[0].bot[0] == 8
&& s.a_meter[0].top[0] % 3 == 0)
beat = C.BLEN / 8 * 3
return beat
} // get_beat()
// transpose the chord back to "C"
function set_nm(p, tr) {
var i, o, o2, a, n,
csa = []
i = p.indexOf('/') // get the bass if any
if (i > 0) {
while (1) {
if (p[i -1] != '<')
break
i = p.indexOf('/', i + 1)
if (i < 0)
break
}
}
if (i < 0) {
csa.push(p)
} else {
csa.push(p.slice(0, i))
csa.push(p.slice(i + 1))
}
for (i = 0; i < csa.length; i++) { // main and optional bass
p = csa[i]
o = p.search(/[A-G]/) // get the base chord
if (o < 0)
continue // not a chord!
a = 0
o2 = o + 1
if (p[o2] == '#' || p[o2] == '♯') {
a++
o2++
} else if (p[o2] == 'b' || p[o2] == '♭') {
a--
o2++
}
n = ([0, 2, 4, 5, 7, 9, 11]
[abc2svg.nns.note_nm.indexOf(p[o])]
+ a
+ tr) % 12
if (mode)
n = (n + 3) % 12
if (!nns.roman) {
if (!mode)
n = abc2svg.nns.nns_nm[n] // major
else
n = abc2svg.nns.nns_nm_m[n] // minor
} else {
if (!mode)
n = abc2svg.nns.rnn_nm[n]
else
n = abc2svg.nns.rnn_nm_m[n]
}
csa[i] = p.slice(0, o)
+ n
+ p.slice(o2)
}
return csa.join('/')
} // set_nm()
// build the arrays of chords and bars
function build_chords(sb) { // block 'nns'
var s, i, w, bt, rep,
bars = [],
chords = [],
parts = [],
chord = [],
beat = get_beat(voice_tb[0].meter),
wm = voice_tb[0].meter.wmeasure,
cur_beat = 0,
beat_i = 0,
tr = (tsfirst.p_v.key.k_sf + 12) * 5
// transposition to "C"
// scan all the symbols
bars.push('|')
for (s = tsfirst; s; s = s.ts_next) {
while (s.time > cur_beat) {
if (beat_i < 3) // only 2, 3 or 4 beats / measure...
beat_i++
cur_beat += beat
}
if (s.part)
parts[chords.length] = s.part.text
switch (s.type) {
case C.NOTE:
case C.REST:
if (!s.a_gch)
break
// search a chord symbol
for (i = 0; i < s.a_gch.length; i++) {
if (s.a_gch[i].type == 'g') {
if (!chord[beat_i]) {
chord[beat_i] =
set_nm(s.a_gch[i].text,
tr)
}
break
}
}
break
case C.BAR:
bt = s.bar_type
if (s.time < wm) { // if anacrusis
if (chord.length) {
chords.push(chord)
bars.push(bt)
} else {
bars[0] = bt
}
} else {
if (!s.bar_num) // if not normal measure bar
break
chords.push(chord)
bars.push(bt)
}
chord = []
cur_beat = s.time // synchronize in case of error
beat_i = 0
if (bt.indexOf(':') >= 0)
rep = true // some repeat
while (s.ts_next && s.ts_next.type == C.BAR)
s = s.ts_next
break
case C.METER:
beat = get_beat(s)
wm = s.wmeasure
break
}
}
if (chord.length) {
bars.push('')
chords.push(chord)
}
if (!chords.length)
return // no chord in this tune
sb.chords = chords
sb.bars = bars
if (parts.length)
sb.parts = parts
} // build_chords
// -------- set_stems --------
// create a specific block
if (nns) {
C = abc2svg.C
tsfirst = this.get_tsfirst()
mode = tsfirst.p_v.key.k_mode
fmt = tsfirst.fmt
voice_tb = this.get_voice_tb()
p_v = voice_tb[this.get_top_v()]
s = {
type: C.BLOCK,
subtype: 'nns',
dur: 0,
time: 0,
p_v: p_v,
v: p_v.v,
st: p_v.st
}
build_chords(s) // build the array of the chords
// and insert it in the tune
if (!s.chords) { // if no chord
;
} else if (nns.nomusic) { // if just the chords
this.set_tsfirst(s)
} else if (nns.n < 0) { // below
for (s2 = tsfirst; s2.ts_next; s2 = s2.ts_next)
;
s.time = s2.time
s.prev = p_v.last_sym.prev // before the last symbol
s.prev.next = s
s.next = p_v.last_sym
p_v.last_sym.prev = s
s.ts_prev = s2.ts_prev
s.ts_prev.ts_next = s
s.ts_next = s2
s2.ts_prev = s
if (s2.seqst) {
s.seqst = true
s2.seqst = false
}
} else { // above
s.next = p_v.sym
s.ts_next = tsfirst
tsfirst.ts_prev = s
this.set_tsfirst(s)
p_v.sym.prev = s
p_v.sym = s
}
s.fmt = s.prev ? s.prev.fmt : fmt
}
of()
}, // set_stems()
set_fmt: function(of, cmd, parm) {
if (cmd == "nns") {
if (!parm)
parm = "1"
parm = parm.split(/\s+/)
var nns = {
n: Number(parm.shift())
}
if (isNaN(nns.n)) {
if (parm.length) {
this.syntax(1, this.errs.bad_val, "%%nns")
return
}
nns.n = 1
}
while (parm.length) {
var item = parm.shift()
if (item == "nomusic")
nns.nomusic = true
else if (item == "roman")
nns.roman = true
else if (item == "repbrk")
nns.repbrk = true
else if (item.slice(0, 8) == "include=")
nns.ls = item.slice(8).split(',')
}
this.cfmt().nns = nns
return
}
of(cmd, parm)
},
set_hooks: function(abc) {
abc.block_gen = abc2svg.nns.block_gen.bind(abc, abc.block_gen)
abc.set_stems = abc2svg.nns.set_stems.bind(abc, abc.set_stems)
abc.set_format = abc2svg.nns.set_fmt.bind(abc, abc.set_format)
}
} // nns
abc2svg.modules.hooks.push(abc2svg.nns.set_hooks)
// the module is loaded
abc2svg.modules.nns.loaded = true
|
Changes to modules/page.js.
1 2 | // page.js - module to generate pages // | | > > > > > > > > > > > > > > > | 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 |
// page.js - module to generate pages
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%pageheight" appears in a ABC source.
//
// Parameters
// %%pageheight <unit>
abc2svg.page = {
|
| ︙ | ︙ | |||
39 40 41 42 43 44 45 46 47 48 |
font = page.abc.get_font(ty),
str = page[ty],
cfmt = page.abc.cfmt(),
fh = font.size * 1.1,
pos = [ '">',
'" text-anchor="middle">',
'" text-anchor="end">' ]
// create the text of a header or a footer
function header_footer(o_font, str) {
| > > > > > > > > > > > > > > > > > | < < | < | < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < > | | | | > > < | | | | | < | | < | | > | | | > > | > | > > > > > > > > > > > > > > | | 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 |
font = page.abc.get_font(ty),
str = page[ty],
cfmt = page.abc.cfmt(),
fh = font.size * 1.1,
pos = [ '">',
'" text-anchor="middle">',
'" text-anchor="end">' ]
// replace <>& by XML character references
function clean_txt(txt) {
return txt.replace(/<|>|&.*?;|&/g, function(c) {
switch (c) {
case '<': return "<"
case '>': return ">"
case '&': return "&"
}
return c
})
} // clean_txt()
// clear a field if $x said so
function clr(str) {
return str.indexOf('\u00ff') >= 0 ? '' : str
} //clr()
// create the text of a header or a footer
function header_footer(o_font, str) {
var c, d, i, k, t, n_font, s,
c_font = o_font,
nl = 1,
j = 0,
r = ["", "", ""]
if (str[0] == '"')
str = str.slice(1, -1)
while (1) {
i = str.indexOf('$', j)
if (i < 0)
break
c = str[++i]
s = '$' + c // string to replace
switch (c) {
case 'd':
if (!abc2svg.get_mtime)
break // cannot know the change time of the file
d = abc2svg.get_mtime(abc.parse.fname)
// fall thru
case 'D':
if (c == 'D')
d = new Date()
if (cfmt.dateformat[0] == '"')
cfmt.dateformat = cfmt.dateformat.slice(1, -1)
d = strftime(cfmt.dateformat, d)
break
case 'F':
d = page.abc.parse.fname
break
case 'I':
c = str[++i]
s += c
// fall thru
case 'T':
t = page.abc.info()[c]
d = t ? t.split('\n', 1)[0] : ''
break
case 'P': // current page number
case 'Q': // absolute page number
t = c == 'P' ? page.pn : page.pna
switch (str[i + 1]) {
case '0':
s += '0'
d = (t & 1) ? '\u00ff' : t
break
case '1':
s += '1'
d = (t & 1) ? t : '\u00ff'
break
default:
d = t
break
}
break
case 'V':
d = "abc2svg-" + abc2svg.version
break
default:
d = ''
if (c == '0')
n_font = o_font
else if (c >= '1' && c < '9')
n_font = page.abc.get_font("u" + c)
else
break
// handle the font changes
if (n_font == c_font)
break
if (c_font != o_font)
d += "</tspan>"
c_font = n_font
if (c_font == o_font)
break
d += '<tspan class="' +
font_class(n_font) + '">'
break
}
str = str.replace(s, d)
j = i
}
if (c_font != o_font)
str += "</tspan>";
str = str.split('\n')
r[4] = str.length // number of lines
for (j = 0; j < str.length; j++) {
if (j != 0)
for (i = 0; i < 3; i++)
r[i] += '\n'
t = str[j].split('\t')
if (t.length == 1) {
r[1] += clr(t[0])
} else {
for (i = 0; i < 3; i++) {
if (t[i])
r[i] += clr(t[i])
}
}
}
return r
} // header_footer()
function font_class(font) {
if (font.class)
return 'f' + font.fid + cfmt.fullsvg + ' ' + font.class
return 'f' + font.fid + cfmt.fullsvg
}
// gen_hf
if (str[0] == '-') { // not on 1st page
if (page.pn == 1)
return 0
str = str.slice(1)
}
a = header_footer(font, clean_txt(str))
y0 = font.size * .8
for (i = 0; i < 3; i++) {
str = a[i]
if (!str)
continue
if (i == 0)
x = cfmt.leftmargin
|
| ︙ | ︙ | |||
334 335 336 337 338 339 340 | abc2svg.page.close_page(page) abc2svg.page.open_page(page, 0) } page.blk = [] // in block page.hb = page.h // keep the offset of the start of tune break case "<svg": // SVG image | | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
abc2svg.page.close_page(page)
abc2svg.page.open_page(page, 0)
}
page.blk = [] // in block
page.hb = page.h // keep the offset of the start of tune
break
case "<svg": // SVG image
h = Number(p.match(/viewBox="0 0 \d+ (\d+)"/)[1])
while (h + page.h >= page.hmax) { // if (still) page overflow
ht = page.blk ? 0 :
this.cfmt().topspace // tune continuation
if (page.blk) {
if (!page.hb) { // overflow on the first page
blkcpy(page)
|
| ︙ | ︙ |
Changes to modules/pedline.js.
1 2 | // pedline.js - module to draw pedal lines instead of 'Ped .. *' // | | > > > > > > > > > > > > > > > | 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 |
// pedline.js - module to draw pedal lines instead of 'Ped .. *'
//
// Copyright (C) 2020-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded when "%%pedline" appears in a ABC source.
//
// Parameters
// %%pedline 1
abc2svg.pedline = {
|
| ︙ | ︙ | |||
59 60 61 62 63 64 65 |
} else {
this.out_svg("h" + val.toFixed(1) + 'v-6"/>\n')
}
}, // out_lped()
set_fmt: function(of, cmd, param) {
if (cmd == "pedline")
| | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
} else {
this.out_svg("h" + val.toFixed(1) + 'v-6"/>\n')
}
}, // out_lped()
set_fmt: function(of, cmd, param) {
if (cmd == "pedline")
this.cfmt().pedline = this.get_bool(param)
else
of(cmd, param)
}, // set_fmt()
set_hooks: function(abc) {
abc.draw_all_deco = abc2svg.pedline.draw_all_deco.bind(abc, abc.draw_all_deco)
abc.out_lped = abc2svg.pedline.out_lped.bind(abc, abc.out_lped)
|
| ︙ | ︙ |
Changes to modules/perc.js.
1 2 | // perc.js - module to handle %%percmap // | | > > > > > > > > > > > > > > > | 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 | // perc.js - module to handle %%percmap // // Copyright (C) 2018-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%percmap" appears in a ABC source. // // Parameters (from W. Vree) // %%percmap ABC_note percussion [note_head] // The percussion may be a number (MIDI percussion number range 35..81), // a ABC note or a possibly abbreviated percussion name. |
| ︙ | ︙ | |||
115 116 117 118 119 120 121 | "s-g": 73, "s-s": 37, "s-w": 71, "t": 54, "v": 58 } | | | | < < < < < < < < < < < < < < < < < < < < < < < < | | < < < | < < < < < < < < < | < < < | < < < < | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
"s-g": 73,
"s-s": 37,
"s-w": 71,
"t": 54,
"v": 58
}
// convert a drum instrument to a ABC note
function toabc(p) {
var i, j, s, pit
if (/^[_^]*[A-Ga-g][,']*$/.test(p)) // '
return p // ABC note
// if not a MIDI pitch, try a drum instrument name
pit = Number(p)
if (isNaN(pit)) {
p = p.toLowerCase(p);
s = p[0]; // get the 1st letters after '-'
i = 0
while (1) {
j = p.indexOf('-', i)
if (j < 0)
break
|
| ︙ | ︙ | |||
195 196 197 198 199 200 201 |
}
break
case 'h':
case 'l':
i = p.indexOf('-')
if (p[i + 1] != 't')
break
| | | | | > | | | < > | | < > | < < | < | < < < | | < < < < | < | < < < < < < < < < < < < < < < < < < | | 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 |
}
break
case 'h':
case 'l':
i = p.indexOf('-')
if (p[i + 1] != 't')
break
switch (p[i + 2]) {
case 'i':
case 'o':
pit = prn[s + p[i + 2]]
break
}
break
}
if (!pit)
return
}
}
p = ["C","^C","D","_E","E","F","^F","G","^G","A","_B","B"][pit % 12]
while (pit < 60) {
p += ','
pit += 12
}
while (pit >= 72) {
p += "'"
pit -= 12
}
return p
} // toabc()
// do_perc()
var a = parm.split(/\s+/),
p = a[1].replace(/[=_^]/, '')
this.do_pscom("map MIDIdrum " + a[1] +
" play=" + toabc(a[2]) +
" print=" + p +
(a[3] ? (" heads=" + a[3]) : ''))
this.set_v_param("perc", "MIDIdrum")
}, // do_perc()
// set the MIDI parameters in the current voice
set_perc: function(a) {
var i, item,
curvoice = this.get_curvoice()
|
| ︙ | ︙ |
Changes to modules/psvg.js.
1 2 | // psvg.js - small PS to SVG convertor for abc2svg | | | | | | | 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 |
// psvg.js - small PS to SVG convertor for abc2svg
// Copyright (C) 2014-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
function Psvg(abcobj_r) {
var svgbuf = '',
// SVG functions - adapted from abcm2ps svg.c
abcobj = abcobj_r,
wps = new Wps(this),
|
| ︙ | ︙ |
Added modules/roman.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
// abc2svg - roman.js - convert the chord symbols to the RNN
// (Roman Numeral Notation)
//
// Copyright (C) 2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This module is loaded by %%roman.
//
// Parameters
// %%roman int
// <int>
// = '1': use uppercase letters with 'm' for minor chords
// = '2': user lowercase letters for minor chords
abc2svg.roman = {
note_nm: "CDEFGAB",
// chord names
nm_M: ["I", "♯I", "II", "♭III", "III", "IV", "♯IV",
"V", "♯V", "VI", "♭VII", "VII"],
nm_m: ["I", "♭II", "II", "III", "♯III", "IV", "♭V",
"V", "VI", "♯VI", "VII", "♯VII"],
// inversions: 1st: (upper)6, 2nd: (upper)6 (lower) 4
gch_build: function(of, s) {
var gch, ix, t,
ty = this.cfmt().roman
// transpose the chord back to "C"
function set_nm(p) {
var i, o, o2, a, n,
csa = []
i = p.indexOf('/') // get the bass if any
while (i > 0) {
if (p[i - 1] != '<') // if not </tag
break
i = p.indexOf('/', i + 1)
}
if (i < 0) {
csa.push(p)
} else {
csa.push(p.slice(0, i))
csa.push(p.slice(i + 1))
}
for (i = 0; i < csa.length; i++) { // main and optional bass
p = csa[i]
o = p.search(/[A-G]/) // get the base chord
if (o < 0)
continue // not a chord!
a = 0
o2 = o + 1
if (p[o2] == '#' || p[o2] == '♯') {
a++
o2++
} else if (p[o2] == 'b' || p[o2] == '♭') {
a--
o2++
}
n = [0, 2, 4, 5, 7, 9, 11]
[abc2svg.roman.note_nm.indexOf(p[o])]
+ a
+ abc2svg.roman.tr
n = abc2svg.roman.nm[n % 12]
if (ty == 2 && p[o2] == 'm') {
n = n.toLowerCase()
o2++
}
csa[i] = p.slice(0, o)
+ n
+ p.slice(o2)
}
return csa.join('/')
} // set_nm()
if (ty && s.a_gch) {
for (ix = 0; ix < s.a_gch.length; ix++) {
gch = s.a_gch[ix]
t = gch.text
if (gch.type == 'g' && t && t[0] != 'N') {
t = set_nm(t)
if (t)
gch.text = t
}
}
}
of(s)
}, // gch_build()
// hook before the generation
o_mus: function(of) {
var tsfirst = this.get_tsfirst()
if (this.cfmt().roman) {
abc2svg.roman.tr = (tsfirst.p_v.key.k_sf + 12) * 5
// transposition to "C"
if (tsfirst.p_v.key.k_mode) {
abc2svg.roman.tr += 3 // minor
abc2svg.roman.nm = abc2svg.roman.nm_m
} else {
abc2svg.roman.nm = abc2svg.roman.nm_M
}
}
of()
}, // o_mus()
set_fmt: function(of, cmd, parm) {
var ty,
cfmt = this.cfmt()
if (cmd == "roman") {
if (!parm)
parm = "1"
ty = Number(parm)
if (isNaN(ty))
this.syntax(1, this.errs.bad_val, "%%roman")
else
cfmt.roman = ty
return
}
of(cmd, parm)
}, // set_fmt()
set_hooks: function(abc) {
abc.gch_build = abc2svg.roman.gch_build.bind(abc, abc.gch_build)
abc.output_music = abc2svg.roman.o_mus.bind(abc, abc.output_music)
abc.set_format = abc2svg.roman.set_fmt.bind(abc, abc.set_format)
} // set_hooks()
} // roman
abc2svg.modules.hooks.push(abc2svg.roman.set_hooks)
abc2svg.modules.roman.loaded = true
|
Changes to modules/soloffs.js.
1 2 | // soloffs.js - module to set the X offset of some elements at start of music line // | | > > > > > > > > > > > > > > > | 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 |
// soloffs.js - module to set the X offset of some elements at start of music line
//
// Copyright (C) 2018-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// Parameters
// %%soloffs <type>=<offset> [<type>=<offset>]*
// <type> is one of 'part', 'tempo' or 'space'
// <offset> is the X offset from the start of staff
abc2svg.soloffs = {
|
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
if (isNaN(v))
continue // error
switch (i[0]) {
// case 'bar':
// soloffs[C.BAR] = v
// break
case 'part':
| | < | > > | 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 |
if (isNaN(v))
continue // error
switch (i[0]) {
// case 'bar':
// soloffs[C.BAR] = v
// break
case 'part':
soloffs[C.PART] = v // see deco.js
break
case 'tempo':
soloffs[C.TEMPO] = v + 16 // see deco.js
break
case 'space':
soloffs[C.SPACE] = v
break
// default:
// // error
// break
}
}
return
}
of(cmd, parm)
},
set_sym_glue: function(of, width) {
var s,
tsfirst = this.get_tsfirst(),
soloffs = this.cfmt().soloffs;
of(width) // compute the x offset of the symbols
if (!soloffs)
return
for (s = tsfirst; s; s = s.ts_next) {
if (s.time != tsfirst.time)
break
if (soloffs[s.type] != undefined)
s.x = soloffs[s.type]
if (s.part && soloffs[abc2svg.C.PART] != undefined)
s.part.x = soloffs[abc2svg.C.PART]
}
}, // set_sym_glue()
set_hooks: function(abc) {
abc.set_sym_glue = abc2svg.soloffs.set_sym_glue.bind(abc, abc.set_sym_glue);
abc.set_format = abc2svg.soloffs.set_fmt.bind(abc, abc.set_format)
}
} // soloffs
abc2svg.modules.hooks.push(abc2svg.soloffs.set_hooks);
// the module is loaded
abc2svg.modules.soloffs.loaded = true
|
Changes to modules/sth.js.
1 2 | // sth.js - module to set the stem heights // | | > > > > > > > > > > > > > > > | 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 | // sth.js - module to set the stem heights // // Copyright (C) 2018-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%sth" appears in a ABC source. // // Parameters // %%sth h1 h2 h3 ... // The values h1, h2, .. are applied to the following notes which // have a stem and which are not inside a beam. |
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
curvoice.sth = null // some stem widths in this voice
}
return s
},
set_fmt: function(of, cmd, param) {
if (cmd == "sth") {
| < < | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
curvoice.sth = null // some stem widths in this voice
}
return s
},
set_fmt: function(of, cmd, param) {
if (cmd == "sth") {
var curvoice = this.get_curvoice()
if (curvoice)
curvoice.sth = param.split(/[ \t;-]+/)
return
}
of(cmd, param)
},
|
| ︙ | ︙ |
Changes to modules/strftime.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* Port of strftime() by T. H. Doan (https://thdoan.github.io/strftime/)
*
* Day of year (%j) code based on Joe Orost's answer:
* http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
*
* Week number (%V) code based on Taco van den Broek's prototype:
* http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
*/
function strftime(sFormat, date) {
if (!(date instanceof Date)) date = new Date();
var nDay = date.getDay(),
nDate = date.getDate(),
nMonth = date.getMonth(),
nYear = date.getFullYear(),
nHour = date.getHours(),
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* Port of strftime() by T. H. Doan (https://thdoan.github.io/strftime/)
*
* Day of year (%j) code based on Joe Orost's answer:
* http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
*
* Week number (%V) code based on Taco van den Broek's prototype:
* http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
*/
// Copyright (c) 2016 Tom Doan - License MIT
function strftime(sFormat, date) {
if (!(date instanceof Date)) date = new Date();
var nDay = date.getDay(),
nDate = date.getDate(),
nMonth = date.getMonth(),
nYear = date.getFullYear(),
nHour = date.getHours(),
|
| ︙ | ︙ |
Changes to modules/strtab.js.
1 2 | // abc2svg - strtab.js - tablature for string instruments // | | | > > > > > > > > > > > > > > | 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 | // abc2svg - strtab.js - tablature for string instruments // // Copyright (C) 2020-2022 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded by %%strtab. // The command %%strtab changes the display of the voice to a tablature. // Syntax: // %%strtab <string list> [diafret] // <string list> is the list of the strings as ABC notes // diafret indicates the instrument has diatonic frets |
| ︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// draw the note heads
stb = abc.get_staff_tb()[p_v.st].y
abc.out_svg('<g class="bn">\n')
for (s = p_v.sym; s; s = s.next) {
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
not = s.notes[m]
x = s.x - 3
if (not.nb >= 10)
x -= 3
y = 3 * (not.pit - 18)
abc.out_svg('<text class="bg' + abc.bgn +
'" x="')
abc.out_sxsy(x, '" y="', stb + y - 2.5)
| > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
// draw the note heads
stb = abc.get_staff_tb()[p_v.st].y
abc.out_svg('<g class="bn">\n')
for (s = p_v.sym; s; s = s.next) {
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
not = s.notes[m]
if (not.nb < 0)
continue
x = s.x - 3
if (not.nb >= 10)
x -= 3
y = 3 * (not.pit - 18)
abc.out_svg('<text class="bg' + abc.bgn +
'" x="')
abc.out_sxsy(x, '" y="', stb + y - 2.5)
|
| ︙ | ︙ | |||
121 122 123 124 125 126 127 |
abc = this,
s = abc.get_tsfirst(), // first symbol
strs = [], // notes per staff - index = staff
lstr = [] // lowest string per staff - index staff
// set a string (pitch) and a fret number
function set_pit(p_v, s, nt, i) {
| | < > > | | > > > > > < < | 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 |
abc = this,
s = abc.get_tsfirst(), // first symbol
strs = [], // notes per staff - index = staff
lstr = [] // lowest string per staff - index staff
// set a string (pitch) and a fret number
function set_pit(p_v, s, nt, i) {
var st = s.st
if (i >= 0) {
nt.nb = (p_v.diafret ? nt.pit : nt.midi) - p_v.tab[i]
if (p_v.diafret && nt.acc)
n += '+'
nt.pit = i * 2 + 18
} else {
nt.nb = -1
nt.pit = 18
}
nt.acc = 0
nt.invis = true
strss[i] = s.time + s.dur
if (s.nflags >= -1 && !s.stemless) {
if (!lstr[st])
lstr[st] = [ 10 ]
if (lstr[st][0] > i) {
lstr[st][0] = i
lstr[st][1] = s
|
| ︙ | ︙ | |||
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 |
case C.TIME:
s.invis = true
default:
continue
case C.NOTE:
break
}
// handle the fret numbers as chord decoration
if (!s.nhd && s.a_dd) {
i = s.a_dd.length
while (--i >= 0) {
bi = strnum(s.a_dd[i].name)
if (bi >= 0) {
nt = s.notes[0]
set_pit(p_v, s, nt, bi)
break
}
}
delete s.a_dd
}
ls: for (m = 0; m <= s.nhd; m++) {
nt = s.notes[m]
if (nt.nb != undefined)
continue
| > > | | | | | > | 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 |
case C.TIME:
s.invis = true
default:
continue
case C.NOTE:
break
}
s.stem = -1 // down stems
// handle the fret numbers as chord decoration
if (!s.nhd && s.a_dd) {
i = s.a_dd.length
while (--i >= 0) {
bi = strnum(s.a_dd[i].name)
if (bi >= 0) {
nt = s.notes[0]
set_pit(p_v, s, nt, bi)
break
}
}
delete s.a_dd
}
ls: for (m = 0; m <= s.nhd; m++) {
nt = s.notes[m]
if (nt.nb != undefined)
continue
if (nt.a_dd) {
i = nt.a_dd.length
while (--i >= 0) {
bi = strnum(nt.a_dd[i].name)
if (bi >= 0) {
set_pit(p_v, s, nt, bi)
delete nt.a_dd
continue ls
}
}
delete nt.a_dd
}
// search the best string
bn = 100
bi = -1
i = p_v.tab.length
while (--i >= 0) {
if (strss[i] && strss[i] > s.time)
continue
n = (p_v.diafret ?
nt.pit : nt.midi) -
p_v.tab[i]
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 | break a.splice(i, 1) // fall thru case "tab": a.splice(i, 1) i-- ok = true | < | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | break a.splice(i, 1) // fall thru case "tab": a.splice(i, 1) i-- ok = true break case "strings=": strs = a[++i] ok = true break case "nostems": p_v.pos.stm = abc2svg.C.SL_HIDDEN |
| ︙ | ︙ | |||
373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
this.syntax(1, "Bad strings in tablature")
ok = false
}
} else if (!p_v.tab) {
tab = p_v.diafret ?
[10, 14, 17] : // dulcimer
[40, 45, 50, 55, 59, 64] // guitar strings
}
}
if (ok) {
if (p_v.capo) {
p_v.tab = []
for (i = 0; i < tab.length; i++)
p_v.tab.push(tab[i] + p_v.capo)
| > > | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
this.syntax(1, "Bad strings in tablature")
ok = false
}
} else if (!p_v.tab) {
tab = p_v.diafret ?
[10, 14, 17] : // dulcimer
[40, 45, 50, 55, 59, 64] // guitar strings
} else {
tab = p_v.tab
}
}
if (ok) {
if (p_v.capo) {
p_v.tab = []
for (i = 0; i < tab.length; i++)
p_v.tab.push(tab[i] + p_v.capo)
|
| ︙ | ︙ |
Changes to modules/temper.js.
1 2 | // temper.js - module to define the temperament // | | > > > > > > > > > > > > > > > | 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 | // temper.js - module to define the temperament // // Copyright (C) 2018-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // // This module is loaded when "%%temperament" appears in a ABC source. // // Parameters // %%temperament <list> // The <list> must contain 12 integer values that are the detune values in cents // of the 12 notes of the equal scale. |
| ︙ | ︙ |
Changes to package.json.
1 2 |
{
"name": "abc2svg",
| | < < < | 1 2 3 4 5 6 7 8 9 10 11 |
{
"name": "abc2svg",
"version": "1.21.6",
"description": "ABC music notation translator",
"files": [
"COPYING",
"COPYING.LESSER",
"MIDI-1.js",
"Scc1t2/",
"abc2odt",
"abc2svg",
|
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
"err-fr.js",
"err-it.js",
"err-pt_BR.js",
"grid-1.js",
"grid2-1.js",
"grid3-1.js",
"json-1.js",
| | > > > | 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 |
"err-fr.js",
"err-it.js",
"err-pt_BR.js",
"grid-1.js",
"grid2-1.js",
"grid3-1.js",
"json-1.js",
"jazzchord-1.js",
"jianpu-1.js",
"mdnn-1.js",
"nns-1.js",
"page-1.js",
"pedline-1.js",
"perc-1.js",
"play-1.js",
"psvg-1.js",
"roman-1.js",
"snd-1.js",
"soloffs-1.js",
"sth-1.js",
"strtab-1.js",
"temper-1.js",
"toabc.js",
"toaudio-1.js",
"toabw.js",
"tohtml.js",
"tomei.js",
"tonotes.js",
"toodt.js",
"toparam.js",
"toxhtml.js"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
|
| ︙ | ︙ |
Changes to toabc.js.
1 2 | // abc2svg - toabc.js - convert ABC to ABC // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - toabc.js - convert ABC to ABC // // Copyright (C) 2016-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
59 60 61 62 63 64 65 | ], k_tb = [ // key names "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" ] | | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
],
k_tb = [ // key names
"Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C",
"G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#"
]
function abc_dump(tsfirst, voice_tb, info, cfmt) {
var i, v, s, g, line, ulen, tmp, tmp2, grace, bagpipe, curv,
cfmtg = abc.cfmt(), // global format
nv = voice_tb.length,
vo = [], // dump line per voice
vold = [], // false/true for voice name
vti = []
// dump an information field on voice 'v'
function info_out(inf) {
|
| ︙ | ︙ | |||
225 226 227 228 229 230 231 |
ln += (s.clef_oct_transp ? '^' : '+') + '8'
else if (s.clef_octave == -7)
ln += (s.clef_oct_transp ? '_' : '-') + '8'
return "clef=" + ln
} // clef_dump()
function deco_dump(a_dd) {
| | | > > > > > > > | | | | > | 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 |
ln += (s.clef_oct_transp ? '^' : '+') + '8'
else if (s.clef_octave == -7)
ln += (s.clef_oct_transp ? '_' : '-') + '8'
return "clef=" + ln
} // clef_dump()
function deco_dump(a_dd) {
var i, n, dd
//fixme: check if user deco
for (i = 0; i < a_dd.length; i++) {
dd = a_dd[i]
n = dd.name
if (dd.ty) {
if (dd.ty != '@')
line += '!' +dd.ty + n + '!'
else
line += '!@' + dd.x + ',' + dd.y + n + '!'
} else {
if (deco_l[n])
line += deco_l[n]
else
line += '!' + n + '!'
}
}
} // deco_dump
function dur_dump(dur, grace) {
var d = 0,
l = grace ? C.BLEN / 4 : ulen
if (dur == l)
|
| ︙ | ︙ | |||
388 389 390 391 392 393 394 |
w[nly++] = ""
}
if (nly == 0)
continue
for (s = voice_tb[v].sym; s; s = s.next) {
if (s.type != C.NOTE)
continue
| | < > | | | < | < < > | | < | < < | 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 |
w[nly++] = ""
}
if (nly == 0)
continue
for (s = voice_tb[v].sym; s; s = s.next) {
if (s.type != C.NOTE)
continue
if (!s.a_ly) {
for (i = 0; i < nly; i++)
w[i] += "*"
continue
}
for (i = 0; i < nly; i++) {
ly = s.a_ly[i]
if (!w[i])
w[i] = ""
if (!ly) {
w[i] += '*'
continue
}
t = ly.t
if (ly.ln) {
w[i] += t
if (ly.ln == 1)
w[i] += '-'
} else {
t = t.replace(/ /g, '~')
t = t.replace(/-/g, '\\-')
if (t.slice(-1) != "-")
t += ' '
w[i] += t
}
}
}
if (w.length != 0) {
if (voice_tb.length > 1)
abc2svg.print("V:" + voice_tb[v].id)
for (i = 0; i < w.length; i++)
|
| ︙ | ︙ | |||
445 446 447 448 449 450 451 |
if (s.a_meter[i].bot)
ln += '/' + s.a_meter[i].bot
}
return ln
} // meter_dump()
function note_dump(s, note, tie_ch) {
| | | < | < > > > > > > > > > > > > | | | | | | | < < < < < < < | 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 |
if (s.a_meter[i].bot)
ln += '/' + s.a_meter[i].bot
}
return ln
} // meter_dump()
function note_dump(s, note, tie_ch) {
var p, j, sl, s2, a, d
if (note.sls) {
for (j = 0; j < note.sls.length; j++) {
sl = note.sls[j];
slti_dump(sl.ty, '(');
s2 = sl.note.s
if (s2.sl2)
s2.sl2++
else
s2.sl2 = 1
}
}
if (note.a_dd)
deco_dump(note.a_dd)
if (note.color)
line += "!" + note.color + "!"
a = note.acc
if (typeof a == "object") {
d = a[1]
a = a[0]
if (a > 0) {
line += '^'
} else {
line += '_'
a = -a
}
dur_dump(C.BLEN / 4 * a / d, true)
} else {
switch (a) {
case -2: line += '__'; break
case -1: line += '_'; break
case 1: line += '^'; break
case 2: line += '^^'; break
case 3: line += '='; break
}
}
p = note.pit
if (p >= 23) {
line += "abcdefg"[p % 7]
if (p >= 30) {
line += "'"
if (p >= 37)
|
| ︙ | ︙ | |||
702 703 704 705 706 707 708 | } } } if (s.a_gch) gch_dump(s.a_gch) if (s.a_dd) deco_dump(s.a_dd) | < < < < < < < < < < < < < < < < < | | 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 |
}
}
}
if (s.a_gch)
gch_dump(s.a_gch)
if (s.a_dd)
deco_dump(s.a_dd)
if (s.color)
line += "!" + s.color + "!"
switch (s.type) {
case C.BAR:
if (s.beam_on)
line += "!beamon!"
if (s.bar_dotted)
line += '.';
line += s.bar_type
if (s.text) {
if (s.bar_type != '[')
line += '['
if (s.text[0] >= '0' && s.text[0] <= '9')
line += s.text + ' '
else
line += '"' + s.text + '"'
}
break
|
| ︙ | ︙ | |||
777 778 779 780 781 782 783 |
} else {
if (s.p_v.pos.stm != C.SL_BELOW) {
s.p_v.pos.stm = C.SL_BELOW
line += "[I:pos stem down]"
}
}
}
| < < < < < < < < < < < < < < < | | | 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
} else {
if (s.p_v.pos.stm != C.SL_BELOW) {
s.p_v.pos.stm = C.SL_BELOW
line += "[I:pos stem down]"
}
}
}
tie_ch = s.ti1
if (s.notes.length == 1) {
note_dump(s, s.notes[0], tie_ch)
} else {
for (i = 0; i < s.notes.length; i++) {
if (!s.notes[i].tie_ty) {
tie_ch = false
break
}
}
line += '['
for (i = 0; i < s.notes.length; i++)
note_dump(s, s.notes[i], tie_ch);
|
| ︙ | ︙ | |||
822 823 824 825 826 827 828 |
dur_dump(tmp, true)
} else {
tmp = s.notes[0].dur // head duration
if (s.trem2)
tmp /= 2;
dur_dump(tmp)
}
| | | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 |
dur_dump(tmp, true)
} else {
tmp = s.notes[0].dur // head duration
if (s.trem2)
tmp /= 2;
dur_dump(tmp)
}
if (tie_ch)
slti_dump(s.notes[0].tie_ty, '-');
tmp = s.sl2
while (tmp) {
line += ')';
tmp--
}
break
|
| ︙ | ︙ | |||
847 848 849 850 851 852 853 | cfmt.writefields += 'Q' } } tempo_dump(s) break case C.REST: line += s.invis ? 'x' : 'z'; | | | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | cfmt.writefields += 'Q' } } tempo_dump(s) break case C.REST: line += s.invis ? 'x' : 'z'; dur_dump(s.dur_orig) break case C.SPACE: line += 'y' if (s.width != 10) line += s.width break case C.STAVES: |
| ︙ | ︙ | |||
903 904 905 906 907 908 909 910 911 912 913 914 915 916 |
if (a)
abc2svg.print('%%writefields ' + a + " 0")
} // wf_dump()
font_dump()
abc2svg.print('\nX:' + info['X'])
header_dump("TC")
abc2svg.print(meter_dump(voice_tb[0].meter));
ulen = voice_tb[0].ulen < 0 ? C.BLEN / 4 : voice_tb[0].ulen;
abc2svg.print('L:1/' + (C.BLEN / ulen).toString());
| > > | 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
if (a)
abc2svg.print('%%writefields ' + a + " 0")
} // wf_dump()
font_dump()
abc2svg.print('\nX:' + info['X'])
if (cfmt["abc-version"] != cfmtg["abc-version"])
abc2svg.print("%%abc-version " + cfmt["abc-version"])
header_dump("TC")
abc2svg.print(meter_dump(voice_tb[0].meter));
ulen = voice_tb[0].ulen < 0 ? C.BLEN / 4 : voice_tb[0].ulen;
abc2svg.print('L:1/' + (C.BLEN / ulen).toString());
|
| ︙ | ︙ | |||
933 934 935 936 937 938 939 |
}
}
abc2svg.print(key_dump(voice_tb[0].key, voice_tb[0].clef))
// loop by time
for (s = tsfirst; s; s = s.ts_next) {
| > > > > > | > | | | | < < < < < < < < | 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 |
}
}
abc2svg.print(key_dump(voice_tb[0].key, voice_tb[0].clef))
// loop by time
for (s = tsfirst; s; s = s.ts_next) {
v = s.v
if (s.soln && s.seqst) {
vo[v] += '$'
voice_out()
}
if (s.part) { // new part
voice_out()
q = s.part
if (q.invis && cfmt.writefields.indexOf('P') >= 0) {
abc2svg.print("%%writefields P 0")
cfmt.writefields =
cfmt.writefields.replace('P', '')
} else if (!q.invis && cfmt.writefields.indexOf('P') < 0) {
abc2svg.print("%%writefields P 1")
cfmt.writefields += 'P'
}
font_def("parts", q.text)
abc2svg.print('P:' + q.text)
}
line = "";
// (all voices are synchronized on %%score)
if (s.type != C.STAVES && s.time > vti[v]) {
//fixme: put 'X' if more than one measure
if (s.time > vti[v] + 2) {
|
| ︙ | ︙ | |||
982 983 984 985 986 987 988 |
voice_out();
lyric_dump();
header_dump("W")
} // abc_dump()
// -- local functions
abc2svg.abc_init = function(args) {
| < < | < > > > > > > > | | 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 |
voice_out();
lyric_dump();
header_dump("W")
} // abc_dump()
// -- local functions
abc2svg.abc_init = function(args) {
abc2svg.args = args.join(' ')
}
abc2svg.abc_end = function() {
var t,
tunes = abc.tunes.slice(0) // get a copy of the generated tunes
t = abc.cfmt()["abc-version"]
if (t != "1")
abc2svg.print('%abc-' + t) // explicit ABC version
abc2svg.print('\
I:abc-creator abc2svg CLI "toabc.js ' + abc2svg.args + '"\n\
I:linebreak $')
if (user.errtxt)
abc2svg.print("\n--- Errors ---\n" + user.errtxt)
while (1) {
t = tunes.shift()
if (!t)
break
abc_dump(t[0], t[1], t[2], t[3])
}
}
abc2svg.abort = function(e) {
abc2svg.print(e.message + "\n*** Abort ***\n" + e.stack);
abc2svg.abc_end();
abc2svg.quit()
}
|
Changes to tohtml.js.
1 2 | // abc2svg - tohtml.js - HTML+SVG generation // | | | 1 2 3 4 5 6 7 8 9 10 | // abc2svg - tohtml.js - HTML+SVG generation // // Copyright (C) 2014-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. |
| ︙ | ︙ | |||
44 45 46 47 48 49 50 |
}
function get_date() {
return (new Date()).toUTCString()
} // get_date()
function header_footer(str) {
| | < < | < | < < | < < < < < < < < < < < < < | | | > | < | | | > > > > > > > > > > > > > > > > > > > > | 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 |
}
function get_date() {
return (new Date()).toUTCString()
} // get_date()
function header_footer(str) {
var c, d, i, t,
j = 0,
r = ["", "", ""]
if (str[0] == '"')
str = str.slice(1, -1)
while (1) {
i = str.indexOf('$', j)
if (i < 0)
break
c = str[++i]
switch (c) {
case 'd':
if (!abc2svg.get_mtime)
break // cannot know the modification date of the file
d = abc2svg.get_mtime(abc.parse.fname)
break
case 'D':
d = get_date()
break
case 'F':
d = abc.parse.fname
break
case 'I':
str = str.replace('$', '')
d = str[i]
case 'T':
t = abc.info()[c]
d = t ? t.split('\n', 1)[0] : ''
break
case 'P':
d = '\x0c' // form feed
break
case 'V':
d = "abc2svg-" + abc2svg.version
break
default:
d = ''
break
}
str = str.replace('$' + c, d)
j = i
}
str = str.split('\n')
for (j = 0; j < str.length; j++) {
if (j != 0)
for (i = 0; i < 3; i++)
r[i] += '<br>'
t = str[j].split('\t')
if (t.length == 1) {
r[1] += t[0]
} else {
for (i = 0; i < 3; i++) {
if (t[i])
r[i] += t[i]
}
}
}
return r
} // header_footer()
// set a paragraph style
function set_pstyle() {
|
| ︙ | ︙ | |||
148 149 150 151 152 153 154 |
// entry point from cmdline
abc2svg.abc_init = function() {
var cfmt = abc.cfmt()
// output a header or footer
function gen_hf(type, str) {
| | | | > > > | | | | > | | | < | | | | > > > | | | | > > > > > | | | < > | | < < | | > | | | | > > > > > > > > > > > < | > | > > > > > > | 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 |
// entry point from cmdline
abc2svg.abc_init = function() {
var cfmt = abc.cfmt()
// output a header or footer
function gen_hf(type, str) {
var i, page,
lcr = ["l", "c", "r"],
//fixme: handle font changes?
a = header_footer(clean_txt(str))
abc2svg.print('<table class="' + type + '" width="100%"><tr>')
for (i = 0; i < 3; i++) {
str = a[i]
if (!str)
str = ' '
//fixme
if (str.indexOf('\x0c') >= 0) {
str = str.replace('\x0c', '')
page = " page"
} else {
page = ''
}
abc2svg.print('<td class="' + lcr[i] + page +
'" width="33%">' +
str + '</td>')
}
abc2svg.print('</table>')
}
user.page_format = true
// output the html header
user.img_out = function(str) {
var header = cfmt.header,
footer = cfmt.footer,
topmargin = cfmt.topmargin || "1cm",
botmargin = cfmt.botmargin || "1cm",
media_s = '@media print {\n\
body {margin:0; padding:0; border:0}\n\
.newpage {page-break-before: always}\n\
div.nobrk {page-break-inside: avoid}\n\
}',
media_f = '@media screen {\n\
.header, .footer, .h-sp, .f-sp {display: none}\n\
}\n\
@media print {\n\
body {margin:0; padding:0; border:0;\n\
counter-reset: page;\n\
counter-increment: page; }\n\
.newpage {page-break-before: always}\n\
div.nobrk {page-break-inside: avoid}\n\
.header {\n\
position: fixed;\n\
top: ' + cfmt.headerfont.size + 'px;\n\
height: ' + (cfmt.headerfont.size * 2) + 'px;\n\
' + abc.style_font(cfmt.headerfont) + ';\n\
left: ' + cfmt.leftmargin.toFixed(1) + 'px;\n\
width: ' + (cfmt.pagewidth - cfmt.leftmargin
- cfmt.rightmargin).toFixed(1) + 'px\n\
}\n\
.footer {\n\
position: fixed;\n\
bottom: 0;\n\
height: ' + (cfmt.footerfont.size * 2) + 'px;\n\
' + abc.style_font(cfmt.footerfont) + ';\n\
left: ' + cfmt.leftmargin.toFixed(1) + 'px;\n\
width: ' + (cfmt.pagewidth - cfmt.leftmargin
- cfmt.rightmargin).toFixed(1) + 'px\n\
}\n\
.h-sp, .f-sp {height: '
+ (cfmt.headerfont.size * 2) + 'px}\n\
div.page:after {\n\
counter-increment: page;\n\
content: counter(page);\n\
}\n\
.l {text-align: left}\n\
.c {text-align: center}\n\
.r {text-align: right}\n\
}';
// no margin / header / footer when SVG page formatting
if (abc.page)
topmargin = botmargin = header = footer = 0
abc2svg.print('<!DOCTYPE html>\n\
<html>\n\
<meta charset="utf-8"/>\n\
<meta name="generator" content="abc2svg-' + abc2svg.version + '"/>\n\
<!-- CreationDate: ' + get_date() + '-->\n\
<style>\n\
body {width:' + cfmt.pagewidth.toFixed(0) +'px}\n\
svg {display:block}\n\
p {' + set_pstyle() + 'margin-top:0}\n\
p span {line-height:' + ((cfmt.lineskipfac * 100) | 0).toString() + '%}\n' +
((header || footer) ? media_f : media_s))
// important for chrome and --headless (abctopdf)
if (abc.page)
abc2svg.print('@page{size:' +
(cfmt.pagewidth / 96).toFixed(2) + 'in ' +
(cfmt.pageheight / 96).toFixed(2) + 'in;margin:0}')
abc2svg.print('</style>\n\
<title> ' + abc.parse.fname.replace(/.*\//, '')
+ '</title>\n\
<body>')
if (header || footer) {
if (header)
gen_hf("header", header)
if (footer)
gen_hf("footer", footer)
abc2svg.print('\
<table style="margin:0">\n\
<thead><tr><td>\n\
<div class="h-sp"> </div>\n\
</td></tr></thead>\n\
<tbody><tr><td>')
init_done = 2 // with header/footer
} else {
init_done = 1
}
// output the first generated string
abc2svg.print(str)
// change the output function
user.img_out = abc2svg.print
}
}
abc2svg.abc_end = function() {
var font_style = abc.get_font_style()
if (!init_done) // if empty document
user.img_out('')
if (user.errtxt)
abc2svg.print("<pre>" + clean_txt(user.errtxt) + "</pre>")
if (font_style) // if some %%text at the end
abc2svg.print('<style>\n' + font_style + '\n</style>')
if (init_done == 2) // if with header/footer
abc2svg.print('\
</td></tr></tbody>\n\
<tfoot><tr><td>\n\
<div class="f-sp"> </div>\n\
</td></tr></tfoot>\n\
</table>')
abc2svg.print('</html>')
}
|
Changes to tomei.js.
| ︙ | ︙ | |||
467 468 469 470 471 472 473 |
ln += ' dis="8" dis.place="' +
(s.clef_octave > 0 ? 'above"' : 'below"')
abc2svg.print(ln + '/>')
} // clef_dump()
// dump a duration
function dur_dump(dur, nflags) {
| | < < < < < | < | | < | | 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 |
ln += ' dis="8" dis.place="' +
(s.clef_octave > 0 ? 'above"' : 'below"')
abc2svg.print(ln + '/>')
} // clef_dump()
// dump a duration
function dur_dump(dur, nflags) {
var t = (dur / 12) | 0,
d = ' dur="'
for (nflags = 5; t; t >>= 1, nflags--) {
if (t & 1)
break
}
if (nflags == -4)
d += "long"
else if (nflags == -3)
d += "breve"
else
d += (1 << (nflags + 2)).toString()
switch (t) {
case 3: d += '" dots="1'; break
case 7: d += '" dots="2'; break
case 15: d += '" dots="3'; break
}
return d + '"'
} // dur_dump()
function gch_dump(s) {
new_ref(s)
var i, gch, t
|
| ︙ | ︙ |
Added tonotes.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
// abc2svg - tonotes.js - convert ABC to a list of MIDI notes
//
// Copyright (C) 2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// This abc2svg backend script outputs a list of the notes
// as they could be played.
//
// Usage:
// (abc2svg batch) tonotes.js ABC_files
//
// The result goes to stdout, one note per line, format:
//
// <time> <MIDI_instrument> <MIDI_pitch> <duration> <voice_number>
// with TAB as the field separator.
// The number after the dot in the voice number indicates a voice overlay.
//
// The time and the durations are in 1/100s.
// Lines starting with '#' are comments.
// don't load tohtml.js
abc2svg.abc_init = function(args) {
}
// but load the sound generator
abc2svg.loadjs('util/sndgen.js')
abc2svg.abc_end = function() {
function pit(v) {
if (v - (v | 0))
return v.toFixed(2)
return v.toString()
} // pit()
var e, t, vn,
audio = ToAudio(), // (in sndgen.js)
po = { // play object
conf: { // configuration
speed: 1
},
tgen: 3600, // generate by (for) 1 hour
get_time: function() { return -.3}, // (move the time origin)
midi_ctrl: function(po, s, t) { },
note_run: function(po, s, k, t, d) {
abc2svg.print(' '+ (t * 100).toFixed(0) +
'\t' + s.instr +
'\t' + pit(k) +
'\t' + (d * 100).toFixed(0) +
'\t' + vn[s.p_v.id])
} // note_run()
},
tunes = abc.tunes.slice(0) // get a copy of the generated tunes
// define the voice numbers
function dvn(v_tb) {
var i, n, p_v,
v = 0
vn = {}
while (1) {
p_v = v_tb[v]
if (!p_v)
break
if (vn[p_v.id]) {
v++
continue
}
vn[p_v.id] = v.toString()
n = 1
while (1) {
p_v = p_v.voice_down
if (!p_v)
break
vn[p_v.id] = v.toString() + '.' + n.toString()
n++
}
v++
}
} //dvn()
// ---- abc_end() body ----
if (user.errtxt)
abc2svg.printErr("\n--- Errors ---\n" + user.errtxt)
abc2svg.print('# MIDI flow (time and duration in 1/100s)\n\
# time instr pitch duration voice')
// loop on the tunes and
while (1) {
e = tunes.shift()
if (!e)
break
audio.add(e[0], e[1], e[3]) // generate the music
dvn(e[1])
t = (e[2].T || '(no title)').replace(/\n/g, ' / ')
abc2svg.print('# ------- tune ' +
e[2].X + '. ' +
t +
' -------')
po.stop = false
po.s_end = null
po.s_cur = e[0] // first music symbol
po.repn = false
po.repv = 0
abc2svg.play_next(po)
}
} // abc_end()
abc2svg.abort = function(e) {
abc2svg.print(e.message + "\n*** Abort ***\n" + e.stack)
abc2svg.abc_end()
abc2svg.quit()
}
|
Changes to util/abcdoc.js.
1 2 3 | //#javascript // abcdoc-1.js file to include in html pages with abc2svg-1.js // | | | | | | 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 |
//#javascript
// abcdoc-1.js file to include in html pages with abc2svg-1.js
//
// Copyright (C) 2014-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
var user
(function(){
window.onerror = function(msg, url, line) {
|
| ︙ | ︙ | |||
84 85 86 87 88 89 90 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
// search the ABC tunes and add their rendering as SVG images
function render() {
| | < < | > > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
alert('error loading ' + fn)
}
document.head.appendChild(s)
}
// search the ABC tunes and add their rendering as SVG images
function render() {
var i = 0, j, k, res, re,
re_stop = /\n<|\n%.begin/g, // stop on "<" and skip "%%begin"
abc = new abc2svg.Abc(user);
// get the ABC insertion mode
if (page.indexOf('<script type="text/vnd.abc"') >= 0)
re = /<script type="text\/vnd.abc"/g
else
re = /\n%abc|\nX:/g
abc.tosvg('abcdoc', '%%bgcolor white\n\
%%rightmargin 0.8cm\n\
%%leftmargin 0.8cm\n\
%%topspace 0')
for (;;) {
|
| ︙ | ︙ |
Changes to util/abcweb.js.
|
| < | | | | | | > > | > > > < | | 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 |
// abcweb-1.js file to include in html pages
//
// Copyright (C) 2014-2022 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// This script is used in HTML or XHTML files.
// It replaces the ABC sequences
// - contained in <script> elements with the type "text/vnd.abc", or
// - defined in HTML elements with the class "abc", or
// - starting with "%abc-n" or "X:n" at start of line up to a XML tag
// by music as SVG images.
// The other elements stay in place.
// The script abc2svg-1.js may be loaded before this script.
// It is automatically loaded when not present.
//
// When the file is .html, if the ABC sequence is contained inside
// elements <script type="text/vnd.abc">, there is no constraint
// about the ABC characters. Note that the <script> tag is removed.
// With a container of class "abc", the characters '<', '>' and '&' may be
// replaced by their XML counterparts ('<', '>' and '&').
// When the file is .xhtml, if the ABC sequence contains the characters
// '<', '>' or '&', this sequence must be enclosed in a XML comment
// (%<!-- .. %-->) or in a CDATA (%<![CDATA[ .. %]]>).
//
// ABC parameters may be defined in the query string of the URL.
window.onerror = function(msg, url, line) {
if (typeof msg == 'string')
alert("window error: " + msg +
"\nURL: " + url +
"\nLine: " + line)
else if (typeof msg == 'object')
alert("window error: " + msg.type + ' ' + msg.target.src)
else
alert("window error: " + msg)
return false
}
var user,
abcplay
if (typeof abc2svg == "undefined")
var abc2svg = {}
// function called when abc2svg is fully loaded
function dom_loaded() {
var abc, src,
a_inc = {},
new_page = '',
errtxt = '',
html, // set if some pure HTML in the file
app = "abcweb",
glopar = '', // global parameters from URL
playing,
playconf = {
onend: function() {
playing = false
}
},
page, // document source
tune_lst = [], // array of [tsfirst, voice_tb, info, cfmt] per tune
jsdir = document.currentScript ?
document.currentScript.src.match(/.*\//) :
(function() {
var s_a = document.getElementsByTagName('script')
for (var k = 0; k < s_a.length; k++) {
if (s_a[k].src.indexOf(app) >= 0)
return s_a[k].src.match(/.*\//) || ''
|
| ︙ | ︙ | |||
133 134 135 136 137 138 139 | return } if (abc.cfmt().soundfont) playconf.sfu = abc.cfmt().soundfont abcplay = AbcPlay(playconf); } | | | | | < | | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
return
}
if (abc.cfmt().soundfont)
playconf.sfu = abc.cfmt().soundfont
abcplay = AbcPlay(playconf);
}
// if not done yet,
// generate the play data of the tune
if (!tune_lst[i]) {
tune_lst[i] = abc.tunes[i]
abcplay.add(tune_lst[i][0],
tune_lst[i][1],
tune_lst[i][3])
}
// check if click on a music symbol
// (this works when 'follow' is active)
s = tune_lst[i][0] // first symbol of the tune
i = e.getAttribute('class')
if (i)
|
| ︙ | ︙ | |||
202 203 204 205 206 207 208 | //search in page // 1- <script type="text/vnd.abc"> ..ABC.. <script> // 2- <anytag .. class="abc" .. > ..ABC.. </anytag> // 3- %abc-n ..ABC.. '<' with skip %%beginxxx .. %%endxxx // 4- X:n ..ABC.. '<' with skip %%beginxxx .. %%endxxx | > | < < < < < | < < | < < < | < < < < < < < < | < < < | > | > > > | > | < < > | > > | | < < | | | > | > | | | | < | | < | < | | | | | | | > > > > > > > | | | | < | | > | < | < < < < | > | < | | | | | < > > > | < | < | < | | | | | | | | | | | > > > > > | > | > > > > | > | 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 |
//search in page
// 1- <script type="text/vnd.abc"> ..ABC.. <script>
// 2- <anytag .. class="abc" .. > ..ABC.. </anytag>
// 3- %abc-n ..ABC.. '<' with skip %%beginxxx .. %%endxxx
// 4- X:n ..ABC.. '<' with skip %%beginxxx .. %%endxxx
var re, src, res,
ss = 0,
re_stop = /\n<|\n%.begin[^\s]+/g
// extract a music sequence
// @re is the regular expression starting a music sequence
function extract() {
var i, j, k, t
res = re.exec(page)
if (!res) {
// alert about bad print
if (abc2svg.page && html) {
new_page += '\
<pre class="nop" style="background:#ff8080">\
Printing may be bad because the file contains pure HTML and %%pageheight\
</pre>\n'
errtxt = ""
}
document.body.innerHTML = new_page // browser page update
+ page.slice(ss) // HTML end
window.onclick = abc2svg.playseq // prepare for play on click
return // done
}
i = re.lastIndex - res[0].length // start of music sequence
if (i > ss) {
new_page += page.slice(ss, i) // HTML copy
html = 1
}
t = res[2]
if (t[0] == '<') {
t = t.slice(1, 4)
switch (t) {
case "scr": // <script
i = page.indexOf('>', i)
i = page.indexOf('\n', i) + 1
j = page.indexOf('</script>', i)
ss = j + 10
break
default: // < .. class="abc"
j = i
i = res[2].index(' ', i) // get the tag
t = res[2].slice(1, i)
i = page.indexOf('>', j)
i = page.indexOf('\n', i) + 1
new_page += page.slice(j, i) // keep the element
j = page.indexOf('</' + t + '>', i)
ss = j + t.length + 4
break
}
} else { // %abc or X:
// get the end of the ABC sequence
// including the %%beginxxx/%%endxxx sequences
re_stop.lastIndex = i
while (1) {
res = re_stop.exec(page)
if (!res || res[0] == "\n<")
break
k = page.indexOf(res[0].replace("begin", "end"),
re_stop.lastIndex)
if (k < 0)
break
re_stop.lastIndex = k
}
if (!res || k < 0)
j = page.length
else
j = re_stop.lastIndex - 1
ss = j
}
if (j < 0) {
//fixme error
console.log('error i/j '+i+' '+j)
return
}
re.lastIndex = ss // new HTML start
// src = page.slice(i, j) // music sequence
// if (abc2svg.modules.load(src, render1))
// render1()
// } // extract()
// render one text music sequence
// @page is the content of the page
// @ss and @se are the start and end indexes of the music sequence
// i,j are the start and stop of the music inside the page source
// function render1() {
abc.tosvg(app, page, i, j)
abc2svg.abc_end() // close the page if %%pageheight
if (errtxt) {
new_page += '<pre class="nop" style="background:#ff8080">'
+ errtxt + "</pre>\n"
errtxt = ""
}
// try the next sequence
extract()
} // render1()
// get the ABC insertion mode
if (/<script[^t>]*type="text\/vnd.abc"/.test(page))
re = '<script[^t>]*type="text\/vnd.abc"'
else if (/<[^>]* class="[^"]*abc[^"]*/.test(page)) // "
re = '<[^>]* class="[^"]*abc[^"]*'
else
re = '%abc-\\d|X:\\s*\\d'
re = new RegExp('(^|\n)(' + re + ')', 'g')
// prepare the generation of the music sequences
abc = new abc2svg.Abc(user)
if (typeof follow == "function") // initialize the play follow function
follow(abc, user, playconf)
abc.tosvg(app, glopar)
extract() // start
} // render()
// load the %%abc-include files
function include() {
var i, j, fn, r,
k = 0
|
| ︙ | ︙ | |||
374 375 376 377 378 379 380 | include() } r.send() } // include() // --- dom_loaded() main code --- | < < < | > > > > > > > > > > > > > > > > > > | | 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 |
include()
}
r.send()
} // include()
// --- dom_loaded() main code ---
// load the abc2svg core if not done by <script>
if (!abc2svg.Abc) {
abc2svg.loadjs(document.body.innerHTML.indexOf("<mei ") >= 0 ?
"mei2svg-1.js" :
"abc2svg-1.js",
dom_loaded)
return
}
window.removeEventListener("load", dom_loaded)
// use the query string of the URL for global parameters
{
var i, j,
k = location.search.substr(1).split("&")
for (i = 0; i < k.length; i++) {
j = k[i].split('=')
if (j[0])
glopar += "%%" + j[0] + " "
+ decodeURIComponent(j[1]) + '\n'
}
}
// accept page formatting
abc2svg.abc_end = function() {}
// load the included files if any
page = document.body.innerHTML // initial page
// load the required modules and the include files before rendering
if (abc2svg.modules.load(page, include))
include()
} // dom_loaded()
// wait for the scripts to be loaded
window.addEventListener("load", dom_loaded)
|
Changes to util/abcweb1.js.
|
| < > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < | 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 |
// abcweb1-1.js file to include in html pages with abc2svg-1.js
//
// Copyright (C) 2019-2021 Jean-Francois Moine
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
//
// This script either:
// - builds a list of the tunes when there is no selection or
// - displays the selected tune.
//
// When the tune is displayed, if playing is not enabled,
// scrolling the music may be done by clicking/taping
// on the 'start scrolling' button.
//
// The header of the tune list ("Tunes:") may be set in a global
// javascript variable 'list_head'.
// The tail of the tune list ("(all tunes)") may be set in a global
// javascript variable 'list_tail'.
window.onerror = function(msg, url, line) {
if (typeof msg == 'string')
alert("window error: " + msg +
"\nURL: " + url +
"\nLine: " + line)
else if (typeof msg == 'object')
|
| ︙ | ︙ | |||
76 77 78 79 80 81 82 |
errtxt = '',
app = "abcweb1",
playconf = { // play arguments
onend: function() {
playing = false
}
},
| | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
errtxt = '',
app = "abcweb1",
playconf = { // play arguments
onend: function() {
playing = false
}
},
tune_lst, // array of [tsfirst, voice_tb, info, cfmt] per tune
jsdir = document.currentScript ?
document.currentScript.src.match(/.*\//) :
(function() {
var s_a = document.getElementsByTagName('script')
for (var k = 0; k < s_a.length; k++) {
if (s_a[k].src.indexOf(app) >= 0)
return s_a[k].src.match(/.*\//) || ''
|
| ︙ | ︙ | |||
194 195 196 197 198 199 200 |
page = document.getElementById('ta').value
abc2svg.get_sel()
} // src_upd()
abc2svg.src_edit = function() {
// offer a textarea with the ABC source and 2 buttons
document.body.innerHTML = '\
| | > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
page = document.getElementById('ta').value
abc2svg.get_sel()
} // src_upd()
abc2svg.src_edit = function() {
// offer a textarea with the ABC source and 2 buttons
document.body.innerHTML = '\
<textarea id="ta" rows="50" cols="80" style="overflow:scroll">'
+ page + '</textarea>\
<br/>\
<a href="#" onclick="abc2svg.src_upd()"> Apply </a> - \
<a href="#" onclick="abc2svg.get_sel()"> Cancel </a>'
} // src_edit()
// start/stop scrolling when no play
abc2svg.st_scroll = function() {
|
| ︙ | ︙ | |||
234 235 236 237 238 239 240 |
abc2svg.get_sel = function() {
var j, k,
n = 0,
i = 0,
t = (typeof list_head == "undefined" ? "Tunes:" : list_head) + '<ul>\n'
tt = typeof list_tail == "undefined" ? "(all tunes)" : list_tail
| < < | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
abc2svg.get_sel = function() {
var j, k,
n = 0,
i = 0,
t = (typeof list_head == "undefined" ? "Tunes:" : list_head) + '<ul>\n'
tt = typeof list_tail == "undefined" ? "(all tunes)" : list_tail
for (;;) {
i = page.indexOf("\nX:", i)
if (i < 0)
break
k = page.indexOf("\n", ++i)
j = page.indexOf("\nT:", i)
n++
|
| ︙ | ︙ | |||
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
abc2svg.do_render = function(select) {
// aweful hack: user.anno_stop must be defined before Abc creation
// for being set later by follow() !
if (typeof follow == "function")
user.anno_stop = function(){}
abc = new abc2svg.Abc(user)
new_page = ""
// initialize the play follow function
if (typeof follow == "function")
follow(abc, user, playconf)
| > | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
abc2svg.do_render = function(select) {
// aweful hack: user.anno_stop must be defined before Abc creation
// for being set later by follow() !
if (typeof follow == "function")
user.anno_stop = function(){}
tune_lst = []
abc = new abc2svg.Abc(user)
new_page = ""
// initialize the play follow function
if (typeof follow == "function")
follow(abc, user, playconf)
|
| ︙ | ︙ | |||
420 421 422 423 424 425 426 |
abc2svg.loadjs("abc2svg-1.js", dom_loaded)
return
}
// get the page content
page = fix_abc(document.body.innerHTML)
| | | < < | > > > > > > > < < < < | < < < < < < | > < < | 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 |
abc2svg.loadjs("abc2svg-1.js", dom_loaded)
return
}
// get the page content
page = fix_abc(document.body.innerHTML)
// mouse/tap events
window.onclick = function(evt) {
if (playing) { // stop playing
abcplay.stop()
return
}
var e, s, j,
c = evt.target
// remove the menu if active
e = document.getElementById("dc")
if (e && e.classList.contains("show")) {
e.classList.remove("show") // remove the menu
return
}
// search if click in a SVG image
e = c // keep the clicked element
while (c && c.tagName != 'svg')
c = c.parentNode
if (!c)
return
c = c.getAttribute('class')
// if click in the menu button, show the menu
if (c == "db") {
e = document.getElementById("dc")
e.classList.toggle("show")
return
}
//play stuff
|
| ︙ | ︙ | |||
476 477 478 479 480 481 482 | // get the clicked tune c = c.match(/tune(\d+)/) if (!c) return c = c[1] // tune number | | | | | < | | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
// get the clicked tune
c = c.match(/tune(\d+)/)
if (!c)
return
c = c[1] // tune number
// if not done yet,
// generate the play data of the tune
if (!tune_lst[c]) {
tune_lst[c] = abc.tunes[c]
abcplay.add(tune_lst[c][0],
tune_lst[c][1],
tune_lst[c][3])
}
// start playing from the clicked symbol
// (this works when 'follow' is active)
// or from the start of the tune
s = tune_lst[c][0] // first symbol of the tune
c = e.getAttribute('class')
|
| ︙ | ︙ | |||
505 506 507 508 509 510 511 |
alert("play bug: no such symbol in the tune")
return
}
}
playing = true
abcplay.play(s, null)
| | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
alert("play bug: no such symbol in the tune")
return
}
}
playing = true
abcplay.play(s, null)
} // onclick()
// accept page formatting
abc2svg.abc_end = function() {}
// load the required modules, then render the music
if (abc2svg.modules.load(page, include))
include()
} // dom_loaded()
// wait for the scripts to be loaded
window.addEventListener("load", dom_loaded)
|
Changes to util/chord.js.
1 2 | // chord.js - generation of accompaniment // | | | | | | | | 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 |
// chord.js - generation of accompaniment
//
// Copyright (C) 2020-2021 Jean-Francois Moine and Seymour Shlien
//
// This file is part of abc2svg.
//
// abc2svg is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// abc2svg is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with abc2svg. If not, see <http://www.gnu.org/licenses/>.
// -- chord table --
// index = chord symbol type
// value: array of strings
// index = inversion
// string = list of 2 characters
// 1st character = note (see abc2svg.letmid)
// 2nd character = octave ('+', ' ', '-')
abc2svg.ch_names = {
'': ["C-E G C+", "E-C G C+", "G-C E G "],
m: ["C-e G C+", "e-C G C+", "G-C e G "],
'7': ["C-b-E G ", "E-C G b ", "G-E b C+", "b-E G C+"],
m7: ["C-b-e G ", "e-C G b ", "G-e b C+", "b-e G C+"],
m7b5: ["C-b-e g ", "e-C g b ", "g-e b C+", "b-e g C+"],
M7: ["C-B-E G ", "E-C G B ", "G-E B C+", "B-E G C+"],
'6': ["C-A-E G ", "E-C A B ", "A-E B C+", "B-E A C+"],
|
| ︙ | ︙ | |||
46 47 48 49 50 51 52 | "D-G-C E b F+", "F-D-G-C E b D+"], dim9: ["C-A-e g d+", "e-C g A d+", "g-C e A d+", "A-C e g d+", "D-g-C e A "], sus4: ["C-F G C+", "F-C G C+", "G-C F G "], sus9: ["C-D G C+", "D-C G C+", "G-C D G "], '7sus4': ["C-b-F G ", "F-C G b ", "G-F b C+", "b-C F G "], '7sus9': ["C-b-D G ", "D-C G b ", "G-D b C+", "b-C D G "], '5': ["C-G C+", "G-G C+"] | | | | 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 |
"D-G-C E b F+", "F-D-G-C E b D+"],
dim9: ["C-A-e g d+", "e-C g A d+", "g-C e A d+", "A-C e g d+", "D-g-C e A "],
sus4: ["C-F G C+", "F-C G C+", "G-C F G "],
sus9: ["C-D G C+", "D-C G C+", "G-C D G "],
'7sus4': ["C-b-F G ", "F-C G b ", "G-F b C+", "b-C F G "],
'7sus9': ["C-b-D G ", "D-C G b ", "G-D b C+", "b-C D G "],
'5': ["C-G C+", "G-G C+"]
} // ch_names
abc2svg.midlet = "CdDeEFgGaAbB" // MIDI pitch -> letter
abc2svg.letmid = { // letter -> MIDI pitch
C: 0,
d: 1,
D: 2,
e: 3,
E: 4,
F: 5,
g: 6,
G: 7,
a: 8,
A: 9,
b: 10,
B: 11
} // letmid
abc2svg.chord = function(first, // first symbol in time
voice_tb, // table of the voices
cfmt) { // tune parameters
var chnm, i, k, vch, s, gchon,
C = abc2svg.C,
trans = 48 + (cfmt.chord.trans ? cfmt.chord.trans * 12 : 0)
|
| ︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 | case '+': v += 12; break case '-': v -= 12; break } r.push(v) } return r } // chcr() // generate a chord | > > > > > > > > > > > > > | | < | > | | 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 |
case '+': v += 12; break
case '-': v -= 12; break
}
r.push(v)
}
return r
} // chcr()
// (quite the same as abc2svg.cs_filter() but with otext)
function filter(a_cs, sel) {
var i, cs,
tcs = ""
for (i = 0; i < a_cs.length; i++) {
cs = a_cs[i]
if (cs.type == 'g')
tcs += cs.otext
}
return tcs.replace(sel ? abc2svg.cs_sel1 : abc2svg.cs_sel0, '')
} // filter()
// generate a chord
function gench(sb) {
var r, ch, b, m, n, not,
a = filter(sb.a_gch, cfmt.altchord).
match(/([A-G])([#♯b♭]?)([^/]*)\/?(.*)/),
// a[1] = note, a[2] = acc, a[3] = type, a[4] = bass
s = {
v: vch.v,
p_v: vch,
type: C.NOTE,
time: sb.time,
notes: []
}
if (!a)
return
r = abc2svg.letmid[a[1]] // root
if (r == undefined) {
if (a[1] != "N")
return
s.type = C.REST // ("N") = no chord
ch = [0]
r = 0
} else {
|
| ︙ | ︙ | |||
177 178 179 180 181 182 183 |
vch.last_sym = s
} // gench()
// -- chord() --
// set the chordnames defined by %%MIDI chordname
if (cfmt.chord.names) {
| | | | | 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 |
vch.last_sym = s
} // gench()
// -- chord() --
// set the chordnames defined by %%MIDI chordname
if (cfmt.chord.names) {
chnm = Object.create(abc2svg.ch_names)
for (k in cfmt.chord.names) {
vch = ""
for (i = 0; i < cfmt.chord.names[k].length; i++) {
s = cfmt.chord.names[k][i]
vch += abc2svg.midlet[s % 12]
vch += i == 0 ? "-" :
(s >= 12 ? "+" : " ")
}
//fixme: no inversion
chnm[k] = [ vch ]
}
} else {
chnm = abc2svg.ch_names
}
// create the chord voice
vch = {
v: voice_tb.length,
id: "_chord",
time: 0,
sym: { // dummy symbol to simplify chord insersion
type: C.REST,
time: 0
},
instr: cfmt.chord.prog || 0,
vol: cfmt.chord.vol || .7
}
vch.last_sym = vch.sym
voice_tb.push(vch)
// define the MIDI channel
k = 0
for (i = 0; i < vch.v; i++) {
|
| ︙ | ︙ | |||
243 244 245 246 247 248 249 |
if (!gchon)
continue
for (i = 0; i < s.a_gch.length; i++) {
gch = s.a_gch[i]
if (gch.type != 'g')
continue
vch.last_sym.dur = s.time - vch.last_sym.time
| | | 256 257 258 259 260 261 262 263 264 265 266 267 |
if (!gchon)
continue
for (i = 0; i < s.a_gch.length; i++) {
gch = s.a_gch[i]
if (gch.type != 'g')
continue
vch.last_sym.dur = s.time - vch.last_sym.time
gench(s)
break
}
}
} // chord()
|
Changes to util/play.js.
1 2 3 4 5 6 7 | // snd-1.js - file to include in html pages with abc2svg-1.js for playing // // Copyright (C) 2015-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // snd-1.js - file to include in html pages with abc2svg-1.js for playing // // Copyright (C) 2015-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // This file is a wrapper around // - ToAudio (sndgen.js): generate the play data // - Audio5 (sndaud.js): play with HTML5 audio API and SF2 // - Midi5 (sndmid.js): play with HTML5 MIDI api // old version: |
| ︙ | ︙ |
Changes to util/sndaud.js.
1 2 3 4 5 6 7 | // sndaud.js - audio output using HTML5 audio // // Copyright (C) 2019-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // sndaud.js - audio output using HTML5 audio // // Copyright (C) 2019-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // Audio5 creation // @conf: configuration object - all items are optional: // ac: audio context - (default: created on play start) // sfu: soundfont URL (sf2 base64 encoded - default: "Scc1t2") |
| ︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
function Audio5(i_conf) {
var po, // play object
conf = i_conf, // configuration
empty = function() {},
errmsg,
ac, // audio context
gain, // global gain
// instruments/notes
parser, // SF2 parser
presets, // array of presets
instr = [], // [voice] bank + instrument
params = [], // [instr][key] note parameters per instrument
rates = [], // [instr][key] playback rates
| > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
function Audio5(i_conf) {
var po, // play object
conf = i_conf, // configuration
empty = function() {},
errmsg,
ac, // audio context
gain, // global gain
model, // device model (for iPad|iPhone|iPod)
// instruments/notes
parser, // SF2 parser
presets, // array of presets
instr = [], // [voice] bank + instrument
params = [], // [instr][key] note parameters per instrument
rates = [], // [instr][key] playback rates
|
| ︙ | ︙ | |||
155 156 157 158 159 160 161 |
return {
// name: instrument[i].instrumentName,
info: info
}
} // get_instr()
// sf2_create
| | | | > > > > > > > | | | | | | | > > | > | < < < < < | | | | | < < | | > | | 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 |
return {
// name: instrument[i].instrumentName,
info: info
}
} // get_instr()
// sf2_create
var i, j, k, sid, gen, parm, gparm, sample, infos,
sampleRate, scale,
b = instr >> 7, // bank
p = instr % 128, // preset
pr = presets
rates[instr] = []
// search the bank:preset
for (i = 0; i < pr.length; i++) {
gen = pr[i].header
if (gen.preset == p
&& gen.bank == b)
break
}
pr = pr[i]
if (!pr) {
errmsg('unknown instrument ' + b + ':' + p)
return // unknown preset!
}
pr = pr.info // list of gen/mod
for (k = 0; k < pr.length; k++) {
if (!pr[k].generator.instrument)
continue
gparm = null
infos = get_instr(pr[k].generator.instrument.amount).info
for (i = 0; i < infos.length; i++) {
gen = infos[i].generator
if (!gparm) {
parm = gparm = { // default parameters
attack: .001,
hold: .001,
decay: .001,
sustain: 0
// release: .001
}
} else {
parm = Object.create(gparm) // new parameters
if (!gen.sampleID)
gparm = parm // global para,eters
}
if (gen.attackVolEnv)
parm.attack = Math.pow(2,
gen.attackVolEnv.amount / 1200)
if (gen.holdVolEnv)
parm.hold = Math.pow(2,
gen.holdVolEnv.amount / 1200)
if (gen.decayVolEnv)
parm.decay = Math.pow(2,
gen.decayVolEnv.amount / 1200) / 3
if (gen.sustainVolEnv)
parm.sustain = gen.sustainVolEnv.amount / 1000
// if (gen.releaseVolEnv)
// parm.release = Math.pow(2,
// gen.releaseVolEnv.amount / 1200)
if (gen.sampleModes && gen.sampleModes.amount & 1)
parm.sm = 1
if (!gen.sampleID) // (empty generator!)
continue
sid = gen.sampleID.amount
sampleRate = parser.sampleHeader[sid].sampleRate
sample = parser.sample[sid]
parm.buffer = ac.createBuffer(1,
sample.length,
sampleRate)
parm.hold += parm.attack
parm.decay += parm.hold
// sustain > 40dB is not audible
if (parm.sustain >= .4)
parm.sustain = 0.01 // must not be null
else
parm.sustain = 1 - parm.sustain / .4
sample_cp(parm.buffer, sample)
if (parm.sm) {
parm.loopStart = parser.sampleHeader[sid].startLoop /
sampleRate
parm.loopEnd = parser.sampleHeader[sid].endLoop /
sampleRate
}
// define the notes
|
| ︙ | ︙ | |||
378 379 380 381 382 383 384 |
// @s = symbol
// @key = MIDI key + detune
// @t = audio start time
// @d = duration adjusted for speed
function note_run(po, s, key, t, d) {
var g, st,
instr = s.instr,
| | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
// @s = symbol
// @key = MIDI key + detune
// @t = audio start time
// @d = duration adjusted for speed
function note_run(po, s, key, t, d) {
var g, st,
instr = s.instr,
k = key | 0,
parm = po.params[instr][k],
o = po.ac.createBufferSource(),
v = s.p_v.vol == undefined ? 1 : s.p_v.vol // volume (gain)
if (!v // mute voice
|| !parm) // if the instrument could not be loaded
return // or if it has not this key
|
| ︙ | ︙ | |||
443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
// Audio5 function
init_b64d() // initialize base64 decoding
if (!conf.sfu)
conf.sfu = "Scc1t2" // set the default soundfont location
// public methods
return {
// get outputs
get_outputs: function() {
return (window.AudioContext || window.webkitAudioContext) ?
['sf2'] : null
| > > > > > > > > > > | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
// Audio5 function
init_b64d() // initialize base64 decoding
if (!conf.sfu)
conf.sfu = "Scc1t2" // set the default soundfont location
// get the device model
if (navigator.userAgentData
&& navigator.userAgentData.getHighEntropyValues)
navigator.userAgentData.getHighEntropyValues(['model'])
.then(function(ua) {
model = ua.model
})
else
model = navigator.userAgent
// public methods
return {
// get outputs
get_outputs: function() {
return (window.AudioContext || window.webkitAudioContext) ?
['sf2'] : null
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 |
// initialize the audio subsystem if not done yet
if (!gain) {
ac = conf.ac
if (!ac) {
conf.ac = ac = new (window.AudioContext ||
window.webkitAudioContext)
| | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
// initialize the audio subsystem if not done yet
if (!gain) {
ac = conf.ac
if (!ac) {
conf.ac = ac = new (window.AudioContext ||
window.webkitAudioContext)
if (/iPad|iPhone|iPod/.test(model))
play_unlock()
}
gain = ac.createGain()
gain.gain.value = conf.gain
}
while (i_start.noplay)
|
| ︙ | ︙ |
Changes to util/sndgen.js.
1 2 | // sndgen.js - sound generation // | | | | | | | 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 | // sndgen.js - sound generation // // Copyright (C) 2019-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // This script generates the play data which are stored in the music symbols: // - in all symbols // s.ptim = play time // - in BAR // rep_p = on a right repeat bar, pointer to the left repeat symbol // rep_s = on the first repeat variant, array of pointers to the next symbols, |
| ︙ | ︙ | |||
104 105 106 107 108 109 110 |
s.parts = r
// build the part table in the first symbol
// and put the reverse pointers in the P: symbols
s.p_s = [] // pointers to the parts
while (1) {
if (!s.ts_next) {
| | | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
s.parts = r
// build the part table in the first symbol
// and put the reverse pointers in the P: symbols
s.p_s = [] // pointers to the parts
while (1) {
if (!s.ts_next) {
s.part1 = first // end of tune = end of part
break
}
s = s.ts_next
if (s.part) {
s.part1 = first // reverse pointer
v = s.part.text[0] // 1st letter only
for (i = 0; i < first.parts.length; i++) {
if (first.parts[i] == v)
first.p_s[i] = s
}
}
}
} // build_parts()
|
| ︙ | ︙ | |||
296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
dt = s.time - abc_time
if (dt != 0) { // may go backwards after grace notes
p_time += dt / play_fac
abc_time = s.time
}
s.ptim = p_time
switch (s.type) {
case C.BAR:
if (s.time != b_tim) {
b_tim = s.time
b_typ = 0
}
if (s.text && rsk // if new variant
| > > > > | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
dt = s.time - abc_time
if (dt != 0) { // may go backwards after grace notes
p_time += dt / play_fac
abc_time = s.time
}
s.ptim = p_time
if (s.part) { // new part
rst = s // new possible restart
rst_fac = play_fac
}
switch (s.type) {
case C.BAR:
if (s.time != b_tim) {
b_tim = s.time
b_typ = 0
}
if (s.text && rsk // if new variant
|
| ︙ | ︙ | |||
386 387 388 389 390 391 392 | d /= play_fac s.pdur = d v = s.v c = chn[v] // channel s.chn = c s.instr = instr[c] break | < < < < | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | d /= play_fac s.pdur = d v = s.v c = chn[v] // channel s.chn = c s.instr = instr[c] break case C.TEMPO: if (s.tempo) play_fac = set_tempo(s) break } s = s.ts_next } // loop |
| ︙ | ︙ | |||
445 446 447 448 449 450 451 |
// - onend: (optional)
// - onnote: (optional)
// - note_run: start playing a note
// - get_time: return the time of the underlaying sound system
abc2svg.play_next = function(po) {
// handle a tie
| | | > > | > | | | < | | | < < | < > | | | | | | | | > | 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 |
// - onend: (optional)
// - onnote: (optional)
// - note_run: start playing a note
// - get_time: return the time of the underlaying sound system
abc2svg.play_next = function(po) {
// handle a tie
function do_tie(note, d) {
var i,
s = note.s,
midi = note.midi,
C = abc2svg.C,
v = s.v,
end_time = s.time + s.dur,
repv = po.repv
// search the end of the tie
while (1) {
s = s.ts_next
if (!s || s.time > end_time)
break
if (s.type == C.BAR) {
if (s.rep_p) {
if (!po.repn) {
s = s.rep_p
end_time = s.time
}
}
if (s.rep_s) {
if (!s.rep_s[repv])
break
s = s.rep_s[repv++]
end_time = s.time
}
while (s.ts_next && !s.ts_next.dur)
s = s.ts_next
}
if (s.type != C.NOTE)
continue
i = s.notes.length
while (--i >= 0) {
note = s.notes[i]
if (note.midi == midi) {
note.ti2 = true // the sound is generated
d += s.pdur / po.conf.speed
return note.tie_ty ? do_tie(note, d) : d
}
}
}
return d
} // do_tie()
// set the MIDI controls up to now
|
| ︙ | ︙ | |||
517 518 519 520 521 522 523 |
po.midi_ctrl(po, s, t)
}
po.p_v[s2.v] = true // synchronization done
} // set_ctrl()
// start and continue to play
function play_cont(po) {
| | > < | | 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 |
po.midi_ctrl(po, s, t)
}
po.p_v[s2.v] = true // synchronization done
} // set_ctrl()
// start and continue to play
function play_cont(po) {
var d, i, st, m, note, g, s2, t, maxt, now,
C = abc2svg.C,
s = po.s_cur
if (po.stop) {
if (po.onend)
po.onend(po.repv)
return
}
while (s.noplay) {
s = s.ts_next
if (!s || s == po.s_end) {
if (po.onend)
po.onend(po.repv)
return
}
}
t = po.stim + s.ptim / po.conf.speed // start time
now = po.get_time(po)
// if speed change, shift the start time
if (po.conf.new_speed) {
po.stim = now - (now - po.stim) *
po.conf.speed / po.conf.new_speed
po.conf.speed = po.conf.new_speed
po.conf.new_speed = 0
t = po.stim + s.ptim / po.conf.speed
}
maxt = t + po.tgen // max time = now + 'tgen' seconds
|
| ︙ | ︙ | |||
586 587 588 589 590 591 592 |
} else { // end of tune
s = po.s_end
break
}
}
if (s.bar_type.slice(-1) == ':') // left repeat
po.repv = 1
| > > | > > > | > | | | > > > > > > > > | < < < > | > > > | | | | | 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 |
} else { // end of tune
s = po.s_end
break
}
}
if (s.bar_type.slice(-1) == ':') // left repeat
po.repv = 1
if (!s.part1) {
while (s.ts_next && !s.ts_next.seqst) {
s = s.ts_next
if (s.part1)
break
}
if (!s.part1)
break
}
// fall thru
default:
if (s.part1 // if end of part
&& po.i_p != undefined) {
s2 = s.part1.p_s[++po.i_p] // next part
if (s2) {
po.stim += (s.ptim - s2.ptim) / po.conf.speed
s = s2
t = po.stim + s.ptim / po.conf.speed
} else {
s = po.s_end
}
po.repv = 1
}
break
}
if (s && s != po.s_end) {
switch (s.type) {
case C.BAR:
break
case C.BLOCK:
if (s.subtype == "midictl")
po.midi_ctrl(po, s, t)
break
case C.GRACE:
for (g = s.extra; g; g = g.next) {
d = g.pdur / po.conf.speed
for (m = 0; m <= g.nhd; m++) {
note = g.notes[m]
po.note_run(po, g,
note.midi,
t + g.ptim - s.ptim,
//fixme: there may be a tie...
d)
}
}
break
case C.NOTE:
case C.REST:
d = s.pdur / po.conf.speed
if (s.type == C.NOTE) {
for (m = 0; m <= s.nhd; m++) {
note = s.notes[m]
if (note.ti2)
continue
po.note_run(po, s,
note.midi,
t,
note.tie_ty ?
do_tie(note, d) : d)
}
}
// follow the notes/rests while playing
if (po.onnote && s.istart) {
i = s.istart
st = (t - now) * 1000
po.timouts.push(setTimeout(po.onnote, st, i, true))
if (d > 2) // problem when loop on one long note
d -= .1
setTimeout(po.onnote, st + d * 1000, i, false)
}
break
}
}
while (1) {
if (!s || s == po.s_end || !s.ts_next) {
if (po.onend)
setTimeout(po.onend,
(t - now + d) * 1000,
po.repv)
po.s_cur = s
return
}
s = s.ts_next
if (!s.noplay)
break
}
t = po.stim + s.ptim / po.conf.speed // next time
if (t > maxt)
break
}
po.s_cur = s
// delay before next sound generation
po.timouts.push(setTimeout(play_cont,
(t - now) * 1000
- 300, // wake before end of playing
po))
} // play_cont()
// search the index in the parts
function get_part(po) {
var s, i, s_p
for (s = po.s_cur; s; s = s.ts_prev) {
if (s.parts) {
po.i_p = -1
return
}
s_p = s.part1
if (!s_p || !s_p.p_s)
continue
for (i = 0; i < s_p.p_s.length; i++) {
if (s_p.p_s[i] == s) {
po.i_p = i // index in the parts
return
}
|
| ︙ | ︙ |
Changes to util/sndmem.js.
1 2 | // sndmem.js - generate play events for use with toaudio5 or tomidi5 // | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // sndmem.js - generate play events for use with toaudio5 or tomidi5 // // Copyright (C) 2020-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // The function abc2svg.sndmem() must be called after the abc2svg generation // and after the play data have been defined (by the function audio.add // in util/sndgen.js). // // It returns an array of Float32Array: |
| ︙ | ︙ |
Changes to util/sndmid.js.
1 2 3 4 5 6 7 | // sndmid.js - audio output using HTML5 MIDI // // Copyright (C) 2019-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // sndmid.js - audio output using HTML5 MIDI // // Copyright (C) 2019-2021 Jean-Francois Moine // // This file is part of abc2svg. // // abc2svg is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // abc2svg is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with abc2svg. If not, see <http://www.gnu.org/licenses/>. // Midi5 creation // @conf: configuration object - all items are optional: // onend: callback function called at end of playing // Argument: |
| ︙ | ︙ |