Using SVG without converting to an image blob

If I paste SVG directly in, it doesn’t render well (in Chrome). In particular, text elements are not visible. If I load it as a file in Chrome, it shows fine. Copying the outer html of the svg element shows that all xmlns attributes were stripped by TW, which is what must have caused the text problems as I can’t find any styling issue that could have caused it.

I want to use svg as is so I can style it. Using content types or $$$ both turn the content into an image blob that I can’t style.

Can you share or attach it here?

Have you tried setting the type on the tiddler?

1 Like

Hi

The following works fine for me pasted into a tiddler as text of course - the tiddler has type image/svg+xml
If that works for you then maybe consider it as a starting point to be adapted to what you actually want.
If memory serves I created this in Inkscape but I probably stripped out some inkscape specifics to reduce file size - not sure it was a while ago.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   width="60.939331mm"
   height="49.75457mm"
   viewBox="0 0 60.939331 49.75457"
   version="1.1"
   id="svg7800">
  <defs
     id="defs7794">
    <linearGradient
       id="linearGradient8458">
      <stop
         style="stop-color:#ecbb01;stop-opacity:1;"
         offset="0"
         id="stop8454" />
      <stop
         style="stop-color:#ecbb01;stop-opacity:0;"
         offset="1"
         id="stop8456" />
    </linearGradient>
    <linearGradient
       id="linearGradient8421">
      <stop
         style="stop-color:#ecbb01;stop-opacity:1"
         offset="0"
         id="stop8449" />
      <stop
         style="stop-color:#e2b713;stop-opacity:0"
         offset="1"
         id="stop8451" />
    </linearGradient>
    <linearGradient
       xlink:href="#linearGradient8421"
       id="linearGradient8447"
       x1="385"
       y1="510"
       x2="485"
       y2="465"
       gradientUnits="userSpaceOnUse" />
    <linearGradient
       xlink:href="#linearGradient8458"
       id="linearGradient8460"
       x1="257.58906"
       y1="500.46663"
       x2="487.91095"
       y2="500.46663"
       gradientUnits="userSpaceOnUse" />
  </defs>
  <metadata
     id="metadata7797">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     id="layer1"
     transform="translate(-68.15377,-107.53784)">
    <path
       id="path8363"
       style="fill:url(#linearGradient8447);fill-opacity:1;stroke:url(#linearGradient8460);stroke-width:1.00157;stroke-opacity:1"
       d="M 373.74609,407.25781 263.01953,547.82812 a 114.66064,35.784565 0 0 0 -4.92969,10.37891 114.66064,35.784565 0 0 0 114.66016,35.7832 114.66064,35.784565 0 0 0 114.66016,-35.7832 114.66064,35.784565 0 0 0 -7.42188,-12.66601 z"
       transform="scale(0.26458333)" />
  </g>
</svg>

1 Like

Yes, sorry. At the bottom is an SVG. It has the text ‘Tiddlywiki’. The first screenshot is how it looks when pasted int Tiddlywiki.com, the second is when loaded from disk (after wrapping in html and body tags).

image
image

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="121px" viewBox="-0.5 -0.5 121 61">
  <defs/>
  <g>
    <rect x="0" y="0" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/>
    <g transform="translate(-0.5 -0.5)">
      <switch>
        <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
          <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 30px; margin-left: 1px;">
            <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
              <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tiddlywiki</div>
            </div>
          </div>
        </foreignObject>
        <text x="60" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tiddlywiki</text>
      </switch>
    </g>
  </g>
  <switch>
    <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
    <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
      <text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text>
    </a>
  </switch>
</svg>

When the tiddler has type image/svg+xml, TW will turn the svg into a data blob and use it as the src attribute of an img tag. This means it can’t be styled.

And here is the content after I copy from Chrome’s devtools while inspecting the TW result. You can see all the namespaces are gone:

<svg version="1.1" width="121px" viewBox="-0.5 -0.5 121 61">
  <defs/>
  <g>
    <rect x="0" y="0" width="120" height="60" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/>
    <g transform="translate(-0.5 -0.5)">
      <switch>
        <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
          <div style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 30px; margin-left: 1px;">
            <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
              <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Tiddlywiki</div>
            </div>
          </div>
        </foreignObject>
        <text x="60" y="34" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Tiddlywiki</text>
      </switch>
    </g>
  </g>
  <switch>
    <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
    <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
      <text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text>
    </a>
  </switch>
</svg>

Where does your SVG come from. Which editor do you use. It seems most of the content is used by the editor and doesn’t make too much sense for the SVG itself.

Especially the transform should go away completely, it’s mainly bloat. SVGOMG - SVGO's Missing GUI can help to optimize SVGs to use with TW.

There is an example at https://tiddlywiki.com/#Using%20SVG, which also contains an html text element. If I start from there my SVG would look like this:

