-
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
Scope the CSS included in the SVG #3953
Conversation
Will this make it harder to override CSS styles in sheet music? Adding the ID will increase the specificity of the CSS rule, making it harder to create a general CSS rule for all rendered sheet music in a website's stylesheet. |
I don't think it will be a problem. If there is a single SVG on the page, it definitely will not be a problem if your CSS does not use the svg ID in the selectors. Even if you have multiple SVG images, you would not give the ID in your external stylesheet so that it would apply to all SVG images (i.e., as any current implementation would handle it): g.syl {
opacity: 0.0;
} Internal CSS is added using verovio's If you use For inserting the SVG image directly into the HTML code, the internal CSS for the svg can otherwise be seen by all other SVG images on the page, which in some cases may cause conflicts between styles in different images (which is what this enhancement is for). The use of the ID in the CSS selector would be useful if there is internal CSS in the SVG image that should apply to only a single SVG image. I am wondering how the SVG ID could be coordinated with the internal CSS in that case? Or would the IDREF for CSS in the SVG be automatically applied (which I suspect that this commit does not do?). The easiest way would probably be a parameter input to verovio when rendering to set the svg ID, such as |
Here is some SVG generated with <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="2100px" height="2970px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="visible" id="dr3gobx">
<desc>Engraved by Verovio 5.1.0-dev-da5157a</desc>
<defs>
<symbol id="E990-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M0 -97v147c0 35 37 52 76 52c41 0 84 -19 84 -54v-149c-6 6 -11 10 -11 10c-12 8 -28 14 -64 14h-5c-32 0 -43 -2 -58 -10c-11 -6 -22 -14 -22 -14v4z" />
</symbol>
<symbol id="E995-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M36 -58c-18 0 -30 -6 -36 -18v162c0 20 10 30 30 30h1c34 0 92 -14 108 -52v-180c-12 44 -67 58 -103 58z" />
</symbol>
<symbol id="E996-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M4 -93c0 0 -4 6 -4 10v140c0 42 45 45 72 45h9c19 0 63 -4 63 -47v-448c0 -3 -2 -8 -6 -8h-5c-3 0 -6 5 -6 8v311c-11 7 -29 12 -51 12h-4c-34 -1 -63 -17 -68 -23z" />
</symbol>
<symbol id="E997-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M6 -401c-4 0 -6 5 -6 8v448c0 43 44 47 63 47h9c27 0 72 -3 72 -45v-140c0 -4 -4 -10 -4 -10c-5 6 -34 22 -68 23h-4c-22 0 -40 -5 -51 -12v-311c0 -3 -3 -8 -6 -8h-5z" />
</symbol>
<symbol id="E9B5-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M0 300h13v-450h-13v450z" />
</symbol>
<symbol id="E9BA-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M0 104c100 -149 297 -328 467 -355h10c22 0 37 15 44 45v-176v-18h-24c-70 0 -154 35 -251 103c-110 78 -192 151 -246 219v182z" />
</symbol>
<symbol id="E9BE-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M0 300h13v-450h-13v450z" />
</symbol>
<symbol id="E906-6lq4mu" viewBox="0 0 1000 1000" overflow="inherit">
<path transform="scale(1,-1)" d="M181 -131c0 -21 -3 -36 -10 -46c-11 -17 -33 -25 -64 -25c-47 0 -77 9 -91 28c-11 15 -17 47 -17 94v43c0 13 0 26 1 37v41c0 13 0 26 -1 39c0 48 5 79 16 94c14 19 45 28 92 28c32 0 53 -8 64 -24c7 -10 10 -26 10 -47c0 -28 -9 -47 -26 -58c-13 -8 -33 -12 -58 -12h-23 c-7 0 -14 0 -21 1c-17 0 -26 -4 -26 -11v-51v-51c0 -8 8 -12 24 -12c4 0 11 0 22 1s19 1 25 1c25 0 44 -4 56 -11c18 -11 27 -30 27 -59z" />
</symbol>
</defs>
<style type="text/css">#dr3gobx g.page-margin{font-family:Times,serif;} g.ending, g.fing, g.reh, g.tempo{font-weight:bold;} g.dir, g.dynam, g.mNum{font-style:italic;} g.label{font-weight:normal;} path{stroke:currentColor}</style>
<style type="text/css">#dr3gobx g.syl{ opacity: 0.0; }</style>
<svg class="definition-scale" color="black" viewBox="0 0 21000 29700">
<g class="page-margin" transform="translate(500, 500)">
<g id="mzpdn2s" class="mdiv pageMilestone" />
<g id="sybk5z9" class="score pageMilestone" />
<g id="s12c860x" class="system">
<g id="seyf69s" class="section systemMilestone" />
<g id="s1f5awmz" class="staff">
<path d="M0 540 L852 540" stroke-width="13" />
<path d="M0 720 L852 720" stroke-width="13" />
<path d="M0 900 L852 900" stroke-width="13" />
<path d="M0 1080 L852 1080" stroke-width="13" />
<path d="M0 1260 L852 1260" stroke-width="13" />
<g id="kb2t54j" class="keySig" />
<g id="l7g0txr" class="layer">
<g id="c1k09lm9" class="clef">
<use xlink:href="#E906-6lq4mu" x="90" y="720" height="720px" width="720px" />
</g>
<g id="spd1yhz" class="syllable">
<g id="s1tfjgxb" class="syl">
<text x="311" y="1752" font-size="0px">
<tspan id="t1htylje" class="text">
<tspan font-size="405px">Be</tspan>
</tspan>
</text>
</g>
<g id="n1aeg39u" class="neume">
<g id="n1tt2x7e" class="nc">
<use xlink:href="#E990-6lq4mu" x="311" y="1170" height="720px" width="720px" />
</g>
<g id="n1cnpfi6" class="nc">
<use xlink:href="#E990-6lq4mu" x="426" y="1170" height="720px" width="720px" />
</g>
<g id="nb59jm4" class="nc">
<use xlink:href="#E996-6lq4mu" x="532" y="1080" height="720px" width="720px" />
</g>
</g>
</g>
</g>
</g>
<g id="scmu1ik" class="staff">
<path d="M852 540 L1325 540" stroke-width="13" />
<path d="M852 720 L1325 720" stroke-width="13" />
<path d="M852 900 L1325 900" stroke-width="13" />
<path d="M852 1080 L1325 1080" stroke-width="13" />
<path d="M852 1260 L1325 1260" stroke-width="13" />
<g id="l1k1vi1t" class="layer">
<g id="skb7ysu" class="syllable">
<g id="sclc1qi" class="syl">
<text x="852" y="1752" font-size="0px">
<tspan id="t1e6n56j" class="text">
<tspan font-size="405px">ne</tspan>
</tspan>
</text>
</g>
</g>
</g>
</g>
<g id="s1kz1z5h" class="staff">
<path d="M1325 540 L1775 540" stroke-width="13" />
<path d="M1325 720 L1775 720" stroke-width="13" />
<path d="M1325 900 L1775 900" stroke-width="13" />
<path d="M1325 1080 L1775 1080" stroke-width="13" />
<path d="M1325 1260 L1775 1260" stroke-width="13" />
<g id="lf4xa3e" class="layer">
<g id="s1leipow" class="syllable">
<g id="sz6i8m7" class="syl">
<text x="1325" y="1752" font-size="0px">
<tspan id="t1drdv8s" class="text">
<tspan font-size="405px">di</tspan>
</tspan>
</text>
</g>
<g id="nz3kco4" class="neume">
<g id="n1qxhlnm" class="nc">
<use xlink:href="#E990-6lq4mu" x="1325" y="990" height="720px" width="720px" />
</g>
<g id="n183o28n" class="nc">
<use xlink:href="#E996-6lq4mu" x="1431" y="900" height="720px" width="720px" />
</g>
</g>
</g>
</g>
</g>
<g id="s7odwrx" class="staff">
<path d="M1775 540 L2225 540" stroke-width="13" />
<path d="M1775 720 L2225 720" stroke-width="13" />
<path d="M1775 900 L2225 900" stroke-width="13" />
<path d="M1775 1080 L2225 1080" stroke-width="13" />
<path d="M1775 1260 L2225 1260" stroke-width="13" />
<g id="l4w3w0w" class="layer">
<g id="s8t3kb7" class="syllable">
<g id="s14jvcsi" class="syl">
<text x="1775" y="1752" font-size="0px">
<tspan id="t69pgs3" class="text">
<tspan font-size="405px">ci</tspan>
</tspan>
</text>
</g>
<g id="n1uoj2zd" class="neume">
<g id="nilw7t8" class="nc">
<use xlink:href="#E997-6lq4mu" x="1775" y="990" height="720px" width="720px" />
</g>
<g id="ndxtacy" class="nc">
<use xlink:href="#E990-6lq4mu" x="1869" y="1170" height="720px" width="720px" />
</g>
</g>
</g>
</g>
</g>
<g id="s1xawr38" class="staff">
<path d="M2225 540 L3202 540" stroke-width="13" />
<path d="M2225 720 L3202 720" stroke-width="13" />
<path d="M2225 900 L3202 900" stroke-width="13" />
<path d="M2225 1080 L3202 1080" stroke-width="13" />
<path d="M2225 1260 L3202 1260" stroke-width="13" />
<g id="l133gn09" class="layer">
<g id="s15d3qt9" class="syllable">
<g id="smkczen" class="syl">
<text x="2225" y="1752" font-size="0px">
<tspan id="t13z7rpf" class="text">
<tspan font-size="405px">te</tspan>
</tspan>
</text>
</g>
<g id="n5benki" class="neume">
<g id="nm4c1p9" class="nc">
<use xlink:href="#E995-6lq4mu" x="2225" y="1080" height="720px" width="720px" />
<use xlink:href="#E9BE-6lq4mu" x="2225" y="1238" height="720px" width="720px" />
<use xlink:href="#E9BE-6lq4mu" x="2316" y="1251" height="720px" width="720px" />
<g id="lnfzerc" class="liquescent" />
</g>
</g>
<g id="n8k2b0e" class="neume">
<g id="n8pf5rc" class="nc">
<use xlink:href="#E9B5-6lq4mu" x="2525" y="1260" height="720px" width="720px" />
</g>
<g id="n19xd4m3" class="nc">
<use xlink:href="#E9BA-6lq4mu" x="2525" y="1080" height="720px" width="720px" />
</g>
<g id="npng4r9" class="nc">
<use xlink:href="#E990-6lq4mu" x="2891" y="1170" height="720px" width="720px" />
</g>
<g id="n1713vny" class="nc">
<use xlink:href="#E990-6lq4mu" x="2997" y="1260" height="720px" width="720px" />
</g>
</g>
</g>
</g>
</g>
<g id="s1kcvza2" class="systemMilestoneEnd seyf69s" />
</g>
<g id="px1looh" class="pageMilestoneEnd sybk5z9" />
<g id="p1oepedl" class="pageMilestoneEnd mzpdn2s" />
<g id="pyvcout" class="pgHead autogenerated" />
<g id="pctzpbc" class="pgFoot autogenerated">
<g id="fkeiut" class="fig">
<g class="svg" transform="translate(7750, 28099) scale(10.000000, 10.000000)">
<g>
<path fill="#00000" d="M 17.11278,49.26451 V 10.367554 h 12.696511 c 3.288815,7.336676 6.71267,14.610456 10.127281,21.888976 3.419998,-7.484684 6.255515,-14.204887 9.58887,-21.909915 2.436207,0.103726 4.316952,0.08453 6.484294,-0.05808 V 49.264423 H 50.274275 C 50.145222,38.35639 50.016136,27.448368 49.887066,16.540329 45.003488,27.315459 39.967448,38.433564 35.083854,49.208695 34.678996,49.343717 34.426583,49.135619 34.021726,49.270644 29.46588,39.330716 24.910049,29.390805 20.354201,19.450876 20.224341,29.388756 20.09461,39.326619 19.964815,49.264497 H 17.11278 Z M 36.754144,39.324695 C 32.721221,30.512695 28.6883,21.700679 24.655394,12.888662 22.530527,12.750737 22.656775,12.71031 20.714356,12.813974 v 0.966497 c 4.612938,9.99784 9.609439,20.748709 13.87298,30.081745 0.722248,-1.512523 1.444528,-3.025014 2.166808,-4.537521 z m 25.738417,9.939815 c 0,-12.965651 0,-25.931305 0,-38.896956 10.084388,0 20.168791,0 30.253178,0 0,0.960416 0,1.920849 0,2.881265 -6.482825,0 -12.965652,0 -19.448478,0 0,4.802097 0,9.604178 0,14.406277 5.52241,0 11.044819,0 16.567229,0 0,0.960415 0,1.920832 0,2.881248 -5.52241,0 -11.044819,0 -16.567229,0 0,5.282306 0,10.564611 0,15.846917 6.963035,0 13.926068,0 20.889103,0 0,0.960416 0,1.920832 0,2.881249 -10.564597,0 -21.129207,0 -31.693803,0 z m 4.321874,-2.160937 c 0,-11.765131 0,-23.530263 0,-35.295394 -0.720312,0 -1.440625,0 -2.160937,0 0,11.765131 0,23.530263 0,35.295394 0.720312,0 1.440625,0 2.160937,0 z m 32.41413,2.160937 c 0,-12.965651 0,-25.931305 0,-38.896956 2.401045,0 4.802095,0 7.203135,0 0,12.965651 0,25.931305 0,38.896956 -2.40104,0 -4.80209,0 -7.203135,0 z m 2.881265,-2.160937 c 0,-11.765131 0,-23.530263 0,-35.295394 -0.72031,0 -1.44064,0 -2.160953,0 0,11.765131 0,23.530263 0,35.295394 0.720313,0 1.440643,0 2.160953,0 z" />
<path fill="#00000" d="m 346.3,6.7 c -3.1,0.5 -4.9,4.4 -2.7,6.8 1.2,1.4 2.7,2.4 4.1,3.5 -2.4,5.3 -7.7,8.3 -11.9,12.1 -3.7,2.8 -7,6.2 -9.7,9.9 -2.2,-0.8 -0.3,-6.8 -0.6,-9.5 0.1,-3.1 0.7,-6.4 2.9,-8.7 1.3,-1.9 3,-3.5 4.5,-5.2 1.2,-3.4 -3.2,-4.9 -5.8,-4.6 -7.3,-0.5 -14.6,2 -20,6.8 -5,4.6 -10,10.1 -11.5,17 -0.9,3.5 -0.2,7.5 2.8,9.9 2.5,2.8 7.4,2.9 9.8,-0.2 1.7,-2.3 3.2,-4.8 3.8,-7.6 -0.1,-2.6 -4.4,-2.3 -4.3,0.2 1.2,2.4 -0.9,4.7 -2.7,6.2 -1.7,0.9 -4.7,0.7 -4.8,-1.7 -1,-5.8 2.1,-11.3 5.2,-16.1 4,-5.8 9.8,-11.2 17.2,-11.8 1.6,0 8.1,-1.2 6.8,1.4 -2.8,2.8 -5.6,6.1 -6,10.3 -1.6,7.7 0.1,15.7 -2.3,23.2 -1.1,3.9 2,2.6 2.5,0.2 3.3,-7.4 8.9,-13.4 15.1,-18.5 4.2,-3.9 9.5,-7.1 11.9,-12.6 1.3,-3.6 1.2,-9 -2.7,-10.9 -0.6,-0.2 -1.2,-0.3 -1.8,-0.3 z m 66,14.5 c -2,0.8 -1.8,4.9 0.8,4.4 3.4,0.4 2.9,-6.2 -0.8,-4.4 z m 0.6,7.3 c -1.3,0.5 -7.6,0.5 -5.4,2.2 4,-0.3 0.7,4.5 0.6,6.7 -0.4,2.9 -2.4,5.9 -1.2,8.8 2.7,1.7 5.6,-0.8 6.8,-3.2 1.6,-1.4 -0.5,-3 -1.2,-0.9 -0.4,0.8 -2.4,3.5 -2.6,1.8 1.1,-5 2.7,-9.9 3.9,-14.9 l -0.1,-0.5 h -0.9 z m -65.1,0.2 c -6.5,1.6 -10.5,9.5 -8.2,15.7 2.1,3.4 7.4,2.9 10.1,0.4 2,-0.2 3.6,-5.3 1,-3.4 -1.4,2 -4,4.2 -6.5,2.8 -2.2,-1.9 -1.9,-5.7 1.7,-5.3 3.1,-0.9 6.9,-2.1 8.1,-5.5 0.9,-2.7 -1.6,-5.2 -4.3,-4.8 h -1.1 -0.7 z m 13.6,0 c -2.2,0 -8.5,1.8 -2.9,2.3 0.9,1.9 -1,4.9 -1.1,7.2 -0.5,2.9 -1.4,5.7 -1.7,8.7 3.7,0.7 3.8,-2.6 4.4,-5.3 0.9,-3.3 1.6,-7 4.1,-9.5 2.4,1.6 6.8,-0.7 3.7,-3.4 -2.9,-0.5 -4.8,2.4 -6.2,4.3 0,-1.2 2.4,-5 -0.2,-4.3 z m 15.8,0 c -6.4,1.3 -9.6,9.1 -7.7,14.9 1.9,4 7.7,3.9 11,1.7 4.1,-3 6,-8.9 4.4,-13.7 -1.3,-3 -4.8,-3.2 -7.6,-3 z m 17,0 c -2.3,0 -8.8,1.9 -3,2.4 0.4,2.5 -1,5.7 -1.4,8.4 -0.7,2.4 -1.8,7.5 2.1,7.2 3.8,-0.1 6.5,-3.5 8.5,-6.3 2,-3.2 4.5,-7 3.3,-10.9 -3.7,-3 -3.6,2.6 -3.1,5.1 -0.7,3.8 -2.7,7.9 -6.2,9.8 -3.6,0.6 -1,-4.3 -0.8,-6.1 0.6,-3.2 1.6,-6.3 1.9,-9.5 -0.4,0 -0.8,0 -1.1,0 z m 30.6,0 c -6.3,1.2 -9.5,8.9 -7.8,14.7 1.5,4 7.2,4.2 10.5,2.4 4.6,-2.8 6.6,-9.3 4.8,-14.3 -1.4,-2.8 -4.8,-3 -7.5,-2.8 z m -75.4,1.7 c 2.1,1.5 0.2,4.7 -1.6,5.7 -1.1,0.4 -5.5,3.4 -4.6,0.7 0.8,-2.7 2.2,-6.2 5.3,-6.6 l 0.9,0.1 z m 30.8,0 c 2.6,1.5 1.3,5.2 0.8,7.6 -0.8,2.7 -1.9,5.9 -4.7,7.1 -5.1,0.8 -4,-5.8 -2.8,-8.8 1,-2.8 3,-6.8 6.7,-5.8 z m 47.1,-0.1 c 2.9,0.7 2,4.7 1.5,6.8 -0.7,3 -1.8,6.7 -5,8 -4.7,0.8 -4,-5.1 -3,-7.9 0.9,-3 2.7,-7.3 6.5,-6.8 z m -88.1,5.9 c -0.3,1.3 0.9,-0.6 0,0 z m -1.1,2.4 c -0.2,0.5 0.5,-0.1 0,0 z m -1.3,4.5 c -0.3,1.3 0.8,-0.2 0,0 z" />
<text y="41" x="201" fill="#00000" style="font-style:italic;font-weight:normal;font-size:30px;line-height:125%;font-family:Times;text-anchor:middle" xml:space="preserve">engraved with</text>
</g>
</g>
</g>
</g>
</g>
</svg>
</svg> |
Will
I am also wondering about multiple selectors for a style rule 😜 :
It might be nice to prefix the ID with the text "svg" to make it clearer what the ID refers to. Such as With such use, adding |
I hadn't thought about the multiple rules case. I would be easy to prefix all the rules in the common css, but having to parse the custom css to add it is not something we would want to do. Maybe one solution would be to use the
for a document witn |
Here is a demo to handle most CSS cases other than #include <iostream>
#include <regex>
#include <string>
#include <vector>
// Function prototype
std::string transformCssRule(const std::string& rule, const std::string& refid);
int main() {
std::vector<std::string> cssInput = {
"g.note {fill: red;}",
"g.note, g.rest {fill: red;}",
"g.note {fill: red} g.rest {fill: blue}"
};
std::string refid = "abc"; // REFID to prepend
for (const auto& cssRule : cssInput) {
std::cout << "Original: " << cssRule << std::endl;
std::cout << "Transformed: " << transformCssRule(cssRule, refid) << std::endl;
std::cout << std::endl;
}
return 0;
}
std::string transformCssRule(const std::string& rule, const std::string& refid) {
std::regex selectorRegex(R"(([\w\s.,]+)\s*\{([^}]*)\})");
std::sregex_iterator it(rule.begin(), rule.end(), selectorRegex);
std::sregex_iterator end;
std::string result;
while (it != end) {
std::string selectors = (*it)[1].str();
std::string properties = (*it)[2].str();
// Trim trailing spaces from selectors to prevent extra spaces before `{`
selectors = std::regex_replace(selectors, std::regex(R"(\s+$)"), "");
// Prepend `#refid` to each selector
std::regex multiSelectorRegex(R"((\b\w+\.[\w-]+\b))");
selectors = std::regex_replace(selectors, multiSelectorRegex, "#" + refid + " $1");
// Keep contents inside `{}` unchanged
result += selectors + " {" + properties + "}";
++it;
if (it != end) {
result += " ";
}
}
return result;
}
Results:
Compiling command: g++ --std=c++20 -O3 -Wall -Wextra -Werror -o cssid cssid.cpp |
Something else you might need to worry about is that CSS has stricter rules than HTML, SVG, or XML on what constitutes a valid ID. See https://developer.mozilla.org/en-US/docs/Web/CSS/ident In particular, CSS identifiers can't start with a number. So if your SVG looks like this: This CSS will not work: You have to escape the identifier, like this: Or you could use an attribute selector as a workaround: |
Note that IDs should not start with a number in XML as well (for example, in SVG data), so when generating an ID, automatically that should be avoided (that is why I used |
One thought on this is that perhaps the MEI and the SVG are somehow accessible in the same HTML page. Most websites where that currently happens has MEI in a text editor such as ACE, so it should not be a problem. Example with MoVI: ![]() |
The default SVG is now going to be looking like: #d1qjy7a g.page-margin {
font-family: Times, serif;
}
#d1qjy7a g.ending,
#d1qjy7a g.fing,
#d1qjy7a g.reh,
#d1qjy7a g.tempo {
font-weight: bold;
}
#d1qjy7a g.dir,
#d1qjy7a g.dynam,
#d1qjy7a g.mNum {
font-style: italic;
}
#d1qjy7a g.label {
font-weight: normal;
}
#d1qjy7a path {
stroke: currentColor;
} |
How are the defaults overridden? I.e. if |
I am also wondering how changing fonts in the CSS will (not) affect music layout 😜 And related to that, how to give non-Times font metrics to verovio... (For Tasso in Music Project, I am using a different font, Simonetta, which is pretty close to Times, so I can apply the font after rendering without much problem). |
This hasn't change. They are overridden with an additional |
should I merge? |
Yes |
Limit the scope of CSS style in the SVG through
svg@id
, namely withand then
Also remove
xmlns:mei
from thesvg
, which is not necessary but make the svg invalid.No change expected