Skip to content

Instantly share code, notes, and snippets.

@vizee
Last active August 3, 2021 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vizee/fa9ed274215372fe8817c43326150559 to your computer and use it in GitHub Desktop.
Save vizee/fa9ed274215372fe8817c43326150559 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
)
type KmSize struct {
Width int `json:"width"`
Height int `json:"height"`
}
type KmData struct {
Id string `json:"id"`
Created int64 `json:"created"`
Text string `json:"text"`
Note string `json:"note"`
Image string `json:"image"`
ImageSize KmSize `json:"imageSize"`
ImageTitle string `json:"imageTitle"`
ExpandState string `json:"expandState"`
}
type KmNode struct {
Data KmData `json:"data"`
Children []KmNode `json:"children"`
}
type KmDoc struct {
Root KmNode `json:"root"`
}
func loadKmDoc(path string) (*KmDoc, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
var doc KmDoc
err = json.Unmarshal(data, &doc)
if err != nil {
return nil, err
}
return &doc, nil
}
func nodeToMarkdown(out io.Writer, node *KmNode, level int) error {
if len(node.Children) == 0 || level > 4 {
fmt.Fprintf(out, "%s\n\n", node.Data.Text)
} else {
title := node.Data.Text
if title == "" {
title = node.Data.Id
}
fmt.Fprintf(out, "%s %s\n\n", strings.Repeat("#", level), title)
}
if node.Data.Image != "" {
fmt.Fprintf(out, "![%s](%s)\n\n", node.Data.ImageTitle, node.Data.Image)
}
if node.Data.Note != "" {
fmt.Fprintf(out, "%s\n\n", node.Data.Note)
}
for _, child := range node.Children {
if err := nodeToMarkdown(out, &child, level+1); err != nil {
return err
}
}
return nil
}
func convertMarkdown(doc *KmDoc, out io.Writer) error {
fmt.Fprintf(out, "# %s\n\n", doc.Root.Data.Text)
fmt.Fprintf(out, "---\n\n")
for _, node := range doc.Root.Children {
if err := nodeToMarkdown(out, &node, 1); err != nil {
return err
}
}
return nil
}
func main() {
var (
infile string
outfile string
)
flag.StringVar(&infile, "i", "in.km", "input file")
flag.StringVar(&outfile, "o", "out.md", "output file")
flag.Parse()
doc, err := loadKmDoc(infile)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
var out io.Writer
if outfile == "-" {
out = os.Stdout
} else {
f, err := os.Create(outfile)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer f.Close()
out = f
}
err = convertMarkdown(doc, out)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment