172 lines
3.7 KiB
Go
172 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type Block struct {
|
|
Type string
|
|
Data json.RawMessage
|
|
}
|
|
|
|
type Paragraph struct {
|
|
Text string
|
|
}
|
|
|
|
type Code struct {
|
|
Code string
|
|
}
|
|
|
|
type List struct {
|
|
Style string
|
|
Items []string
|
|
}
|
|
|
|
type Header struct {
|
|
Level int
|
|
Text string
|
|
}
|
|
|
|
type ChecklistItem struct {
|
|
Text string
|
|
Checked bool
|
|
}
|
|
|
|
type Checklist struct {
|
|
Style string
|
|
Items []ChecklistItem
|
|
}
|
|
|
|
type Link struct {
|
|
Link string
|
|
Meta LinkResponseMeta
|
|
}
|
|
|
|
type Table struct {
|
|
Content [][]string
|
|
}
|
|
|
|
type Document struct {
|
|
Time int64
|
|
Version string
|
|
Blocks []Block
|
|
}
|
|
|
|
func renderJSON(text string) (string, error) {
|
|
var data Document
|
|
err := json.Unmarshal([]byte(text), &data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
|
|
for _, block := range data.Blocks {
|
|
switch block.Type {
|
|
case "table":
|
|
var table Table
|
|
err = json.Unmarshal(block.Data, &table)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
|
|
buf.WriteString("<table class='table'>")
|
|
for _, row := range table.Content {
|
|
buf.WriteString("<tr>")
|
|
for _, col := range row {
|
|
buf.WriteString("<td>")
|
|
buf.WriteString(col)
|
|
buf.WriteString("</td>")
|
|
}
|
|
buf.WriteString("</tr>")
|
|
}
|
|
buf.WriteString("</table>")
|
|
break
|
|
case "link":
|
|
// TODO(peter): improve link rendering
|
|
var link Link
|
|
err = json.Unmarshal(block.Data, &link)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
fmt.Fprintf(&buf, `<a href=%q>%s</a>`, link.Link, link.Meta.Title)
|
|
case "list":
|
|
var list List
|
|
err = json.Unmarshal(block.Data, &list)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
var tag string
|
|
if list.Style == "ordered" {
|
|
tag = "ol"
|
|
} else {
|
|
tag = "ul"
|
|
}
|
|
buf.WriteString("<")
|
|
buf.WriteString(tag)
|
|
buf.WriteString(">")
|
|
for _, item := range list.Items {
|
|
buf.WriteString("<li>")
|
|
buf.WriteString(item)
|
|
buf.WriteString("</li>")
|
|
}
|
|
buf.WriteString("</")
|
|
buf.WriteString(tag)
|
|
buf.WriteString(">")
|
|
case "header":
|
|
var header Header
|
|
err = json.Unmarshal(block.Data, &header)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
fmt.Fprintf(&buf, "<h%d>%s</h%d>", header.Level, header.Text, header.Level)
|
|
case "paragraph":
|
|
var para Paragraph
|
|
err = json.Unmarshal(block.Data, ¶)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
buf.WriteString("<p>")
|
|
buf.WriteString(para.Text)
|
|
buf.WriteString("</p>")
|
|
case "code":
|
|
var code Code
|
|
err = json.Unmarshal(block.Data, &code)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
buf.WriteString("<pre>")
|
|
buf.WriteString(code.Code)
|
|
buf.WriteString("</pre>")
|
|
case "checklist":
|
|
var checklist Checklist
|
|
err = json.Unmarshal(block.Data, &checklist)
|
|
if err != nil {
|
|
return "", fmt.Errorf("error while parsing %s: %s", block.Type, err.Error())
|
|
}
|
|
for _, item := range checklist.Items {
|
|
buf.WriteString("<p>")
|
|
|
|
buf.WriteString(`<span class="icon is-medium">`)
|
|
if item.Checked {
|
|
buf.WriteString(` <span class="fa-stack">`)
|
|
buf.WriteString(` <i class="fa fa-circle fa-stack-2x has-text-success"></i>`)
|
|
buf.WriteString(` <i class="fa fa-check fa-stack-1x fa-inverse"></i>`)
|
|
buf.WriteString(` </span>`)
|
|
}
|
|
buf.WriteString(`</span>`)
|
|
buf.WriteString(item.Text)
|
|
buf.WriteString("</p>")
|
|
}
|
|
default:
|
|
return "", fmt.Errorf("unknown type: %s", block.Type)
|
|
}
|
|
|
|
fmt.Fprintln(&buf)
|
|
}
|
|
|
|
return buf.String(), nil
|
|
}
|