feat: render markdown examples
1 file changed, 68 insertions(+), 10 deletions(-)
changed files
M internal/options/process.go → internal/options/process.go
@@ -3,6 +3,7 @@ import ( "encoding/json" "io" + "log/slog" "os" "github.com/bcicen/jstream"@@ -10,6 +11,27 @@ "github.com/mitchellh/mapstructure" "github.com/pkg/errors" ) +type nixValueJSON struct { + Type string `mapstructure:"_type"` + Text string +} + +type linkJSON struct { + Name string + URL string `json:"url"` +} + +type nixOptionJSON struct { + Declarations []linkJSON + Default nixValueJSON + Description string + Example nixValueJSON + Loc []string + ReadOnly bool + RelatedPackages string + Type string +} + func ValueTypeToString(valueType jstream.ValueType) string { switch valueType { case jstream.Unknown:@@ -31,6 +53,27 @@ return "very strange" } +func convertNixValue(nj nixValueJSON) *NixValue { + switch nj.Type { + case "", "literalExpression": + if nj.Text == "" { + return nil + } + + return &NixValue{ + Text: nj.Text, + } + case "literalMD": + return &NixValue{ + Markdown: Markdown(nj.Text), + } + default: + slog.Warn("got unexpected NixValue type", "type", nj.Type, "text", nj.Text) + + return nil + } +} + func Process(inpath string, outpath string) error { infile, err := os.Open(inpath) if err != nil {@@ -46,10 +89,11 @@ defer outfile.Close() } dec := jstream.NewDecoder(infile, 1).EmitKV() - var opt NixOption + var optJSON nixOptionJSON ms, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ ErrorUnused: true, - Result: &opt, + ZeroFields: true, + Result: &optJSON, Squash: true, DecodeHook: mapstructure.TextUnmarshallerHookFunc(), })@@ -69,17 +113,29 @@ if mv.ValueType != jstream.Object { return errors.Errorf("unexpected object type %s", ValueTypeToString(mv.ValueType)) } kv := mv.Value.(jstream.KV) - if kv.Key == "_module.args" { - continue - } x := kv.Value.(map[string]interface{}) - x["option"] = kv.Key - err = ms.Decode(x) + err = ms.Decode(x) // stores in optJSON if err != nil { return errors.WithMessagef(err, "failed to decode option %#v", x) } + var decs = make([]Link, len(optJSON.Declarations)) + for i, d := range optJSON.Declarations { + decs[i] = Link(d) + } + + opt := NixOption{ + Option: kv.Key, + Declarations: decs, + Default: convertNixValue(optJSON.Default), + Description: Markdown(optJSON.Description), + Example: convertNixValue(optJSON.Example), + RelatedPackages: Markdown(optJSON.RelatedPackages), + Loc: optJSON.Loc, + Type: optJSON.Type, + } + b, err := json.MarshalIndent(opt, "", " ") if err != nil { return errors.WithMessagef(err, "failed to encode option %#v", opt)@@ -95,9 +151,11 @@ return errors.WithMessage(err, "failed to write to output") } } - _, err = outfile.Seek(-2, io.SeekCurrent) - if err != nil { - return errors.WithMessage(err, "could not write to output") + if outpath != "/dev/stdout" { + _, err = outfile.Seek(-2, io.SeekCurrent) + if err != nil { + return errors.WithMessage(err, "could not write to output") + } } _, err = outfile.WriteString("]\n")