0

Brand new to python and am running into an annoying formatting issue. I wrote a script that logs onto Confluence and posts content. Unfortunately, the Confluence page only recognizes HTML5 syntax and getting this formatted is taking me wayyy longer than I expected.

I edited the script to replace all \n characters with br \ characters, which gets me to something ugly, but respectable. To really tidy things up, I'd ideally like to just stick this entire thing inside a table.

I already outlined the HTML5 code that I want below, but I don't know the easiest/most efficient way of prepending these tags to my string header1 header 2 header3 header4 header 5 10 15 20 27 to/path/foo.c 7 67 10 22 to/path/boo.c ...etc without using some external Python module/library. Using Python 2.7.5, I believe.

HTML5 code to produce table below

 <table style="width:100%" \>
   <tr \>
     <th \>Header1
     <th \>Header2  
     <th \>Header3
     <th \>Header4
     <th \>Header5
   <tr \>
     <td \>10
     <td \>15
     <td \>20
     <td \>27
     <td \>to/path/foo.c
   <tr \>
     <td \>7
     <td \>67       
     <td \>10
     <td \>22
     <td \>to/path/boo.c
   <tr \>
     <td \>1
     <td \>2    
     <td \>3
     <td \>4    
     <td \>to/path/moo.c
   <tr \>
     <th \> Sum:
   <tr \>
     <td \>18
     <td \>84
     <td \>33
     <td \>53

myDesiredTableFormat

      Header1 Header2 Header3 Header4  Header5
           10      15      20      27   to/path/foo.c
            7      67      10      22   to/path/boo.c
            1       2       3       4   to/path/moo.c

      Sum:          
           18      84      33      53     

The way I am thinking of writing this script is:

  1. A nested for-loop (i.e. for every line/for every word)
  2. Prepend <table style="width:100%" \><tr \> to the variable that will store this table
  3. If word = header or sum...prepend <th \>
  4. Else word = number or file path...prepend <td \>
  5. Replace \n with <br \><tr \>.

Please tell me there is an easier, more efficient (or elegant way) to convert a string to an HTML5 table in Python (i.e. without using modules that I have to download...imports with the language are fine).

MrPickles
  • 1,085
  • 1
  • 15
  • 31
  • 1
    What format is your data in now? Where do you get the table contents from? – bytesized Jul 07 '15 at 02:08
  • 1
    I still don't understand. This is what it sounds like you are saying to me: "I already have a string containing an HTML5 table, I want to know how to append rows of data to the table". Is that correct? – bytesized Jul 07 '15 at 02:17
  • It's in the string `myString = header1 header 2 header3 header4 header 5
    10 15 20 27 to/path/foo.c
    7 67 10 22 to/path/boo.c ...etc` right now. This gives me something that looks like a table, but it's not aligned like a table should be.
    – MrPickles Jul 07 '15 at 02:18
  • @bytesized No. I have a string that looks like the string posted above. I want to prepend html5 tags to each word. What is the best way to do this in Python? – MrPickles Jul 07 '15 at 02:19
  • 1
    By the way, the `
    ` syntax is incorrect. What you are trying to use are self-closing tags but there are several things wrong. First, your slashes are backwards. Self closing tags look like this: `
    `. Second, you do not need them in HTML5. Third, you never need them on tags that already have a closing tag. (`
    ` has no close tag, it stands alone. `` needs a close tag and should not be 'self-closed'). See [this](http://stackoverflow.com/questions/3558119/are-self-closing-tags-valid-in-html5) for more
    – bytesized Jul 07 '15 at 02:25
  • @bytesized Thank you very much for the info. – MrPickles Jul 07 '15 at 02:30

1 Answers1

0

How about something like this:

string = "header1 header2 header3 header4 header5 <br \> 10 15 20 27 to/path/foo.c <br \> 7 67 10 22 to/path/boo.c"
rows = string.split("<br \>")
data = map(lambda r: r.split(" "), rows)
html_rows = map(lambda r: "<td>" + "</td><td>".join(r) + "</td>", data)
html_table = "<table><tr>" + "</tr><tr>".join(html_rows) + "</tr></table>"

EDIT: Oh wait, I forgot the header and sum rows

string = "header1 header2 header3 header4 header5 <br \> 10 15 20 27 to/path/foo.c <br \> 7 67 10 22 to/path/boo.c"
// Make array of rows
rows = string.split("<br \>")
rows = map(lambda r: r.strip(" "), rows)
// Make array of arrays of column data
data = map(lambda r: r.split(" "), rows)
// The first row is header data; remove it
header_data = data.pop(0)
// HTML-ize each row
header_rows = "<th>" + "</th><th>".join(header_data) + "</th>"
html_rows = map(lambda r: "<td>" + "</td><td>".join(r) + "</td>", data)
// Concatenate everything into one table, but do not close it yet
html_table = "<table><tr>" + header_rows + "</tr><tr>" + "</tr><tr>".join(html_rows) + "</tr>"
// Total data and put it in Sum row
html_table += "<tr><th>Sum</th></tr>"
sums = [0, 0, 0, 0]
for row in data:
    sums[0] += int(row[0])
    sums[1] += int(row[1])
    sums[2] += int(row[2])
    sums[3] += int(row[3])

sums = map(str, sums)
// Add summation data and close the table
html_table += "<tr>" + "</tr><tr>".join(sums) + "</tr></table>"

Keep in mind, this code depends on the separators being very consistent: Once space between each column, the exact string <br \> between each row.

bytesized
  • 1,420
  • 11
  • 22
  • Wow, thank you so much. Commented and everything. Very impressive. – MrPickles Jul 07 '15 at 03:14
  • 1
    I just tested it with the input string in the first line and it looks ok. The main problems you may encounter are inconsistent separators (mentioned in answer) and separators within strings. You gave an example with `myString = header1 header 2 ...`. If there is a space between 'header' and '2', this will become two separate columns. – bytesized Jul 07 '15 at 03:18
  • Yes, thank you. I believe you want to `"".join(header_data) + ""` or else you'd wind up with back-to-back `` tags, btw. Same goes for the joining with the `` tags. – MrPickles Jul 07 '15 at 03:21
  • Oops. Typo. Good catch. – bytesized Jul 07 '15 at 04:45