Skip to content

Instantly share code, notes, and snippets.

@hymkor
Created March 25, 2020 05:35
Show Gist options
  • Save hymkor/20218afc7b80ea0bdd5f6357ab4e36d4 to your computer and use it in GitHub Desktop.
Save hymkor/20218afc7b80ea0bdd5f6357ab4e36d4 to your computer and use it in GitHub Desktop.
scrapbox.ioのエクスポートJSONをプレーンテキスト(UTF8)に展開するやつ (1ページ1ファイルにする時は-dオプションでディレクトリを指定する)
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)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment