diff --git a/cmd/transpile/main.go b/cmd/transpile/main.go index f4a397c..59574d9 100644 --- a/cmd/transpile/main.go +++ b/cmd/transpile/main.go @@ -16,6 +16,7 @@ import ( // T represents the state of things type T struct { + Stdin io.Reader Stdout io.Writer Stderr io.Writer Args []string @@ -42,6 +43,7 @@ func usage(w io.Writer) { fmt.Fprintln(w, " puzzle: Print puzzle JSON") fmt.Fprintln(w, " file: Open a file for a puzzle") fmt.Fprintln(w, " answer: Check correctness of an answer") + fmt.Fprintln(w, " markdown: Format stdin with markdown") } // ParseArgs parses arguments and runs the appropriate action. @@ -71,6 +73,8 @@ func (t *T) ParseArgs() (Command, error) { case "answer": cmd = t.CheckAnswer flags.StringVar(&t.answer, "answer", "", "Answer to check") + case "markdown": + cmd = t.Markdown case "help": usage(t.Stderr) return nothing, nil @@ -185,6 +189,11 @@ func (t *T) CheckAnswer() error { return err } +// Markdown runs stdin through a Markdown engine +func (t *T) Markdown() error { + return transpile.Markdown(t.Stdin, t.Stdout) +} + func main() { t := &T{ Stdout: os.Stdout, diff --git a/cmd/transpile/main_test.go b/cmd/transpile/main_test.go index 4843d23..27065b8 100644 --- a/cmd/transpile/main_test.go +++ b/cmd/transpile/main_test.go @@ -51,9 +51,11 @@ func (tp T) Run(args ...string) error { } func TestTranspilerEverything(t *testing.T) { + stdin := new(bytes.Buffer) stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) tp := T{ + Stdin: stdin, Stdout: stdout, Stderr: stderr, BaseFs: newTestFs(), @@ -94,6 +96,15 @@ func TestTranspilerEverything(t *testing.T) { t.Error("Answer validation failed", stdout.String()) } + stdout.Reset() + stdin.Reset() + stdin.WriteString("text *emphasized* text") + if err := tp.Run("markdown"); err != nil { + t.Error(err) + } + if stdout.String() != "
text emphasized text
\n" { + t.Error("Markdown conversion failed", stdout.String()) + } } func TestMothballs(t *testing.T) { @@ -165,9 +176,11 @@ func TestMothballs(t *testing.T) { } func TestFilesystem(t *testing.T) { + stdin := new(bytes.Buffer) stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) tp := T{ + Stdin: stdin, Stdout: stdout, Stderr: stderr, BaseFs: afero.NewOsFs(), diff --git a/pkg/transpile/markdown.go b/pkg/transpile/markdown.go new file mode 100644 index 0000000..2754b60 --- /dev/null +++ b/pkg/transpile/markdown.go @@ -0,0 +1,29 @@ +package transpile + +import ( + "io" + "io/ioutil" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/renderer/html" +) + +// Markdown formats the provided bytes using whatever Markdown engine we're currently using. +func Markdown(input io.Reader, output io.Writer) error { + md := goldmark.New( + goldmark.WithExtensions( + extension.Table, + extension.DefinitionList, + ), + goldmark.WithRendererOptions( + html.WithUnsafe(), + ), + ) + buf, err := ioutil.ReadAll(input) + if err != nil { + return err + } + md.Convert(buf, output) + return nil +} diff --git a/pkg/transpile/puzzle.go b/pkg/transpile/puzzle.go index ed816c5..b9818ba 100644 --- a/pkg/transpile/puzzle.go +++ b/pkg/transpile/puzzle.go @@ -19,9 +19,6 @@ import ( "time" "github.com/spf13/afero" - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/extension" - "github.com/yuin/goldmark/renderer/html" "gopkg.in/yaml.v2" ) @@ -281,20 +278,9 @@ func (fp FsPuzzle) staticPuzzle() (StaticPuzzle, []byte, error) { return static, nil, err } - body := new(bytes.Buffer) - - md := goldmark.New( - goldmark.WithExtensions( - extension.Table, - extension.DefinitionList, - ), - goldmark.WithRendererOptions( - html.WithUnsafe(), - ), - ) - md.Convert(bodyBuf.Bytes(), body) - - return static, body.Bytes(), err + html := new(bytes.Buffer) + err = Markdown(bodyBuf, html) + return static, html.Bytes(), err } func legacyAttachmentParser(val []string) []StaticAttachment {