1 package bbcodehtml 2 3 import ( 4 "strings" 5 6 "vimagination.zapto.org/bbcode" 7 ) 8 9 type table struct{} 10 11 func (table) Name() string { 12 return "table" 13 } 14 15 var ( 16 tableOpen = []byte("<table>") 17 tableClose = []byte("</table>") 18 tableHeadOpen = []byte("<thead>") 19 tableHeadClose = []byte("</thead>") 20 tableFootOpen = []byte("<tfoot>") 21 tableFootClose = []byte("</tfoot>") 22 trOpen = []byte("<tr>") 23 trClose = []byte("</tr>") 24 tdOpen = []byte("<td>") 25 tdClose = []byte("</td>") 26 thOpen = []byte("<th>") 27 thClose = []byte("</th>") 28 ) 29 30 func (table) Handle(p *bbcode.Processor, attr string) { 31 p.Write(tableOpen) 32 tableHandle(p) 33 p.Write(tableClose) 34 } 35 36 func tableHandle(p *bbcode.Processor) { 37 var thead, tfoot bool 38 Loop: 39 for { 40 switch t := p.Get().(type) { 41 case bbcode.Text: 42 case bbcode.OpenTag: 43 if strings.EqualFold(t.Name, "thead") { 44 if !thead { 45 p.Write(tableHeadOpen) 46 tableIHandle(p, "thead") 47 p.Write(tableHeadClose) 48 49 thead = true 50 } 51 } else if strings.EqualFold(t.Name, "tfoot") { 52 if !tfoot { 53 p.Write(tableFootOpen) 54 tableIHandle(p, "tfoot") 55 p.Write(tableFootClose) 56 57 tfoot = true 58 } 59 } else if strings.EqualFold(t.Name, "row") || strings.EqualFold(t.Name, "tr") { 60 p.Write(trOpen) 61 tableRow(p, t.Name) 62 p.Write(trClose) 63 } 64 case bbcode.CloseTag: 65 if strings.EqualFold(t.Name, "table") { 66 break Loop 67 } 68 default: 69 break Loop 70 } 71 } 72 } 73 74 func tableIHandle(p *bbcode.Processor, tagName string) { 75 Loop: 76 for { 77 switch t := p.Get().(type) { 78 case bbcode.Text: 79 case bbcode.OpenTag: 80 if strings.EqualFold(t.Name, "row") || strings.EqualFold(t.Name, "tr") { 81 p.Write(trOpen) 82 tableRow(p, t.Name) 83 p.Write(trClose) 84 } 85 case bbcode.CloseTag: 86 if t.Name == tagName { 87 break Loop 88 } 89 default: 90 break Loop 91 } 92 } 93 } 94 95 func tableRow(p *bbcode.Processor, tagName string) { 96 Loop: 97 for { 98 switch t := p.Get().(type) { 99 case bbcode.Text: 100 case bbcode.OpenTag: 101 if strings.EqualFold(t.Name, "col") || strings.EqualFold(t.Name, "td") { 102 p.Write(tdOpen) 103 p.Process(t.Name) 104 p.Write(tdClose) 105 } else if strings.EqualFold(t.Name, "th") { 106 p.Write(thOpen) 107 p.Process(t.Name) 108 p.Write(thClose) 109 } 110 case bbcode.CloseTag: 111 if t.Name == tagName { 112 break Loop 113 } 114 default: 115 break Loop 116 } 117 } 118 } 119