<svg class="test-svg">
	<path fill="#FFF" stroke="#000" pointer-events="all" d="M0 0h120v60H0z"/>
<foreignObject x="10" y="20" width="110" height="40" ><body>[[link to a tiddler|HelloThere]].</body></foreignObject>
</svg>

If I would give the SVG a class=“test-svg” it should be able to style the different elements.

1 Like

I’m drawing diagrams with draw.io. It allows to export the diagram as SVG and read it again for further editing (given the SVG is the original).

So I’m trying to find a hassle free way to paste the exported SVG into a tiddler as an SVG so it can be styled and so I can copy later to draw.io to edit.

The same bloated SVG is loaded fine as a standalone document, I think it is TW manipulation (removing xmlns) that make it not render properly.

I took your above SVG text and in NotePad++ pasted it into an empty file and saved it as test.svg although I cant attach it here.

Importing this file imported a working SVG image, with no stripping.

  • We only need the items inside the <svg >...</svg> tags.

With a little work we could add an svg file to the tiddler exports https://tiddlywiki.com/#Creating%20a%20custom%20export%20format

  • However see below about draw.io files

Of note is you need to export a drawing to SVG, not save as. ie you will always edit your draw.io file not the svg, so you do not need to import the svg to draw IO.

In this example I exported a Draw.io flowchart as svg and imported it, it all works fine.
Then I exported the tiddler as JSON and it imports and works as well, attached.

Here is a raw exporter.

raw-file-exporter.json (699 Bytes)

It exports the current tiddler as a simple file containing the text in only in the file. Leave the file extension in the title eg test.svg so on export, the filename includes that extension eg; text.txt or other files should happily export the same. This exporter does not enforce a set extension.

I can now use this to export the SVG tiddler back out to a file, however as noted before to re-edit a draw io file keep it on one of its save as formats, not an export format, which is what svg is.

With an svg extension it will import correctly and add the type=image/svg+xml

[Edited] I would like to work out how to import an flowchart svg from draw.io and edit the boxes to include tiddlywiki internal and url external links, that would be cool.

  • Perhaps this can be done via html but we need to include some javascript support
    <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>

Thanks for the exporter. That’s neat.

When draw.io exports an SVG it also puts in all its raw content. I removed it to make the pasted content smaller.

I just tried to import an SVG and it imports it with the image/svg+xml content type, which means TW renders it as an where the src attribute has a data blob. This cannot be styled.

The solution is, I think, to be able to save SVG as is without turning it into and without stripping the xmlns. I couldn’t find a way to do that.

No problem @Ittayd, As I understand it the issue now remains in the format the SVG generator exports the SVG and what it includes?

What do you mean by the “Blob”?

In the image example shared above testdrawio.drawio.svg.json (13.3 KB) I see a section which looks like binary but otherwise no “blob”?

  • Attempt’s to edit out the binary failed.

When viewing the SVG in TW (that, is, the graphics), right click and choose Inspect. You will see the DOM contains an <img src="data:... tag.

1 Like

When viewing the SVG in TW (that, is, the graphics), right click and choose Inspect. You will see the DOM contains an <img src="data:... tag.

Right.

TBH, the explanation at https://tiddlywiki.com/#Using%20SVG covers the basics and why “img” versions of SVGs can’t be styled by external directives (sandboxed).

Personally I use most always inline SVG directly for easiest management.

A comment
T T

Yes, my problem is when using inline SVG, some text nodes are not displayed. I think it is because TW strips the xmlns attributes. I couldn’t find a way to disable it from doing so.

1 Like

If I get time i’ll look into it. No promises.

It is true that SVG in TW can be slightly confusing. Mainly because it can work with it several ways.

My GUESS is that it is not the lack of an xmnls directive causing the issue you are having. But it would be good to say what actually it is. Later.

TT

I do want to footnote that with a simple observation.

SVG orientated apps often add stuff to SVGs that THEY need, but that a browser doesn’t.
They assume the browser will ignore it.

Just a comment
TT

In your example removing “switch” and “/switch” (plain SVG) you do get text.

It may not be a full solution, but definitely a clue …

You get the imperfect …

Screenshot 2022-07-04 131426
But that can be adjusted.

Note. The Content Type here should be “text/vnd.tiddlywiki”, because it is used inline.

Best, TT

Thanks for looking into it! As mentioned, if I take the same SVG and load it directly in chrome (with or without wrapping it in html and body tags), the text is shown fine. So it seems to me this is not a Chrome issue. At first I suspected styling, but that doesn’t seem like it either.

If I take the SVG from the rendered dom (by ‘copy outerHTML’) then it doesn’t load in chrome with an error for the missing xmlns.

1 Like

This may be an issue but we’ll have to have a closer look. I’m testing with FF and Edge