matthiaskoenig / libsbgn-python

Python bindings for libsbgn
GNU Lesser General Public License v3.0
6 stars 0 forks source link

Preventing markup being re-marked-up #38

Open carissableker opened 3 years ago

carissableker commented 3 years ago

Is there any way to mark text as safe (in labels). I have labels with already replaced text, and when saving the xml, the &'s are again replaced as & for example

β is changed to β in the export.

I think the issue lies in this function: https://github.com/matthiaskoenig/libsbgn-python/blob/4d28cf300aaaeb1cab9fe027c21f9e58c2e29acd/src/libsbgnpy/libsbgn.py#L481-L493

called here: https://github.com/matthiaskoenig/libsbgn-python/blob/4d28cf300aaaeb1cab9fe027c21f9e58c2e29acd/src/libsbgnpy/libsbgn.py#L1379

matthiaskoenig commented 3 years ago

@carissableker Yes, I can fix this. Could you send an example script/file which shows the problem, so I can reproduce and debug the issue.

carissableker commented 3 years ago

All the following code is in the attached notebook. libsbgn-python-issues-38.ipynb.zip

This was a little more complicated than I thought :smile: --my html markdown (&beta;) is not compatible with xml, so I need to instead use the decimal value (&#946;) \<source>

Anyway, here is a small example code:

import libsbgnpy.libsbgn as libsbgn
from libsbgnpy.libsbgnTypes import Language, GlyphClass, ArcClass
from libsbgnpy import render, utils

sbgn = libsbgn.sbgn()

sbgn_map = libsbgn.map()
sbgn_map.set_language(Language.PD)
sbgn_map.set_bbox(libsbgn.bbox(x=0, y=0, w=600, h=200))
sbgn.set_map(sbgn_map)

g1 = libsbgn.glyph(class_=GlyphClass.MACROMOLECULE, id='glyph1')
g1.set_label(libsbgn.label(text='&#945;/&#946; hydrolase'))
g1.set_bbox(libsbgn.bbox(x=5, y=70, w=160, h=60))
sbgn_map.add_glyph(g1)

g2 = libsbgn.glyph(class_=GlyphClass.MACROMOLECULE, id='glyph2')
g2.set_label(libsbgn.label(text='5&#8242;-3&#8242; exoribonuclease'))
g2.set_bbox(libsbgn.bbox(x=435, y=70, w=160, h=60))
sbgn_map.add_glyph(g2)

g3 = libsbgn.glyph(class_=GlyphClass.PROCESS, id='glyph3')
g3.set_bbox(libsbgn.bbox(x=300, y=90, w=20, h=20))
g3.add_port(libsbgn.port(id="glyph3.1", x=285, y=100))
g3.add_port(libsbgn.port(id="glyph3.2", x=315, y=100))
sbgn_map.add_glyph(g3)

a = libsbgn.arc(class_=ArcClass.CONSUMPTION, source="glyph1", target="glyph3.1", id="arc1")
a.set_start(libsbgn.startType(x=165, y=100))
a.set_end(libsbgn.endType(x=285, y=100))
sbgn_map.add_arc(a)

a = libsbgn.arc(class_=ArcClass.PRODUCTION, source="glyph3.2", target="glyph2", id="arc2")
a.set_start(libsbgn.startType(x=315, y=100))
a.set_end(libsbgn.endType(x=435, y=100))
sbgn_map.add_arc(a)

sbgn_str = utils.write_to_string(sbgn)
print(sbgn_str)
render.render_sbgn(sbgn, image_file="test38.png", file_format="png")

This produces the following xml:

<?xml version="1.0" encoding="UTF-8"?>
<sbgn xmlns="http://sbgn.org/libsbgn/0.2">
    <map language="process description">
        <bbox w="600." h="200." x="0." y="0."/>
        <glyph class="macromolecule" id="glyph1">
            <label text="&amp;#945;/&amp;#946; hydrolase"/>
            <bbox w="160." h="60." x="5." y="70."/>
        </glyph>
        <glyph class="macromolecule" id="glyph2">
            <label text="5&amp;#8242;-3&amp;#8242; exoribonuclease"/>
            <bbox w="160." h="60." x="435." y="70."/>
        </glyph>
        <glyph class="process" id="glyph3">
            <bbox w="20." h="20." x="300." y="90."/>
            <port id="glyph3.1" x="285." y="100."/>
            <port id="glyph3.2" x="315." y="100."/>
        </glyph>
        <arc class="consumption" id="arc1" source="glyph1" target="glyph3.1">
            <start x="165." y="100."/>
            <end x="285." y="100."/>
        </arc>
        <arc class="production" id="arc2" source="glyph3.2" target="glyph2">
            <start x="315." y="100."/>
            <end x="435." y="100."/>
        </arc>
    </map>
</sbgn>

And image: image

I edit the xml label texts (replacing the (&amp;) :

import tempfile

fixed_sbgn_str = sbgn_str.replace("&amp;", "&")
print(fixed_sbgn_str)

with tempfile.NamedTemporaryFile(mode='w', suffix=".xml") as f:
    f.write(fixed_sbgn_str)
    f.seek(0)
    fixed_sbgn = utils.read_from_file(f.name)

render.render_sbgn(fixed_sbgn, image_file="test38-fix.png", file_format="png")

Resulting xml

<?xml version="1.0" encoding="UTF-8"?>
<sbgn xmlns="http://sbgn.org/libsbgn/0.2">
    <map language="process description">
        <bbox w="600." h="200." x="0." y="0."/>
        <glyph class="macromolecule" id="glyph1">
            <label text="&#945;/&#946; hydrolase"/>
            <bbox w="160." h="60." x="5." y="70."/>
        </glyph>
        <glyph class="macromolecule" id="glyph2">
            <label text="5&#8242;-3&#8242; exoribonuclease"/>
            <bbox w="160." h="60." x="435." y="70."/>
        </glyph>
        <glyph class="process" id="glyph3">
            <bbox w="20." h="20." x="300." y="90."/>
            <port id="glyph3.1" x="285." y="100."/>
            <port id="glyph3.2" x="315." y="100."/>
        </glyph>
        <arc class="consumption" id="arc1" source="glyph1" target="glyph3.1">
            <start x="165." y="100."/>
            <end x="285." y="100."/>
        </arc>
        <arc class="production" id="arc2" source="glyph3.2" target="glyph2">
            <start x="315." y="100."/>
            <end x="435." y="100."/>
        </arc>
    </map>
</sbgn>

And image I expect: image