Open l-althueser opened 3 weeks ago
Hi @l-althueser
I had to trim the first few lines of the SVG file as it starts with
Ah ok. Good that you mention this. In my set_svg
I should remove the xml and comment tags automatically, because it is indeed ok that the injected svg contains it.
Inkscape has the nasty feature of putting any text in spans
Could you share with me a piece of your svg that shows how something like that looks like?
Just to make sure I understand your problem correctly...
Thanks!
Hi!
I attached the full test file that I use at the moment. This is just plain Inkscape and adding some text components with no extra styling or conversion. A typical text component would be:
<text
xml:space="preserve"
id="LS1_InB"
style="white-space:pre;shape-inside:url(#rect2-6-7);display:inline;fill:#000000"
transform="translate(-169.91543,-33.586677)"><tspan
x="255"
y="214.94796"
id="tspan4">000.00</tspan></text>
Inkscape uses some transform and span logic to place the text field in the correct position - removing either screws up the format. Therefore, I want to avoid deleting the html components inside the text content of the text field :)
This is the full svg file:
So you want to set the content of the text element with id "LS1_InB", but that contains a tspan element with id "tspan4". I would think that you change the "tpsan4" to e.g. "LS1_InB_tspan"? Or perhaps the tspan is nowhere visible in Inkscape, and generated automatically. In the latter case I understand your fix in my code and I will adopt it...
Right! The naming and placement are automatically performed by Inkscape itself and not visible to the user. There is also no option in Inkscape to avoid the span elements. Unfortunately, I have to rely on Inkscape for these special cases as the future maintainers of the SVG files have no other paid software that handles the files better. Now that you saying it, we might be able to query for any tspan object inside the innerHTML and go recursively to the text element and just change that - no need for the html parsing. But you are the expert in that field and I would love to see a solution implemented in your node. Thanks!
@l-althueser,
I started implementing a solution for your problem, but I wanted to have something reusable for other use cases. Because in the past I added some workarounds for very specific use cases in the old svg node, which I regretted a lot later on.
There are various SVG editors around, each with their own dialects. And these dialects can change over time, in new versions of these tools. I can not support all these weird combinations unfortunately...
Then I suddenly realized that I don't need to change anything to solve this, because you can easily use a dedicated css selector!
For a simple text
element (with id "my_text") containing text:
"command": "set_text",
"selector": "#my_text",
"text": "Text content updated"
For a text
element (with id "my_text"), which has a single tspan
child element (which contains the text):
"command": "set_text",
"selector": "#my_text > tspan",
"text": "Tspan content updated"
This is how you can use it for Inkscape drawings.
For a text
element (with id "my_text"), which has multiple tspan
child elements (from which the first one contains the text):
"command": "set_text",
"selector": "#my_text > tspan:first-child",
"text": "Tspan content updated"
And so on...
This way we can keep the code simple, and still support numerous use cases.
And if you don't know how to write a custom css selector for some use case, just ask ChatGpt ;-)
Here is an example flow for Inkscape:
[{"id":"51b14b784794954b","type":"inject","z":"f624e6564f974a57","name":"Add text element with tspan child","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"add_element\",\"type\":\"text\",\"id\":\"my_text\",\"attributes\":{\"x\":\"250\",\"y\":\"50\"}},{\"command\":\"add_element\",\"type\":\"tspan\",\"parentSelector\":\"#my_text\",\"style\":{\"fill\":\"red\",\"text-anchor\":\"middle\",\"dominant-baseline\":\"middle\",\"font-size\":\"30px\",\"font-style\":\"italic\",\"font-family\":\"serif\"},\"text\":\"A tspan child for a text element\"}]","payloadType":"json","x":950,"y":1420,"wires":[["9a338535ec8313b6"]]},{"id":"9a338535ec8313b6","type":"ui-svg","z":"f624e6564f974a57","name":"","group":"65805ec358e05ea4","width":0,"height":0,"x":1170,"y":1420,"wires":[["1a204e0ea61e1371"]]},{"id":"86f29f3f65dc2ff2","type":"inject","z":"f624e6564f974a57","name":"Get text","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"get_text\",\"selector\":\"#my_text > tspan\"}]","payloadType":"json","x":1030,"y":1460,"wires":[["9a338535ec8313b6"]]},{"id":"918b284798103b7d","type":"inject","z":"f624e6564f974a57","name":"Set text","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"set_text\",\"selector\":\"#my_text > tspan\",\"text\":\"Tspan content updated\"}]","payloadType":"json","x":1030,"y":1500,"wires":[["9a338535ec8313b6"]]},{"id":"1a204e0ea61e1371","type":"debug","z":"f624e6564f974a57","name":"Text content","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1330,"y":1420,"wires":[]},{"id":"5409476d82196839","type":"comment","z":"f624e6564f974a57","name":"Inkscape text with tspan demo","info":"","x":960,"y":1380,"wires":[]},{"id":"65805ec358e05ea4","type":"ui-group","name":"SVG demos","page":"0a90f52e8742b298","width":"10","height":"10","order":-1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"0a90f52e8742b298","type":"ui-page","name":"SVG","ui":"be29745a6e568f30","path":"/page2","icon":"home","layout":"grid","theme":"092547d34959327c","order":-1,"className":"","visible":"true","disabled":"false"},{"id":"be29745a6e568f30","type":"ui-base","name":"UI Name","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false},{"id":"092547d34959327c","type":"ui-theme","name":"Theme Name","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"}}]
By inspecting the svg - using your browser's developer tools - you can easily see that this way the content of the nested tspan
element has been updated:
I will create later on a wiki page about this, to assist others with a similar issue.
Hi there and many thanks for making this project!
I was injecting an Inkscape SVG to the SVG node and noticed that I had to trim the first few lines of the SVG file as it starts with:
instead of just
<svg
. This is an easy fix on the client side but then I noticed that Inkscape has the nasty feature of putting any text in spans which would be removed in the current version. Can I propose to change the setText function to something like the following? I am pretty sure there are some better ways to do it but this seems to work:What do you think? Thanks!