blob: 24888a6ec409a894917f2d536f8feec98756509f [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package gndoc
import (
"fmt"
"io"
"sort"
"strings"
)
type ArgMap struct {
argLookup map[string][]string // map of arg names to keys for lookup
args map[string][]Arg // map of key names to relevant args
sources *SourceMap // map of existing source locations for linkifying
}
// NewArgMap returns a pointer to an
func NewArgMap(sources *SourceMap) *ArgMap {
return &ArgMap{
argLookup: make(map[string][]string),
args: make(map[string][]Arg),
sources: sources,
}
}
// AddArgs creates args from GNArgs and adds them to the maps
func (a *ArgMap) AddArgs(gnArgs <-chan Arg) {
for gnArg := range gnArgs {
a.AddArg(gnArg)
}
}
// AddArg adds Arg to the maps
func (a *ArgMap) AddArg(gnArg Arg) {
a.args[gnArg.Key] = append(a.args[gnArg.Key], gnArg)
a.argLookup[gnArg.Name] = append(a.argLookup[gnArg.Name], gnArg.Key)
}
// EmitMarkdown emits Markdown text for the map of arguments.
func (a *ArgMap) EmitMarkdown(out io.Writer) {
type mappedArgs struct {
m map[string][]Arg
k []string
}
sortedArgs := struct {
m map[string]*mappedArgs
k []string
}{
m: make(map[string]*mappedArgs),
k: make([]string, 0),
}
numKeys := len(a.args)
for _, gnArgs := range a.args {
for _, gnArg := range gnArgs {
// Lookup the keys associated with this arg & sort & stringify.
keys, _ := a.argLookup[gnArg.Name]
if len(keys) == numKeys {
// Incoming keys will always have an `=`, and so this is an
// okay value.
keys = []string{"all"}
}
sort.Strings(keys)
key := strings.Join(keys, ", ")
if _, ok := sortedArgs.m[key]; !ok {
sortedArgs.m[key] = &mappedArgs{
m: make(map[string][]Arg),
k: make([]string, 0)}
}
sortedArgs.m[key].m[gnArg.Name] = append(sortedArgs.m[key].m[gnArg.Name], gnArg)
}
}
for k := range sortedArgs.m {
for argName := range sortedArgs.m[k].m {
sort.Slice(sortedArgs.m[k].m[argName], func(i, j int) bool {
return sortedArgs.m[k].m[argName][i].Key < sortedArgs.m[k].m[argName][j].Key
})
sortedArgs.m[k].k = append(sortedArgs.m[k].k, argName)
}
sort.Strings(sortedArgs.m[k].k)
sortedArgs.k = append(sortedArgs.k, k)
}
sort.Strings(sortedArgs.k)
// Emit a header.
fmt.Fprintf(out, "# %s\n\n", pageTitle)
for _, name := range sortedArgs.k {
if name == "all" {
fmt.Fprintf(out, "## All builds\n\n")
} else {
fmt.Fprintf(out, "## `%s`\n\n", name)
}
for _, argsKey := range sortedArgs.m[name].k {
gnArgs := sortedArgs.m[name].m[argsKey]
writeArgs(gnArgs, out, a.sources)
}
}
}