1
0
Fork 0
forked from fz0x1/go-org-py
go-org-py-orgwiki/convert.go
2025-06-23 17:25:28 +02:00

82 lines
1.8 KiB
Go

package convert
import "C"
import (
"errors"
"strings"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
"github.com/niklasfasching/go-org/org"
)
func Render(src, path, format string) (string, error) {
doc := org.New().Parse(strings.NewReader(src), path)
write := func(w org.Writer) (string, error) {
out, wErr := doc.Write(w)
if pErr := doc.Error; pErr != nil {
return out, pErr
}
return out, wErr
}
switch strings.ToLower(format) {
case "org":
return write(org.NewOrgWriter())
case "html":
return write(org.NewHTMLWriter())
case "html-chroma":
w := org.NewHTMLWriter()
w.HighlightCodeBlock = highlightCodeBlock
return write(w)
default:
return "", errors.New("unknown format")
}
}
func OrgToHTML(src string) (string, error) {
return Render(src, "", "html")
}
// --- helpers ---------------------------------------------------------------
func highlightCodeBlock(source, lang string, inline bool,
params map[string]string) string {
var b strings.Builder
l := lexers.Get(lang)
if l == nil {
l = lexers.Fallback
}
l = chroma.Coalesce(l)
it, _ := l.Tokenise(nil, source)
opts := []html.Option{}
if hl := params[":hl_lines"]; hl != "" {
if r := org.ParseRanges(hl); r != nil {
opts = append(opts, html.HighlightLines(r))
}
}
styleName := params[":style"]
if styleName == "" {
styleName = "friendly"
}
style := styles.Get(styleName)
if style == nil {
style = styles.Fallback
}
_ = html.New(opts...).Format(&b, style, it)
wrap := "highlight"
if inline {
wrap = "highlight-inline"
}
return `<div class="` + wrap + `">` + "\n" + b.String() + "\n</div>"
}