Repository 'blast2html'
hg clone https://toolshed.g2.bx.psu.edu/repos/jankanis/blast2html

Changeset 16:db7e4ee3be03 (2014-05-13)
Previous changeset 15:648b3b7437da (2014-05-12) Next changeset 17:8e61627a87f1 (2014-05-13)
Commit message:
fix validation, reindent
modified:
blast_html.html.jinja
blast_html.py
b
diff -r 648b3b7437da -r db7e4ee3be03 blast_html.html.jinja
--- a/blast_html.html.jinja Mon May 12 17:33:08 2014 +0200
+++ b/blast_html.html.jinja Tue May 13 12:22:35 2014 +0200
[
b'@@ -4,10 +4,10 @@\n     <meta charset="UTF-8">\n     \n     <title>Blast output</title>\n-\n+    \n     <style>\n       body {\n-      color: #33333;\n+      color: #333333;\n       font-family: Arial,Sans-Serif;\n       }\n \n@@ -86,20 +86,18 @@\n \n \n       \n+      .graphics .grey {\n+      text-align: center;\n+      }\n+\n       .graphic {\n       background-color: white;\n       border: 2px solid black;\n       padding: .5em 1.5em;\n-      align: center;\n       margin: auto;\n       }\n \n-      #graphics .grey {\n-      text-align: center;\n-      }\n-\n       .centered, #defline, div.legend, div.tablewrapper {\n-      align: center;\n       margin-left: auto;\n       margin-right: auto;\n       }\n@@ -250,7 +248,7 @@\n       }\n \n       .title .hittitle {\n-      color: #22222;\n+      color: #222222;\n       margin-bottom: .3em;\n       }\n       .title .titleinfo {\n@@ -331,11 +329,11 @@\n \n     <script type="text/javascript">\n       function toggle_visibility(id) {\n-\t var e = document.getElementById(id);\n-\t if(e.style.display != \'block\')\n-\t    e.style.display = \'block\';\n-\t else\n-\t    e.style.display = \'none\';\n+          var e = document.getElementById(id);\n+          if(e.style.display != \'block\')\n+              e.style.display = \'block\';\n+          else\n+              e.style.display = \'none\';\n       }\n     </script>\n \n@@ -346,29 +344,29 @@\n     <div id=content>\n       <h1>Nucleotide Sequence ({{length}} letters)</h1>\n \n-      <div id=header>\n+      <div class=header>\n \n         <table class=headerdata>\n           {% for param, value in params %}\n             <tr><td class=param>{{param}}:</td><td>{{value}}</td></tr>\n           {% endfor %}\n         </table>\n-          \n+        \n       </div>\n       \n       {% if not (blast.BlastOutput_iterations.findall(\'Iteration\') and\n                  blast.BlastOutput_iterations.Iteration.Iteration_hits.findall(\'Hit\')) %}\n-      <div id=nodata>\n-\t<h2>No Results</h2>\n-\t<div class=grey>\n-\t  No Matches\n-\t</div>\n+      <div class=nodata>\n+        <h2>No Results</h2>\n+        <div class=grey>\n+          No Matches\n+        </div>\n       </div>\n       {% else %}\n \n \n       \n-      <div id=graphics>\n+      <div class=graphics>\n         <h2>Graphic Summary</h2>\n \n         <div class=grey>\n@@ -378,41 +376,40 @@\n \n           <div class=graphic>\n             <h4 class=darkHeader>Color key for alignment scores</h4>\n-\t    <div class=legend><div class=graphicrow>\n-\t\t<div class=graphicitem style="background-color: {{colors[0]}}">&lt;40</div>\n-\t\t<div class=graphicitem style="background-color: {{colors[1]}}">40\xe2\x80\x9350</div>\n-\t\t<div class=graphicitem style="background-color: {{colors[2]}}">50\xe2\x80\x9380</div>\n-\t\t<div class=graphicitem style="background-color: {{colors[3]}}">80\xe2\x80\x93200</div>\n-\t\t<div class=graphicitem style="background-color: {{colors[4]}}">200\xe2\x89\xa4</div>\n+            <div class=legend><div class=graphicrow>\n+                <div class=graphicitem style="background-color: {{colors[0]}}">&lt;40</div>\n+                <div class=graphicitem style="background-color: {{colors[1]}}">40\xe2\x80\x9350</div>\n+                <div class=graphicitem style="background-color: {{colors[2]}}">50\xe2\x80\x9380</div>\n+                <div class=graphicitem style="background-color: {{colors[3]}}">80\xe2\x80\x93200</div>\n+                <div class=graphicitem style="background-color: {{colors[4]}}">200\xe2\x89\xa4</div>\n             </div></div>\n-\t    <div style="clear: left"></div>\n+            <div style="clear: left"></div>\n \n             <div class=tablewrapper>\n \n               <div class=scale>\n                 <div>query:</div>\n-\t\t<div class=graphicrow>\n-                    {% for s in queryscale %}\n-                    <div class=graphicitem\n-\t\t\t style="width: {{s.width|safe}}%">\n-\t\t      <div>{{s.label|safe}}</div>\n-\t\t    </div>\n-                    {% endfor %}\n-\t\t</div>\n-\t\t<div style="clear: left"></div>\n+                <div class=graphicrow>\n+                  {% for s in queryscale %}\n+                  <div class=graphicitem style="width: {{s.width}}%">\n+                '..b'<a class=showmoretitles onclick="toggle_visibility(\'moretitles{{hit.Hit_num}}\'); return false;" href=\'\'>\n-\t\tSee {{hit|othertitles|length}} more title(s)\n-\t      </a>\n+              {% if hit|othertitles|length %}\n+              <a class=showmoretitles onclick="toggle_visibility(\'moretitles{{hit.Hit_num|js_string_escape}}\'); return false;" href=\'\'>\n+                See {{hit|othertitles|length}} more title(s)\n+              </a>\n \n-\t      <div class=moretitles id=moretitles{{hit.Hit_num}} style="display: none">\n-\t\t{% for title in hit|othertitles %}\n-\t\t<div class=title>\n-\t\t  <p class=hittitle>{{title.title}}</p>\n-\t\t  <p class=titleinfo>\n-\t\t    <span class=b>Sequence ID:</span> <a href="{{genelink(title.hitid)}}">{{title.id}}</a>\n-\t\t  </p>\n-\t\t</div>\n-\t\t{% endfor %}\n-\t      </div>\n-\t      {% endif %}\n+              <div class=moretitles id=moretitles{{hit.Hit_num}} style="display: none">\n+                {% for title in hit|othertitles %}\n+                <div class=title>\n+                  <p class=hittitle>{{title.title}}</p>\n+                  <p class=titleinfo>\n+                    <span class=b>Sequence ID:</span> <a href="{{genelink(title.hitid)}}">{{title.id}}</a>\n+                  </p>\n+                </div>\n+                {% endfor %}\n+              </div>\n+              {% endif %}\n \n-\t      {% for hsp in hit.Hit_hsps.Hsp %}\n-\t      <div class=hotspot>\n-\t\t<p class=range>\n-\t\t  <span class=range>Range {{hsp.Hsp_num}}: {{hsp[\'Hsp_hit-from\']}} to {{hsp[\'Hsp_hit-to\']}}</span>\n-\t\t  <a class=range href="{{genelink(hit|hitid, \'genbank\', hsp)}}">GenBank</a>\n-\t\t  <a class=range href="{{genelink(hit|hitid, \'graph\', hsp)}}">Graphics</a>\n-\t\t</p>\n+              {% for hsp in hit.Hit_hsps.Hsp %}\n+              <div class=hotspot>\n+                <p class=range>\n+                  <span class=range>Range {{hsp.Hsp_num}}: {{hsp[\'Hsp_hit-from\']}} to {{hsp[\'Hsp_hit-to\']}}</span>\n+                  <a class=range href="{{genelink(hit|hitid, \'genbank\', hsp)}}">GenBank</a>\n+                  <a class=range href="{{genelink(hit|hitid, \'graph\', hsp)}}">Graphics</a>\n+                </p>\n \n-\t\t<table class=hotspotstable>\n-\t\t  <tr>\n-\t\t    <th>Score</th><th>Expect</th><th>Identities</th><th>Gaps</th><th>Strand</th>\n-\t\t  </tr>\n-\t\t  <tr>\n-\t\t    <td>{{hsp[\'Hsp_bit-score\']|fmt(\'.1f\')}} bits({{hsp.Hsp_score}})</td>\n-\t\t    <td>{{hsp.Hsp_evalue|fmt(\'.1f\')}}</td>\n-\t\t    <td>{{ hsp.Hsp_identity }}/{{ hsp|len }}({{\n-\t\t      (hsp.Hsp_identity/hsp|len) |fmt(\'.0%\') }})</td>\n-\t\t    <td>{{ hsp.Hsp_gaps }}/{{ hsp|len\n-\t\t      }}({{ (hsp.Hsp_gaps / hsp|len) | fmt(\'.0%\') }})</td>\n-\t\t    <td>{{ hsp[\'Hsp_query-frame\']|asframe }}/{{ hsp[\'Hsp_hit-frame\']|asframe }}</td>\n-\t\t  </tr>\n-\t\t</table>\n+                <table class=hotspotstable>\n+                  <tr>\n+                    <th>Score</th><th>Expect</th><th>Identities</th><th>Gaps</th><th>Strand</th>\n+                  </tr>\n+                  <tr>\n+                    <td>{{hsp[\'Hsp_bit-score\']|fmt(\'.1f\')}} bits({{hsp.Hsp_score}})</td>\n+                    <td>{{hsp.Hsp_evalue|fmt(\'.1f\')}}</td>\n+                    <td>{{ hsp.Hsp_identity }}/{{ hsp|len }}({{\n+                      (hsp.Hsp_identity/hsp|len) |fmt(\'.0%\') }})</td>\n+                    <td>{{ hsp.Hsp_gaps }}/{{ hsp|len\n+                      }}({{ (hsp.Hsp_gaps / hsp|len) | fmt(\'.0%\') }})</td>\n+                    <td>{{ hsp[\'Hsp_query-frame\']|asframe }}/{{ hsp[\'Hsp_hit-frame\']|asframe }}</td>\n+                  </tr>\n+                </table>\n \n-\t\t<pre class=alignmentgraphic>{{hsp|alignment_pre}}</pre>\n-\t      </div>\n-\t      {% endfor %}\n-\t      \n-\t    </div>\n+                <pre class=alignmentgraphic>{{hsp|alignment_pre}}</pre>\n+              </div>\n+              {% endfor %}\n+              \n+            </div>\n \n-\t    {% endfor %}\n-\t</div></div>\n+            {% endfor %}\n+        </div></div>\n       </div>\n \n       {% endif %}\n@@ -540,3 +537,9 @@\n   </body>\n </html>\n \n+{#\n+Local Variables:\n+tab-width: 2\n+indent-tabs-mode: nil\n+End:\n+#}\n'
b
diff -r 648b3b7437da -r db7e4ee3be03 blast_html.py
--- a/blast_html.py Mon May 12 17:33:08 2014 +0200
+++ b/blast_html.py Tue May 13 12:22:35 2014 +0200
[
@@ -94,8 +94,44 @@
     link = "http://www.ncbi.nlm.nih.gov/nucleotide/{}?report={}&log$=nuclalign".format(hit, type)
     if hsp != None:
         link += "&from={}&to={}".format(hsp['Hsp_hit-from'], hsp['Hsp_hit-to'])
-    return jinja2.Markup(link)
+    return link
+
+
+# javascript escape filter based on Django's, from https://github.com/dsissitka/khan-website/blob/master/templatefilters.py#L112-139
+# I've removed the html escapes, since html escaping is already being performed by the template engine.
 
+_base_js_escapes = (
+    ('\\', r'\u005C'),
+    ('\'', r'\u0027'),
+    ('"', r'\u0022'),
+    # ('>', r'\u003E'),
+    # ('<', r'\u003C'),
+    # ('&', r'\u0026'),
+    # ('=', r'\u003D'),
+    # ('-', r'\u002D'),
+    # (';', r'\u003B'),
+    # (u'\u2028', r'\u2028'),
+    # (u'\u2029', r'\u2029')
+)
+
+# Escape every ASCII character with a value less than 32. This is
+# needed a.o. to prevent parsers from jumping out of javascript
+# parsing mode.
+_js_escapes = (_base_js_escapes +
+               tuple(('%c' % z, '\\u%04X' % z) for z in range(32)))
+
+@filter
+def js_string_escape(value):
+    """Escape javascript string literal escapes. Note that this only works
+    within javascript string literals, not in general javascript
+    snippets."""
+
+    value = str(value)
+
+    for bad, good in _js_escapes:
+        value = value.replace(bad, good)
+
+    return value
 
 
 
@@ -175,10 +211,10 @@
                 if table[i] == last:
                     count += 1
                     continue
-                matches.append((count * percent_multiplier, self.colors[last] if last != 255 else 'none'))
+                matches.append((count * percent_multiplier, self.colors[last] if last != 255 else 'transparent'))
                 last = table[i]
                 count = 1
-            matches.append((count * percent_multiplier, self.colors[last] if last != 255 else 'none'))
+            matches.append((count * percent_multiplier, self.colors[last] if last != 255 else 'transparent'))
 
             yield dict(colors=matches, link="#hit"+hit.Hit_num.text, defline=firsttitle(hit))