Skip to content

Instantly share code, notes, and snippets.

@hymkor
Created March 25, 2020 05:35

Revisions

  1. hymkor created this gist Mar 25, 2020.
    135 changes: 135 additions & 0 deletions scrapbox.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    package main

    import (
    "encoding/json"
    "flag"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "path/filepath"
    "strings"
    "time"
    )

    var optionOutputDir = flag.String("d", "", "directory where files output")

    type ScrapboxPage struct {
    Title string `json:"title"`
    Created int64 `json:"created"`
    Updated int64 `json:"updated"`
    Lines []string `json:"lines"`
    }

    type ScrapboxJson struct {
    Name string `json:"name"`
    DisplayName string `json:"displayName"`
    Exported int64 `json:"exported"`
    Pages []*ScrapboxPage `json:"pages"`
    }

    func (this *ScrapboxJson) Read(r io.Reader) error {
    bin, err := ioutil.ReadAll(r)
    if err != nil {
    return err
    }
    err = json.Unmarshal(bin, this)
    if err != nil {
    return err
    }
    return nil
    }

    func (this *ScrapboxJson) Load(fname string) error {
    fd, err := os.Open(fname)
    if err != nil {
    return err
    }
    defer fd.Close()

    err = this.Read(fd)
    if err != nil {
    return err
    }
    return nil
    }

    func (page *ScrapboxPage) WriteTo(w io.Writer) (int64, error) {
    n, _ := fmt.Fprintf(w, "Subject: %s\n", page.Title)
    n1, _ := fmt.Fprintf(w, "Created: %s\n", time.Unix(page.Created, 0).Format(time.ANSIC))
    n += n1
    n1, _ = fmt.Fprintf(w, "Updated: %s\n", time.Unix(page.Updated, 0).Format(time.ANSIC))
    n += n1
    n1, _ = fmt.Fprintln(w)
    n += n1
    for _, line := range page.Lines {
    n1, _ = fmt.Fprintln(w, line)
    n += n1
    }
    return int64(n), nil
    }

    var forbiddens = strings.NewReplacer(
    `\`, `¥`,
    `/`, `/`,
    `:`, `:`,
    `*`, `*`,
    `?`, `?`,
    `"`, `”`,
    `<`, `<`,
    `>`, `>`,
    `|`, `|`)

    func safeFileName(name string) string {
    return forbiddens.Replace(name)
    }

    func main1(fname string) error {
    var sbox ScrapboxJson
    if err := sbox.Load(fname); err != nil {
    return fmt.Errorf("%s: %w", fname, err)
    }

    if *optionOutputDir != "" {
    for _, page := range sbox.Pages {
    ofname := filepath.Join(
    *optionOutputDir, safeFileName(page.Title)+".txt")
    fd, err := os.Create(ofname)
    if err != nil {
    return fmt.Errorf("%s: Create: %w", ofname, err)
    }
    if _, err := page.WriteTo(fd); err != nil {
    fd.Close()
    return fmt.Errorf("%s: %w", ofname, err)
    }
    if err := fd.Close(); err != nil {
    return fmt.Errorf("%s: Close: %w", ofname, err)
    }
    }
    return nil
    }
    for i, page := range sbox.Pages {
    if i > 0 {
    fmt.Println("\f")
    }
    page.WriteTo(os.Stdout)
    }
    return nil
    }

    func mains(args []string) error {
    for _, fname := range args {
    if err := main1(fname); err != nil {
    return fmt.Errorf("%s: %w", fname, err)
    }
    }
    return nil
    }

    func main() {
    flag.Parse()
    if err := mains(flag.Args()); err != nil {
    fmt.Fprintln(os.Stderr, err.Error())
    os.Exit(1)
    }
    }