Skip to content
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

Inline the styles to be styling attributes when generating standalone SVG #36

Open
tabatkins opened this issue Jan 1, 2016 · 11 comments

Comments

@tabatkins
Copy link
Owner

Might be useful to allow generating a standalone SVG document - #35 requested it. Right now I just generate an <svg> suitable for inserting into an HTML doc.

Just need to output the <svg> with the right namespace decls, and inline the style.

@lurch
Copy link
Contributor

lurch commented Sep 3, 2018

Yes please! Being able to generate standalone SVG files (with the styles inlined, etc.) would be great 👍
I'm using the Python version, if that makes any difference.

@florianpircher
Copy link

Instead of inlining the styles you could also include the CSS within the SVG element.

<style> in <svg>: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/style

@tabatkins
Copy link
Owner Author

Okay, standalone output is now supported.

In Python, this should happen by default; it already output the styles in an inline style block by default, and now it'll output the xmlns attribute as well. (This doesn't hurt usage inline in html, where it's just ignored.)

In JS, you can call .toStandalone(), which is the same as .toString() except it includes the xmlns attribute and a style child.

The dingus has been updated with a standalone checkbox as well, if you want to generate things one-off.

I haven't tested the Python code, but it was a trivial change so it should work fine, hopefully? Let me know if there are any problems.

@lurch
Copy link
Contributor

lurch commented Feb 29, 2020

The "standalone" diagrams generated by the online dingus still just display as black boxes when opened in Inkscape or Gnome's Image Viewer? 😕

@tabatkins
Copy link
Owner Author

I think that's just because those don't support CSS? Hmm, I could just inline it all into attributes, but there's no reasonable way to automatically do that in a way that supports both CSS and attributes. :(

@lurch
Copy link
Contributor

lurch commented Mar 2, 2020

Hmmm, could it be done with some kind of post-processing step at export time?

With a bit of trial&error, I was able to (manually) convert:

<svg class="railroad-diagram" height="92" viewBox="0 0 592.0 92" width="592.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<style>/* <![CDATA[ */
	svg.railroad-diagram {
		background-color:hsl(30,20%,95%);
	}
	svg.railroad-diagram path {
		stroke-width:3;
		stroke:black;
		fill:rgba(0,0,0,0);
	}
	svg.railroad-diagram text {
		font:bold 14px monospace;
		text-anchor:middle;
	}
	svg.railroad-diagram text.label{
		text-anchor:start;
	}
	svg.railroad-diagram text.comment{
		font:italic 12px monospace;
	}
	svg.railroad-diagram rect{
		stroke-width:3;
		stroke:black;
		fill:hsl(120,100%,90%);
	}

/* ]]> */
</style><g>
<path d="M20 21v20m10 -20v20m-10 -10h20"></path></g><path d="M40 31h10"></path><g class="terminal">
<path d="M50 31h0.0"></path><path d="M112.5 31h0.0"></path><rect height="22" rx="10" ry="10" width="62.5" x="50.0" y="20"></rect><text x="81.25" y="35">BEGIN</text></g><path d="M112.5 31h10"></path><path d="M122.5 31h10"></path><g class="terminal">
<path d="M132.5 31h0.0"></path><path d="M169.5 31h0.0"></path><rect height="22" rx="10" ry="10" width="37.0" x="132.5" y="20"></rect><text x="151.0" y="35">IF</text></g><path d="M169.5 31h10"></path><path d="M179.5 31h10"></path><g class="non-terminal">
<path d="M189.5 31h0.0"></path><path d="M303.0 31h0.0"></path><rect height="22" width="113.5" x="189.5" y="20"></rect><text x="246.25" y="35">name&#95;string</text></g><path d="M303.0 31h10"></path><g>
<path d="M313.0 31h0.0"></path><path d="M390.0 31h0.0"></path><path d="M313.0 31h20"></path><g class="terminal">
<path d="M333.0 31h0.0"></path><path d="M370.0 31h0.0"></path><rect height="22" rx="10" ry="10" width="37.0" x="333.0" y="20"></rect><text x="351.5" y="35">==</text></g><path d="M370.0 31h20"></path><path d="M313.0 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g class="terminal">
<path d="M333.0 61h0.0"></path><path d="M370.0 61h0.0"></path><rect height="22" rx="10" ry="10" width="37.0" x="333.0" y="50"></rect><text x="351.5" y="65">!=</text></g><path d="M370.0 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g>
<path d="M390.0 31h0.0"></path><path d="M552.0 31h0.0"></path><path d="M390.0 31h20"></path><g class="non-terminal">
<path d="M410.0 31h0.0"></path><path d="M532.0 31h0.0"></path><rect height="22" width="122.0" x="410.0" y="20"></rect><text x="471.0" y="35">value&#95;number</text></g><path d="M532.0 31h20"></path><path d="M390.0 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g class="non-terminal">
<path d="M410.0 61h0.0"></path><path d="M532.0 61h0.0"></path><rect height="22" width="122.0" x="410.0" y="50"></rect><text x="471.0" y="65">value&#95;string</text></g><path d="M532.0 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path d="M 552.0 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>

(which displays okay in the browser, but not in Gnome's Image Viewer) into:

<svg class="railroad-diagram" height="92" viewBox="0 0 592.0 92" width="592.0" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(.5 .5)">
<g>
<rect width="100%" height="100%" fill="rgb(245,242,240)"/>
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M20 21v20m10 -20v20m-10 -10h20"></path></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M40 31h10"></path><g class="terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M50 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M112.5 31h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" rx="10" ry="10" width="62.5" x="50.0" y="20"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="81.25" y="35">BEGIN</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M112.5 31h10"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M122.5 31h10"></path><g class="terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M132.5 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M169.5 31h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" rx="10" ry="10" width="37.0" x="132.5" y="20"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="151.0" y="35">IF</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M169.5 31h10"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M179.5 31h10"></path><g class="non-terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M189.5 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M303.0 31h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" width="113.5" x="189.5" y="20"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="246.25" y="35">name&#95;string</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M303.0 31h10"></path><g>
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M313.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M390.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M313.0 31h20"></path><g class="terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M333.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M370.0 31h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" rx="10" ry="10" width="37.0" x="333.0" y="20"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="351.5" y="35">==</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M370.0 31h20"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M313.0 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g class="terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M333.0 61h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M370.0 61h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" rx="10" ry="10" width="37.0" x="333.0" y="50"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="351.5" y="65">!=</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M370.0 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><g>
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M390.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M552.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M390.0 31h20"></path><g class="non-terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M410.0 31h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M532.0 31h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" width="122.0" x="410.0" y="20"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="471.0" y="35">value&#95;number</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M532.0 31h20"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M390.0 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path><g class="non-terminal">
<path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M410.0 61h0.0"></path><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M532.0 61h0.0"></path><rect stroke-width="3" stroke="black" fill="rgb(204,255,204)" height="22" width="122.0" x="410.0" y="50"></rect><text font-weight="bold" font-size="14px" font-family="monospace" text-anchor="middle" x="471.0" y="65">value&#95;string</text></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M532.0 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path></g><path stroke-width="3" stroke="black" fill="rgba(0,0,0,0)" d="M 552.0 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path></g></svg>

(displays okay in both the browser and Gnome's Image Viewer). The only slight problem in Inkscape is that the curved-paths appear to be drawn as a closed-shape, which makes them look a bit strange (like a squished figure-of-eight). But that might just be because I'm using an old v0.48 of Inkscape? 🤷‍♂️ It looks fine when opened in GIMP.
Note that I had to insert an extra rect for the background colour, as suggested by https://stackoverflow.com/questions/11293026/default-background-color-of-svg-root-element
EDIT: and I had to convert hsl to rgb

@tabatkins
Copy link
Owner Author

None of the paths are closed (they don't end with z command), so if they're drawing "solid" it means they have a non-transparent fill.

@lurch
Copy link
Contributor

lurch commented Mar 2, 2020

Ah, thanks for the hint. Did a bit more experimentation, and found that if I change fill="rgba(0,0,0,0)" to fill="none" then it finally displays correctly in Inkscape! 🎉

@tabatkins
Copy link
Owner Author

Okay, so an alternative approach: since my styling isn't complicated in the first place, I can replace it with a few "fake selectors", targetting each of the objects. So you'd specify it something like:

defaultStyle = {
  "line-color": "black",
  "line-width": "3px",
  "terminal-bg": "#ccffcc",
  ...
}

Then, if generating standalone, I can walk the graph and set attributes appropriately; otherwise, I can turn this into a stylesheet and append that, as appropriate.

@tabatkins tabatkins reopened this Mar 4, 2020
@lurch
Copy link
Contributor

lurch commented Mar 4, 2020

Happy to beta-test, when you have something ready 🙂

@tabatkins tabatkins changed the title Allow generating standalone SVG Inline the styles to be styling attributes when generating standalone SVG Apr 18, 2020
@dolmen
Copy link

dolmen commented Mar 22, 2022

As a workaround, I apply the following railroad-fix-svg.sed script to SVG files produced by the online service:

#!/usr/bin/sed -f
1 s@\([0-9]\)">@\1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">@
1 s@\(.*\)@\1\n<style type="text/css">@
1 r railroad.css
2 x
2 s@.*@</style>@p
2 x
$ sed -i '' -f railroad-fix-svg.sed my-railroad.svg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants
@dolmen @lurch @tabatkins @florianpircher and others