-
Notifications
You must be signed in to change notification settings - Fork 187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adjustPageWidth option #272
Comments
To be solved with #249 |
This would be useful for creating short music examples for papers. If the bounding box is extended past the end of a short example, it is more difficult to center the musical excerpt on the page. Demonstration of the bounding box for a short example placed on a page wider than the music: This should be given a higher priority than #249 (now a back-burner issue), but can be considered low priority. #249 can be simulated reliably for one system by setting the height of the page to very small, and can be approximately simulated by predicting the height of a page with a given number of systems. This issue is useful as mentioned above for generating music examples for papers (such as inserting the generated SVG image into Microsoft Word). MEI test data: <?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2019-01-26T01:26:39" version="2.0.0-dev-bd2039c">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workDesc>
<work>
<titleStmt>
<title />
</titleStmt>
</work>
</workDesc>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000000696167396">
<score xml:id="score-0000000994515716">
<scoreDef xml:id="scoredef-0000000907742012" midi.bpm="100">
<staffGrp xml:id="staffgrp-0000001603677160" symbol="bracket">
<staffDef xml:id="staffdef-0000001194553425" clef.shape="G" clef.line="2" key.sig="2s" meter.count="4" meter.unit="4" meter.sym="common" n="1" lines="5">
<label xml:id="label-0000000383314834" />
</staffDef>
<staffDef xml:id="staffdef-0000000916599571" clef.shape="G" clef.line="2" key.sig="2s" meter.count="4" meter.unit="4" meter.sym="common" n="2" lines="5" />
<staffDef xml:id="staffdef-0000000547285043" clef.shape="G" clef.line="2" clef.dis="8" clef.dis.place="below" key.sig="2s" meter.count="4" meter.unit="4" meter.sym="common" n="3" lines="5" />
<staffDef xml:id="staffdef-0000000936539610" clef.shape="F" clef.line="4" key.sig="2s" meter.count="4" meter.unit="4" meter.sym="common" n="4" lines="5" />
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L8" n="6">
<staff xml:id="staff-L8F4N1" n="1">
<layer xml:id="layer-L8F4N1" n="1">
<note xml:id="note-L9F4" dur="2" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L10F4" dur="4" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L12F4" dur="4" oct="4" pname="a" accid.ges="n" />
</layer>
</staff>
<staff xml:id="staff-L8F3N1" n="2">
<layer xml:id="layer-L8F3N1" n="1">
<note xml:id="note-L9F3" dur="2" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L10F3" dur="4" oct="4" pname="d" accid.ges="n" />
<beam xml:id="beam-L12F3-L13F3">
<note xml:id="note-L12F3" dur="8" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L13F3" dur="8" oct="4" pname="c" accid="n" />
</beam>
</layer>
</staff>
<staff xml:id="staff-L8F2N1" n="3">
<layer xml:id="layer-L8F2N1" n="1">
<note xml:id="note-L9F2" dur="2" oct="4" pname="c" accid.ges="s" />
<beam xml:id="beam-L10F2-L11F2">
<note xml:id="note-L10F2" dur="8" oct="3" pname="f" accid.ges="s" />
<note xml:id="note-L11F2" dur="8" oct="3" pname="g" accid.ges="n" />
</beam>
<note xml:id="note-L12F2" dur="4" oct="3" pname="a" accid.ges="n" />
</layer>
</staff>
<staff xml:id="staff-L8F1N1" n="4">
<layer xml:id="layer-L8F1N1" n="1">
<note xml:id="note-L9F1" dur="2" oct="2" pname="a" accid.ges="n" />
<note xml:id="note-L10F1" dur="4" oct="2" pname="b" accid.ges="n" />
<note xml:id="note-L12F1" dur="4" oct="3" pname="f" accid.ges="s" />
</layer>
</staff>
<fermata xml:id="fermata-L9F4" staff="1" startid="#note-L9F4" place="above" />
<fermata xml:id="fermata-L9F3" staff="2" startid="#note-L9F3" place="above" />
<fermata xml:id="fermata-L9F2" staff="3" startid="#note-L9F2" place="above" />
<fermata xml:id="fermata-L9F1" staff="4" startid="#note-L9F1" place="above" />
</measure>
<measure xml:id="measure-L14" n="7">
<staff xml:id="staff-L14F4N1" n="1">
<layer xml:id="layer-L14F4N1" n="1">
<note xml:id="note-L15F4" dur="4" oct="4" pname="b" accid.ges="n" />
<note xml:id="note-L17F4" dur="4" oct="5" pname="c">
<accid xml:id="accid-L17F4" accid="s" func="caution" />
</note>
<note xml:id="note-L18F4" dur="4" oct="5" pname="d" accid.ges="n" />
<note xml:id="note-L19F4" dur="4" oct="5" pname="c" accid.ges="s" />
</layer>
</staff>
<staff xml:id="staff-L14F3N1" n="2">
<layer xml:id="layer-L14F3N1" n="1">
<beam xml:id="beam-L15F3-L16F3">
<note xml:id="note-L15F3" dur="8" oct="3" pname="b" accid.ges="n" />
<note xml:id="note-L16F3" dur="8" oct="4" pname="d" accid.ges="n" />
</beam>
<note xml:id="note-L17F3" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L18F3" dur="4" oct="4" pname="f" accid.ges="s" />
<note xml:id="note-L19F3" dur="4" oct="4" pname="f" accid.ges="s" />
</layer>
</staff>
<staff xml:id="staff-L14F2N1" n="3">
<layer xml:id="layer-L14F2N1" n="1">
<note xml:id="note-L15F2" dur="4" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L17F2" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L18F2" dur="4" oct="3" pname="a" accid.ges="n" />
<note xml:id="note-L19F2" dur="4" oct="3" pname="a" accid.ges="n" />
</layer>
</staff>
<staff xml:id="staff-L14F1N1" n="4">
<layer xml:id="layer-L14F1N1" n="1">
<note xml:id="note-L15F1" dur="4" oct="3" pname="g" accid.ges="n" />
<note xml:id="note-L17F1" dur="4" oct="3" pname="e" accid.ges="n" />
<note xml:id="note-L18F1" dur="4" oct="3" pname="d" accid.ges="n" />
<note xml:id="note-L19F1" dur="4" oct="3" pname="f" accid.ges="s" />
</layer>
</staff>
<fermata xml:id="fermata-L18F4" staff="1" startid="#note-L18F4" place="above" />
<fermata xml:id="fermata-L18F3" staff="2" startid="#note-L18F3" place="above" />
<fermata xml:id="fermata-L18F2" staff="3" startid="#note-L18F2" place="above" />
<fermata xml:id="fermata-L18F1" staff="4" startid="#note-L18F1" place="above" />
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei> |
Can you make a PR for this? Thanks |
I would suggest that adjustPageWidth is combined with the possibility to decide how many measures you want in each system- e.g. "sysMeasures": 4 meaning maximum 4 measures in each system and "sysMeasures": 0 meaning let pageWidth decide - as it currently is. In combination with adjustPageWidth this will enable you to specify:
This will give you maximum 4 measures in each system and page width adjustet accordingly. As it currently is I'm forced to use pageWidth to adjust the number of measures in each system. To find the sweet spot is very time-consuming, so this feature would be much appreciated. |
That is more of a separate feature: the adjustPageWidth would automatically shrink the SVG bounding box, so it is not really adjusting the margins/width of the page, but rather moving the bounding box of the SVG image to fit the partial line of music (otherwise the SVG bounding box is set to the full expected width of the music). If you had four measures of whole notes, versus four measures of eight notes, you would still want four measures on a system? One option that will get you somewhat uniform measure counts on a page currently would be to increase the spacingNonLinear value towards 1 to make the measure widths more uniform. There will be complications with pickup measures and partial-measure repeats, which you probably do not want to count as a full measure. Not useful to you directly, but I have a Bach chorale typesetting page: Here is a choral with the scale/spacings set to a nice 4-bar/system layout: https://chorales.sapp.org/typesetter/#chor008 Using: { scale: 32,
spacingLinear: 0.3,
spacingNonLinear: 0.58
} I manually went through each of the 370 chorales in a relatively short time, recorded the spacing (and occasionally tweaks in the scaling) to get them to justify to the right edge of the page on their last systems (only one was impossible to do this with): Getting repeats to break at the desired places is currently difficult in veorvio (that would probably require encoding specific line breaks). Here is an example of setting the spacingNonLinear to 0.8, and then reducing the spacingLinear to get 4 measures to fit on a line (and I needed to shrink the music a little to get the first system to 4 measures): {
scale: 29,
spacingLinear: 0.1,
spacingNonLinear: 0.8,
} A visual problem is that the half-note gaps look too wide, which would be a problem with doing it this way. |
You would be able to do it at least 10 time faster 😜 What would the algorithm be? In other words, (1) how to extract the width of the typeset music, and (2) (which I could probably figure out on my own) how to set the width of the SVG image with that width? |
The request for adjustPageWidth on my part is actually for the bounding SVG box as @craigsapp mentions. The problem arises when you want the score to center on the page. If the bounding SVG box is too big the layout is lost. It is especially a problem when content (PAE og MEI) is created dynamically, where you do not know the width in advance. In regard to the number of measures for each system it is not as big an issue as adjustPageWidth. But just a few more words about this, because I still think it is related. I would like to create a PR, but I do not know the inner workings of Verovio - I'm just a programmer using it - so bear with me, if what I'm suggesting is stupid. I'm guessing the current algorithme makes a decision whether a measure should stay in the current system or jump down to the next is done in relation to creating each measure based on the specified width? If this is true implementing a fixed number of measures turns things the other way around, and I can see the difficulty. Is it possible to do post editing after the score is created:
Again, I do not know how Verovio is programmed, but hopefully this gives an idea of the intend behind the request. |
Yes, adding an option to verovio to generate layout to a fix measure count per system would be the only correct way of doing what you want. The only current way is to estimate the ideal width of the widest four-bar system of music and insert If this were to be implemented and you had multiple P&E incipits displayed on a page, what is your expected view? Either the width of each example would be different (which would be somewhat annoying to look at), or you would resize each one to fit within a specific width (which would be quite annoying to look at). Most P&E incipits (coming from RISM data, I presume) are quite short and often less that four measures: https://www.verovio.org/pae-examples.xhtml Here is an example of encoding system breaks: The left side notation was generated with the command-line command: verovio file.mei --breaks encoded --page-width 1400 --no-footer And the second example ignores the line breaks: verovio file.mei --page-width 1400 --no-footer (no The https://music-encoding.org/guidelines/v4/elements/sb.html A To do this with PAE import, you would need to do two steps: (1) convert PAE to MEI with verovio (can be done in the Javascript toolkit or with the command-line version of verovio), and (2) Insert On the command-line here is how to convert PAE to MEI: verovio file.pae -a -t mei This creates the file Here is the test MEI data for the above notation examples: <?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2019-01-28T13:26:22" version="2.1.0-dev-52e318d-dirty">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000002126902590">
<score xml:id="score-0000001986525815">
<scoreDef xml:id="scoredef-0000000116272359" midi.bpm="400">
<staffGrp xml:id="staffgrp-0000000496383883">
<staffDef xml:id="staffdef-0000001705962418" clef.shape="G" clef.line="2" meter.count="4" meter.unit="4" n="1" lines="5">
<label xml:id="label-0000001217288792" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<pb/>
<measure xml:id="measure-L4" n="1">
<staff xml:id="staff-L4F1N1" n="1">
<layer xml:id="layer-L4F1N1" n="1">
<note xml:id="note-L5F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L6" n="2">
<staff xml:id="staff-L6F1N1" n="1">
<layer xml:id="layer-L6F1N1" n="1">
<note xml:id="note-L7F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L8F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L9" n="3">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<note xml:id="note-L10F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L11F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L12F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L13F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L15" n="4">
<staff xml:id="staff-L15F1N1" n="1">
<layer xml:id="layer-L15F1N1" n="1">
<beam xml:id="beam-L16F1-L17F1">
<note xml:id="note-L16F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L17F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L18F1-L19F1">
<note xml:id="note-L18F1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L19F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L20F1-L21F1">
<note xml:id="note-L20F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L21F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
<beam xml:id="beam-L22F1-L23F1">
<note xml:id="note-L22F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L23F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L24" n="5">
<staff xml:id="staff-L24F1N1" n="1">
<layer xml:id="layer-L24F1N1" n="1">
<note xml:id="note-L25F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L26F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L27" n="6">
<staff xml:id="staff-L27F1N1" n="1">
<layer xml:id="layer-L27F1N1" n="1">
<note xml:id="note-L28F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L29F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L30F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L31F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L33" n="7">
<staff xml:id="staff-L33F1N1" n="1">
<layer xml:id="layer-L33F1N1" n="1">
<note xml:id="note-L34F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L35" n="8">
<staff xml:id="staff-L35F1N1" n="1">
<layer xml:id="layer-L35F1N1" n="1">
<note xml:id="note-L36F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L37F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L38" n="9">
<staff xml:id="staff-L38F1N1" n="1">
<layer xml:id="layer-L38F1N1" n="1">
<note xml:id="note-L39F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L40F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L41F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L42F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L43" n="10">
<staff xml:id="staff-L43F1N1" n="1">
<layer xml:id="layer-L43F1N1" n="1">
<beam xml:id="beam-L44F1-L45F1">
<note xml:id="note-L44F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L45F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L46F1-L47F1">
<note xml:id="note-L46F1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L47F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L48F1-L49F1">
<note xml:id="note-L48F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L49F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
<beam xml:id="beam-L50F1-L51F1">
<note xml:id="note-L50F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L51F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-L53" n="11">
<staff xml:id="staff-L53F1N1" n="1">
<layer xml:id="layer-L53F1N1" n="1">
<note xml:id="note-L54F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L55" n="12">
<staff xml:id="staff-L55F1N1" n="1">
<layer xml:id="layer-L55F1N1" n="1">
<note xml:id="note-L56F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L57F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L58" n="13">
<staff xml:id="staff-L58F1N1" n="1">
<layer xml:id="layer-L58F1N1" n="1">
<note xml:id="note-L59F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L60F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L61F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L62F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L64" n="14">
<staff xml:id="staff-L64F1N1" n="1">
<layer xml:id="layer-L64F1N1" n="1">
<beam xml:id="beam-L65F1-L66F1">
<note xml:id="note-L65F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L66F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L67F1-L68F1">
<note xml:id="note-L67F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L68F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
<beam xml:id="beam-L69F1-L70F1">
<note xml:id="note-L69F1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L70F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L71F1-L72F1">
<note xml:id="note-L71F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L72F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-L73" n="15">
<staff xml:id="staff-L73F1N1" n="1">
<layer xml:id="layer-L73F1N1" n="1">
<note xml:id="note-L74F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L75F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L76" n="16">
<staff xml:id="staff-L76F1N1" n="1">
<layer xml:id="layer-L76F1N1" n="1">
<note xml:id="note-L77F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L78F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L79F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L80F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L82" n="17">
<staff xml:id="staff-L82F1N1" n="1">
<layer xml:id="layer-L82F1N1" n="1">
<note xml:id="note-L83F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L84" n="18">
<staff xml:id="staff-L84F1N1" n="1">
<layer xml:id="layer-L84F1N1" n="1">
<note xml:id="note-L85F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L86F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L87" n="19">
<staff xml:id="staff-L87F1N1" n="1">
<layer xml:id="layer-L87F1N1" n="1">
<note xml:id="note-L88F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L89F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L90F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L91F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L93" n="20">
<staff xml:id="staff-L93F1N1" n="1">
<layer xml:id="layer-L93F1N1" n="1">
<note xml:id="note-L94F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L95" n="21">
<staff xml:id="staff-L95F1N1" n="1">
<layer xml:id="layer-L95F1N1" n="1">
<note xml:id="note-L96F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L97F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L98" n="22">
<staff xml:id="staff-L98F1N1" n="1">
<layer xml:id="layer-L98F1N1" n="1">
<note xml:id="note-L99F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L100F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L101F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L102F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L104" n="23">
<staff xml:id="staff-L104F1N1" n="1">
<layer xml:id="layer-L104F1N1" n="1">
<beam xml:id="beam-L105F1-L106F1">
<note xml:id="note-L105F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L106F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
<beam xml:id="beam-L107F1-L108F1">
<note xml:id="note-L107F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L108F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L109F1-L110F1">
<note xml:id="note-L109F1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L110F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L111F1-L112F1">
<note xml:id="note-L111F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L112F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-L113" n="24">
<staff xml:id="staff-L113F1N1" n="1">
<layer xml:id="layer-L113F1N1" n="1">
<note xml:id="note-L114F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L115" n="25">
<staff xml:id="staff-L115F1N1" n="1">
<layer xml:id="layer-L115F1N1" n="1">
<note xml:id="note-L116F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L117F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L118" n="26">
<staff xml:id="staff-L118F1N1" n="1">
<layer xml:id="layer-L118F1N1" n="1">
<note xml:id="note-L119F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L120F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L121F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L122F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L123" n="27">
<staff xml:id="staff-L123F1N1" n="1">
<layer xml:id="layer-L123F1N1" n="1">
<note xml:id="note-L124F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L125" n="28">
<staff xml:id="staff-L125F1N1" n="1">
<layer xml:id="layer-L125F1N1" n="1">
<note xml:id="note-L126F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L127F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L128" n="29">
<staff xml:id="staff-L128F1N1" n="1">
<layer xml:id="layer-L128F1N1" n="1">
<note xml:id="note-L129F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L130F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L131F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L132F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L134" n="30">
<staff xml:id="staff-L134F1N1" n="1">
<layer xml:id="layer-L134F1N1" n="1">
<beam xml:id="beam-L135F1-L136F1">
<note xml:id="note-L135F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L136F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L137F1-L138F1">
<note xml:id="note-L137F1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L138F1" dur="8" oct="4" pname="g" accid.ges="n" />
</beam>
<beam xml:id="beam-L139F1-L140F1">
<note xml:id="note-L139F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L140F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
<beam xml:id="beam-L141F1-L142F1">
<note xml:id="note-L141F1" dur="8" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L142F1" dur="8" oct="4" pname="f" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-L143" n="31">
<staff xml:id="staff-L143F1N1" n="1">
<layer xml:id="layer-L143F1N1" n="1">
<note xml:id="note-L144F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L145" n="32">
<staff xml:id="staff-L145F1N1" n="1">
<layer xml:id="layer-L145F1N1" n="1">
<note xml:id="note-L146F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L147F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L148" n="33">
<staff xml:id="staff-L148F1N1" n="1">
<layer xml:id="layer-L148F1N1" n="1">
<note xml:id="note-L149F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L150F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L151F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L152F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L154" n="34">
<staff xml:id="staff-L154F1N1" n="1">
<layer xml:id="layer-L154F1N1" n="1">
<note xml:id="note-L155F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L156" n="35">
<staff xml:id="staff-L156F1N1" n="1">
<layer xml:id="layer-L156F1N1" n="1">
<note xml:id="note-L157F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L158F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L159" n="36">
<staff xml:id="staff-L159F1N1" n="1">
<layer xml:id="layer-L159F1N1" n="1">
<note xml:id="note-L160F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L161F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L162F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L163F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L165" n="37">
<staff xml:id="staff-L165F1N1" n="1">
<layer xml:id="layer-L165F1N1" n="1">
<note xml:id="note-L166F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L167" n="38">
<staff xml:id="staff-L167F1N1" n="1">
<layer xml:id="layer-L167F1N1" n="1">
<note xml:id="note-L168F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L169F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L170" n="39">
<staff xml:id="staff-L170F1N1" n="1">
<layer xml:id="layer-L170F1N1" n="1">
<note xml:id="note-L171F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L172F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L173F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L174F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L176" n="40">
<staff xml:id="staff-L176F1N1" n="1">
<layer xml:id="layer-L176F1N1" n="1">
<note xml:id="note-L177F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L178" n="41">
<staff xml:id="staff-L178F1N1" n="1">
<layer xml:id="layer-L178F1N1" n="1">
<note xml:id="note-L179F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L180F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L181" n="42">
<staff xml:id="staff-L181F1N1" n="1">
<layer xml:id="layer-L181F1N1" n="1">
<note xml:id="note-L182F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L183F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L184F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L185F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L187" n="43">
<staff xml:id="staff-L187F1N1" n="1">
<layer xml:id="layer-L187F1N1" n="1">
<note xml:id="note-L188F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L189" n="44">
<staff xml:id="staff-L189F1N1" n="1">
<layer xml:id="layer-L189F1N1" n="1">
<note xml:id="note-L190F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L191F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<sb/>
<measure xml:id="measure-L192" n="45">
<staff xml:id="staff-L192F1N1" n="1">
<layer xml:id="layer-L192F1N1" n="1">
<note xml:id="note-L193F1" dur="4" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L194F1" dur="4" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L195F1" dur="4" oct="4" pname="e" accid.ges="n" />
<note xml:id="note-L196F1" dur="4" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L198" n="46">
<staff xml:id="staff-L198F1N1" n="1">
<layer xml:id="layer-L199F1N1" n="1">
<note xml:id="note-L200F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L201F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L202" n="47">
<staff xml:id="staff-L203F1N1" n="1">
<layer xml:id="layer-L203F1N1" n="1">
<note xml:id="note-L204F1" dur="2" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L205F1" dur="2" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L206" right="end" n="48">
<staff xml:id="staff-L207F1N1" n="1">
<layer xml:id="layer-L208F1N1" n="1">
<note xml:id="note-L209F1" dur="1" oct="4" pname="f" accid.ges="n" />
</layer>
</staff>
<fermata xml:id="fermata-L209F1" staff="1" startid="#note-L209F1" place="above" />
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei> |
I am not convinced this should be an option in Verovio. This can easily be done by pre-processing the data before passing it to Verovio. With MEI a simple XSLT can extract the number of measures you want to display. |
The core of the issue from our perspective is not a problem with getting the score to look as we want - either by changing encoding, adjusting the width or in other ways. The issue is that it is time-consuming and therefore inefficient. To explain this, I will like to describe how we are using Verovio. We are creating an interactive learning environment for music theory where Verovio is used to present small parts of scores for the user to respond to - either on a virtual piano or othervise. The examples are choosen by random from a pool. The pool is a list (json) of PAE (text strings) or MEI-files (that needs to be loaded before used). MEI is used to larger and more complex scores and PAE is used for smaller simpler things. To make sure that every PAE and MEI looks good we currently have to add the rendering width along with each PAE or MEI in the pool. This works. We can find the sweet spot for each PAE or MEI and ensure that the bounding SVG box is not too wide and the score has as many measures in each system, as we like. But all this is cumbersome - especially when you have a pool containing maybe 50 items and you have a lot of pools. I think the strength of Verovio, among others, is it's flexibility. That it is able to not just to show scores in traditionel sense, but also can be used as an engine in an interactive environment with quick changing content. To enable that you do not need manually to inspect every single score to make sure it looks as you want, would be a huge upgrade that will make it even more useful as part of interactive applications. |
Here is a summary graphic of what @peterkorgaard wants: In other words, given a fixed number of measures to show on a line (ignoring complications if last system is a remainder), what is the widest system when nominally typeset at the desired spacing and scaling parameters. Make note of that width and stretch all other systems to match it when typesetting the music. I will propose a variation on his feature request which would satisfy my feature request at the same time: Verovio should have an option to output the nominal widths of all measures given a particular set of layout parameters (spacingLinear, spacingNonLinear, scale being the main ones). An external program could then take this information and perform its own layout decisions, then insert appropriate The simplest possibility to implement this feature would be to have an option that returns an array of the nominal widths of each measure ("nominal width" means the typeset width of the measure before it is stretched or compressed to fit a system to a target width): [45, 55, 37, 40, 34, 22, 57, 37, 77, 55, 26, 34, 20, 36, 19, 24, 48,
53, 25, 28, 28, 15, 49, 29] Beyond the basic possibility, it would be useful to echo the parameters used to make the width calculations: {
"spacingLinear": 0.27,
"spacingNonLinear": 0.62,
"scale": 46,
"measureWidths": [45, 55, 37, 40, 34, 22,
57, 37, 77, 55, 26, 34, 20, 36,
19, 24, 48, 53, 25, 28, 28, 15,
49, 29]
} For my initial request of an adjustPageWidth option, this can be implemented with the above feature by summing the values in the measureWidths array, and then using that as the pageWidth option. For @peterkorgaard, he could then group the measures by 4, then sum the measure widths for each group, find the maximum, and then provide that value as the pageWidth option. I would say that this particular feature (exporting the nominal measure widths) is highly desirable. This allows for refined automated layout that a user might want without having to implement the system inside of verovio (inside which the current nominal measure width information is hidden). For example, Walter's layout system for MuseData is somewhat based on what @peterkorgaard wants, and it is also an iterative process that will move measures around to different systems as it calculates an optimal layout (verovio currently uses a one-pass algorithm). If you allow access to nominal measure widths, then you can leave more complicated layout algorithms to the reader 😄 There will be some complications, such as not counting the width of the initial clef/key/time signature information. Maybe this can be provided in the output, as this can be variable based on they key signature width for example. Also what to do with the initial indentation (currently only related to staff labels), and also abbreviation labels. These would also be useful to report in the layout information.
The data exported with this feature can be used to do that. Otherwise it is not possible to accurately make decisions as to where the system breaks should be placed, or in @peterkorgaard's case, what the (minimal) width of the music should be chosen. |
A related feature that would be useful to add if/when the above feature is implemented is an option to control the stretching threshold of the last system. Currently it is hard-wired to about 85%. It would be useful to allow the user to control this threshold, particularly when they want to do external layout with the above feature request. I can add that as a separate issue after you implement the export of nominal measure widths, unless you (or whomever provides a PR for it 😉) do it at the same time. |
I think @craigsapps description of what I requested is accurate, but it made me wonder if a post-process and the sacrifice of the one-pass algorithm would increase rendering time in javascript-toolkit, which would be bad? Revisiting the initial problem I think the ability for Verovio to assign the ideal width of a one-line-no-system-breaks-score is what I'm requesting. It could be applied if Verovio is provided with { pageWidth: 0 } meaning please figure it out yourself and make sure the bounding box has the correct width. The fixed number of measures is of much less importance and just nice to have. |
That is close to my feature request as well. It is currently possible to do something similar to adjustPageHeight: if it is set to 60000 (max value allow for height), then it will automatically display all of the music on one page. Iikewise, a similar options for page width is useful. This could be done in two possible ways: (1) how @peterkorgaard describes by setting pageWidth to 0 (and therefore making pageHeight 0 mean a single infinite page would be good), or set the pageWidth to a very large number and then have an adjustPageWidth parameter to shrink the bounding box to the width of the actual music in a manner similar to pageHeight/adjustPageHeight are currently working. |
Either way. Both methods would be good and highly desirable. |
Move to the wishlist |
It would be useful to have an
--adjust-page-width
option which functions in a similar manner to--adjust--page-height
. The option would shrink the width of the music in the case where there is only a single system of music, and the music does not completely fill the full width specified by--page-width
.Alternatively, or in addition, there could be an option called
--crop
and/or-c
which would turn on both--adjust-page-height
and--adjust-page-width
.The text was updated successfully, but these errors were encountered: