-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
107 lines (92 loc) · 2.02 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"bytes"
_ "embed"
"flag"
"io"
"log"
"os"
"strings"
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
"github.com/bevzzz/nb"
synth "github.com/bevzzz/nb-synth"
"github.com/bevzzz/nb/extension"
"github.com/bevzzz/nb/extension/adapter"
jupyter "github.com/bevzzz/nb/extension/extra/goldmark-jupyter"
"github.com/bevzzz/nb/render"
"github.com/bevzzz/nb/render/html"
"github.com/robert-nix/ansihtml"
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
)
var (
file = flag.String("f", "", "Jupyter notebook file")
)
func main() {
flag.Parse()
if *file == "" {
log.Fatal("-f must be a valid path to notebook")
}
var b []byte
var err error
outFile := "notebook.html"
if f := *file; f != "" {
if b, err = os.ReadFile(f); err != nil {
log.Fatal(err)
}
outFile = strings.ReplaceAll(f, ".ipynb", ".html")
}
_ = os.Remove(outFile)
out, err := os.Create(outFile)
if err != nil {
log.Fatal(err)
}
defer out.Close()
if err := convert(out, b); err != nil {
log.Fatal(err)
}
log.Printf("Done! %s -> %s", *file, outFile)
}
func convert(w io.Writer, b []byte) error {
var body, css bytes.Buffer
md := goldmark.New(
goldmark.WithExtensions(
jupyter.Attachments(),
highlighting.Highlighting,
),
)
c := nb.New(
nb.WithExtensions(
jupyter.Goldmark(md),
synth.NewHighlighting(
synth.WithStyle("monokailight"),
synth.WithFormatOptions(
chromahtml.WithLineNumbers(true),
),
),
extension.NewStream(
adapter.AnsiHtml(ansihtml.ConvertToHTML),
),
),
nb.WithRenderOptions(
render.WithCellRenderers(
html.NewRenderer(
html.WithCSSWriter(&css),
),
),
),
)
err := c.Convert(&body, b)
if err != nil {
return err
}
// Write styles to the final output
io.WriteString(w, "<html><head><meta charset=\"UTF-8\"><style>")
io.Copy(w, &css)
io.WriteString(w, "</style></head>")
// Copy notebook body
io.WriteString(w, "<body>")
io.Copy(w, &body)
io.WriteString(w, "</body></html>")
return nil
}