0

I'm very new to HTML...just started yesterday. The problem I'm having is that when I'm importing an SVG into my HTML script, the text gets all gargled. For example, Peak Metagene Plot becomes 2eak MetaCene 2lot. It's almost like certain letters are changed.

I have made a python script to read in an SVG file like such (I'm calling in two SVGs here, violin and metagene_reads):

# violin

if args['--violin']:
    violin_file = open(args['--violin'], 'r')
    violin_txt = violin_file.read()
    violin_hide = ''
else:
    violin_txt = ''
    violin_hide = 'hidden'

# metagene reads

if args['--metagene_reads']:
    metagene_reads_file = open(args['--metagene_reads'], 'r')
    metagene_reads_txt = metagene_reads_file.read()
    metagene_reads_hide = ''
else:
    metagene_reads_txt = ''
    metagene_reads_hide = 'hidden'

I then use this code to feed into an HTML template. Without pasting the entire code, I'll only list the contents that are giving me the weird text:

Specify font type...

<!DOCTYPE html>
<html>
<h1><link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.18/css/jquery.dataTables.css">
<style>
td {
  text-align: center;
  vertical-align: middle;
}
h1 {
  font-size: 36px;
  font-weight: bold;
  font-family: Georgia, Times, "Times New Roman", serif;
}
h2 {
  font-size: 24px;
  font-family: Georgia, Times, "Times New Roman", serif;
}
h3 {
  margin-bottom: 0px;
  padding: 0px;
  margin-left: 300px;
  font-size: 24px;
  font-family: Georgia, Times, "Times New Roman", serif;
}
.initiallyHidden { display: none; }
.toggle {
    background-color: #4CAF50;
    border: none;
    color: white;
    padding: 8px 20px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 12px;
    margin-bottom: 20px;
}

....other contents like tables, etc.

Below is where I'm importing the SVGs called in from the python script (code shown above). This is where I'm getting the weird formatting issues.

<br>
{{metagene_reads_txt}}
<br>
<h2 {{metagene_peaks_hide}}><center>MultipleMetagene Peaks Plot</center></h2>
<p {{metagene_peaks_hide}}> 
<br>
<button class="toggle" onclick="metagenePeaks()">Click to learn more</button>
<div id="metagenePeaksID" class="initiallyHidden">
The multiple metagene peaks plot illustrates the average peak coverage of 5' UTR, CDS, and 3' UTR features.
</div>
<script>
function metagenePeaks() {
    var x = document.getElementById("metagenePeaksID");
    display = x.style.display;
    x.style.display = (display && display !== 'none') ? 'none' : 'block';
}
</script>
<br>
{{metagene_peaks_txt}}
<br>
<h2 {{violin_hide}}><center>Gene Count Violin Plot</center></h2>
<p {{violin_hide}}> 
<br>
<button class="toggle" onclick="violinFunction()">Click to learn more</button>
<div id="violinDIV" class="initiallyHidden">
The violin plot illustrates the distribution of gene counts for each sample. The gene counts were normalized for differences in library depth and log transformed.
</div>
<script>
function violinFunction() {
    var x = document.getElementById("violinDIV");
    display = x.style.display;
    x.style.display = (display && display !== 'none') ? 'none' : 'block';
}
</script>
<br>
{{violin_txt}}
<br>
</p>
</body>
</html>

Any help would be greatly appreciated.

1 Answers1

0

What you are doing right now is taking SVG content, something like this:

<svg version="1.1"
     baseProfile="full"
     width="300" height="200"
     xmlns="http://www.w3.org/2000/svg">
  <rect width="100%" height="100%" fill="black" />
  <circle cx="150" cy="100" r="90" fill="blue" />
</svg>

And just copy+pasting that into the HTML, which the browser does not understand.

Instead, you should be linking to the SVG file using something like this (although depending on how this is hosted the relative path may need to be adjusted):

<img src="{{violin_file}}">

If you really want to embed it within the code (which I generally do not recommend), you can Base64 Encode it and embed that, something like this:

import base64

with open(violin_file, "rb") as image_file:
    violin_base64 = str(base64.b64encode(image_file.read()),'utf-8')

And then instead of {{violin_txt}} you would do:

<img src="data:image/svg+xml;base64,{{violin_base64}}" />
Daniel Centore
  • 3,220
  • 1
  • 18
  • 39
  • When I try to use the Base64 Encode method, the images show up as broken images in my HTML. Any idea why? Example: https://cdn-codespeedy.pressidium.com/wp-content/uploads/2019/03/Chrome-Broken-Image-Icon.png – xovaw85242 Oct 13 '21 at 01:57
  • @xovaw85242 Could you link me to the image you are trying to use? It would also be helpful if you `print(violin_txt)` and share the output to confirm it is as expected – Daniel Centore Oct 13 '21 at 02:04
  • Thanks, Daniel. Here is one of the violin.svg files I'm trying to incorporate into the HTML. https://easyupload.io/2lz2ud The output of violin_txt is here: https://easyupload.io/z8u4b0 – xovaw85242 Oct 13 '21 at 02:25
  • @xovaw85242 I modified my answer to use `violin_base64 = str(...,'utf-8')`, incorporating the fix from here: https://stackoverflow.com/a/42303447/998251 – Daniel Centore Oct 13 '21 at 06:18