An extensible library that converts editor.js data into HTML or markdown.
go get github.com/davidscottmills/goeditorjs
package main
import (
"io/ioutil"
"log"
"github.com/davidscottmills/goeditorjs"
)
func main() {
content, err := ioutil.ReadFile("editorjs_output.json")
if err != nil {
log.Fatal(err)
}
ejs := string(content)
// HTML
// Get the HTML engine
htmlEngine := goeditorjs.NewHTMLEngine()
// Register the handlers you wish to use
htmlEngine.RegisterBlockHandlers(
&goeditorjs.HeaderHandler{},
&goeditorjs.ParagraphHandler{},
&goeditorjs.ListHandler{},
&goeditorjs.CodeBoxHandler{},
)
// Generate the html
html, err := htmlEngine.GenerateHTML(ejs)
if err != nil {
log.Fatal(err)
}
// Do something with the html output. In this case, write it to a file.
err = ioutil.WriteFile("editorjs.html", []byte(html), 0644)
if err != nil {
log.Fatal(err)
}
// Generate markdown and save it to a file
// Get the markdown engine
markdownEngine := goeditorjs.NewMarkdownEngine()
// Register the handlers you wish to use
markdownEngine.RegisterBlockHandlers(
&goeditorjs.HeaderHandler{},
&goeditorjs.ParagraphHandler{},
&goeditorjs.ListHandler{},
&goeditorjs.CodeBoxHandler{},
)
// Generate the markdown
md, err := markdownEngine.GenerateMarkdown(ejs)
if err != nil {
log.Fatal(err)
}
// Do something with the md output. In this case, write it to a file.
err = ioutil.WriteFile("editorjs.md", []byte(md), 0644)
if err != nil {
log.Fatal(err)
}
}
You can create and use your own handler in either engine by implementing the required interface and registering it. This package provides two interfaces for handlers.
-
HTMLBlockHandler
type HTMLBlockHandler interface { Type() string // Type returns the type the block handler supports as a string GenerateHTML(editorJSBlock EditorJSBlock) (string, error) // Return associated HTML }
-
MarkdownBlockHandler
type MarkdownBlockHandler interface { Type() string // Type returns the type the block handler supports as a string GenerateMarkdown(editorJSBlock EditorJSBlock) (string, error) // Return associated markdown }
If you're only planning to use the HTMLEngine, then you only need to implement the HTMLBlockHandler
interface. The same goes for markdown.
Once you've met the required interface, register the handler for use in the engine.
htmlEngine := goeditorjs.NewHTMLEngine()
// Register the handlers you wish to use
htmlEngine.RegisterBlockHandlers(
&MyCustomBlockHandler{},
)
Below is an example of how the header handle is implemented.
package header
import (
"encoding/json"
"fmt"
)
// HeaderHandler is the default HeaderHandler for EditorJS HTML generation
type HeaderHandler struct {
// Notice that you could put some configurable options in this struct and then use them in your handler
}
// Header represents header data from EditorJS
type Header struct {
Text string `json:"text"`
Level int `json:"level"`
}
func (*HeaderHandler) parse(editorJSBlock EditorJSBlock) (*Header, error) {
header := &Header{}
return header, json.Unmarshal(editorJSBlock.Data, header)
}
// Type "header"
func (*HeaderHandler) Type() string {
return "header"
}
// GenerateHTML generates html for HeaderBlocks
func (h *HeaderHandler) GenerateHTML(editorJSBlock EditorJSBlock) (string, error) {
header, err := h.parse(editorJSBlock)
if err != nil {
return "", err
}
return fmt.Sprintf("<h%d>%s</h%d>", header.Level, header.Text, header.Level), nil
}
// GenerateMarkdown generates markdown for HeaderBlocks
func (h *HeaderHandler) GenerateMarkdown(editorJSBlock EditorJSBlock) (string, error) {
header, err := h.parse(editorJSBlock)
if err != nil {
return "", err
}
return fmt.Sprintf("%s %s", strings.Repeat("#", header.Level), header.Text), nil
}
- Provide more handlers (table, etc.)