// 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)