CSV to HTML translation: Difference between revisions

Content added Content deleted
(Add Jsish, put Julia entry back into alphabetical order)
(Add a Python solution which makes proper use of the Python standard library and generates semantically proper HTML)
Line 4,356: Line 4,356:


=={{header|Python}}==
=={{header|Python}}==
(Note: rendered versions of both outputs are shown at the foot of this section).
(Note: rendered versions of all three outputs are shown at the foot of this section).
===Simple solution===
===Simple solution===
<lang python>csvtxt = '''\
<lang python>csvtxt = '''\
Line 4,442: Line 4,442:
<TBODY bgcolor="orange"><TR><TD>The multitude</TD><TD>Behold his mother! Behold his mother!</TD></TR></TBODY>
<TBODY bgcolor="orange"><TR><TD>The multitude</TD><TD>Behold his mother! Behold his mother!</TD></TR></TBODY>
</TABLE></lang>
</TABLE></lang>

===Robust solution===

This solution uses the CSV parser and HTML-capable XML serializer included in the Python standard library to produce the same fancy table as in the "extra credit" version.

Since the version of ElementTree in the standard library does not support pretty-printing, the output it produces is minified. Unlike the "extra credit" version, this doesn't put each <code>&lt;TR&gt;</code> element in its own <code>&lt;TBODY&gt;</code>.

<lang python>from csv import DictReader
from xml.etree import ElementTree as ET

def csv2html_robust(txt, header=True, attr=None):
# Use DictReader because, despite what the docs say, reader() doesn't
# return an object with .fieldnames
# (DictReader expects an iterable that returns lines, so split on \n)
reader = DictReader(txt.split('\n'))

table = ET.Element("TABLE", **attr.get('TABLE', {}))
thead_tr = ET.SubElement(
ET.SubElement(table, "THEAD", **attr.get('THEAD', {})),
"TR")
tbody = ET.SubElement(table, "TBODY", **attr.get('TBODY', {}))

if header:
for name in reader.fieldnames:
ET.SubElement(thead_tr, "TD").text = name

for row in reader:
tr_elem = ET.SubElement(tbody, "TR", **attr.get('TR', {}))

# Use reader.fieldnames to query `row` in the correct order.
# (`row` isn't an OrderedDict prior to Python 3.6)
for field in reader.fieldnames:
td_elem = ET.SubElement(tr_elem, "TD", **attr.get('TD', {}))
td_elem.text = row[field]

return ET.tostring(table, method='html')

htmltxt = csv2html_robust(csvtxt, True, {
'TABLE': {'border': "1", 'summary': "csv2html extra program output"},
'THEAD': {'bgcolor': "yellow"},
'TBODY': {'bgcolor': "orange"}
})

print(htmltxt.decode('utf8'))</lang>

'''Sample HTML output'''

<!--
The only difference between this and The output is semantically identical to the "extra credit" version, but whitespace has been collapsed as if it had been run through a minifier.
-->
<lang html5><TABLE border="1" summary="csv2html extra program output"><THEAD bgcolor="yellow"><TR><TD>Character</TD><TD>Speech</TD></TR></THEAD><TBODY bgcolor="orange"><TR><TD>The multitude</TD><TD>The messiah! Show us the messiah!</TD></TR><TR><TD>Brians mother</TD><TD>&lt;angry&gt;Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!&lt;/angry&gt;</TD></TR><TR><TD>The multitude</TD><TD>Who are you?</TD></TR><TR><TD>Brians mother</TD><TD>I'm his mother; that's who!</TD></TR><TR><TD>The multitude</TD><TD>Behold his mother! Behold his mother!</TD></TR></TBODY></TABLE></lang>


===HTML outputs rendered in firefox browser===
===HTML outputs rendered in firefox browser===