// Package code creates a markdown document with a fenced code block.
package code
import (
_ "embed"
"fmt"
"go/parser"
"go/token"
)
//go:embed code.go
var codeFile string
type Opt struct {
code string
syntax string
name string
}
type Option func(*Opt)
// WithCode sets the content.
func WithCode(s string) Option {
return func(o *Opt) {
if s != "" {
o.code = s
}
}
}
// WithSyntax sets the language for syntax highlighting.
func WithSyntax(s string) Option {
return func(o *Opt) {
if s != "" {
o.syntax = s
}
}
}
func name(code string) string {
f, err := parser.ParseFile(token.NewFileSet(), "", code, parser.PackageClauseOnly)
if err != nil {
return "to-err-"
}
return f.Name.Name
}
// New sets the options for displaying a fenced code block in a markdown
// document.
func New(opt ...Option) *Opt {
o := &Opt{
code: codeFile,
syntax: "go",
}
for _, fn := range opt {
fn(o)
}
o.name = name(o.code)
return o
}
const (
// The markdown parser matches fences (``` or ~~~) embedded in
// the code block.
fence = "```"
tmpl = `---
title: '%s Is Code'
---
%s%s
%s
%s
---
([source](/%s?md))
`
)
// Run generates a markdown document containing a fenced code block.
func (o *Opt) Run() (string, error) {
return fmt.Sprintf(tmpl, o.name, fence, o.syntax, o.code, fence, o.name), nil
}
(source)