| // 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, |
| } |
| } |
| |
| // AddArg creates args from GNArgs and adds them to the maps |
| func (a *ArgMap) AddArgs(gnArgs <-chan Arg) { |
| for gnArg := range gnArgs { |
| a.AddArg(gnArg) |
| } |
| } |
| |
| 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) |
| } |
| |
| // sortedArgs returns the list of args in the appropriate order to print. |
| func (a *ArgMap) sortedArgs() (map[string]map[string][]Arg, []string) { |
| numKeys := len(a.args) |
| args := make(map[string]map[string][]Arg) |
| // For each arg, we need to push it into the appropiate list. |
| 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"} |
| } |
| key := strings.Join(keys, ", ") |
| _, ok := args[key] |
| if !ok { |
| args[key] = make(map[string][]Arg) |
| } |
| args[key][gnArg.Name] = append(args[key][gnArg.Name], gnArg) |
| } |
| } |
| |
| // Get the keys in alphabetical order |
| keys := make([]string, 0, numKeys) |
| for k := range args { |
| // Sort by name first, then by key |
| for argName := range args[k] { |
| sort.Slice(args[k][argName], func(i, j int) bool { return args[k][argName][i].Key < args[k][argName][j].Key }) |
| } |
| |
| keys = append(keys, k) |
| } |
| sort.Strings(keys) |
| |
| return args, keys |
| } |
| |
| // EmitMarkdown emits Markdown text for the map of arguments. |
| func (a *ArgMap) EmitMarkdown(out io.Writer) { |
| // Emit a header. |
| fmt.Fprintf(out, "# %s\n\n", pageTitle) |
| gnArgsMap, keys := a.sortedArgs() |
| for _, name := range keys { |
| if name == "all" { |
| fmt.Fprintf(out, "## All builds\n\n") |
| } else { |
| fmt.Fprintf(out, "## `%s`\n\n", name) |
| } |
| |
| for _, gnArgs := range gnArgsMap[name] { |
| writeArgs(gnArgs, out, a.sources) |
| } |
| } |
| } |