weave: fix %include parsing, add highlighting Recognize that %include file - means "no tag, no caption" instead of "the tag is -, add caption." Write "go" after backticks, which GitHub will render with syntax highlighting. Change-Id: I9e0b3618b5fba8834d7f06b8fc7adf0781574a2d Reviewed-on: https://go-review.googlesource.com/c/example/+/673875 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/gotypes/README.md b/gotypes/README.md index 350fbc6..9886a11 100644 --- a/gotypes/README.md +++ b/gotypes/README.md
@@ -143,7 +143,7 @@ // go get golang.org/x/example/gotypes/pkginfo -``` +```go package main import ( @@ -247,7 +247,7 @@ (The hexadecimal number may vary from one run to the next.) -``` +```go $ go build golang.org/x/example/gotypes/pkginfo $ ./pkginfo Package "cmd/hello" @@ -505,7 +505,7 @@ // go get golang.org/x/example/gotypes/defsuses -``` +```go func PrintDefsUses(fset *token.FileSet, files ...*ast.File) error { conf := types.Config{Importer: importer.Default()} info := &types.Info{ @@ -535,7 +535,7 @@ // go get golang.org/x/example/gotypes/hello -``` +```go package main import "fmt" @@ -549,7 +549,7 @@ This is what it prints: -``` +```go $ go build golang.org/x/example/gotypes/defsuses $ ./defsuses hello.go:1:9: "main" defines <nil> @@ -796,7 +796,7 @@ // go get golang.org/x/example/gotypes/lookup -``` +```go func main() { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments) @@ -839,7 +839,7 @@ and so on. -``` +```go const hello = ` package main @@ -863,7 +863,7 @@ Here's the output: -``` +```go $ go build golang.org/x/example/gotypes/lookup $ ./lookup At hello.go:6:1, "append" = builtin append @@ -1566,7 +1566,7 @@ // go get golang.org/x/example/gotypes/typeandvalue -``` +```go // f is a parsed, type-checked *ast.File. ast.Inspect(f, func(n ast.Node) bool { if expr, ok := n.(ast.Expr); ok { @@ -1596,7 +1596,7 @@ Given this input: -``` +```go const input = ` package main @@ -1613,7 +1613,7 @@ the program prints: -``` +```go $ go build golang.org/x/example/gotypes/typeandvalue $ ./typeandvalue make(map[string]int) mode: value @@ -1672,7 +1672,7 @@ // go get golang.org/x/example/gotypes/nilfunc -``` +```go // CheckNilFuncComparison reports unintended comparisons // of functions against nil, e.g., "if x.Method == nil {". func CheckNilFuncComparison(info *types.Info, n ast.Node) { @@ -1718,7 +1718,7 @@ Given this input, -``` +```go const input = `package main import "bytes" @@ -1736,7 +1736,7 @@ the program reports these errors: -``` +```go $ go build golang.org/x/example/gotypes/nilfunc $ ./nilfunc input.go:7:5: comparison of function Bytes == nil is always false @@ -1969,7 +1969,7 @@ Here's an example: -``` +```go $ ./skeleton io ReadWriteCloser buffer // *buffer implements io.ReadWriteCloser. type buffer struct{} @@ -1993,7 +1993,7 @@ // go get golang.org/x/example/gotypes/skeleton -``` +```go func PrintSkeleton(pkg *types.Package, ifacename, concname string) error { obj := pkg.Scope().Lookup(ifacename) if obj == nil { @@ -2051,7 +2051,7 @@ Here's another example that illustrates it: -``` +```go $ ./skeleton net/http Handler myHandler // *myHandler implements net/http.Handler. type myHandler struct{} @@ -2067,7 +2067,7 @@ // go get golang.org/x/example/gotypes/implements -``` +```go // Find all named types at package level. var allNamed []*types.Named for _, name := range pkg.Scope().Names() { @@ -2099,7 +2099,7 @@ // go get golang.org/x/example/gotypes/implements -``` +```go const input = `package main type A struct{} @@ -2118,7 +2118,7 @@ the program prints: -``` +```go $ go build golang.org/x/example/gotypes/implements $ ./implements *hello.A satisfies hello.I @@ -2276,7 +2276,7 @@ // go get golang.org/x/example/gotypes/hugeparam -``` +```go var bytesFlag = flag.Int("bytes", 48, "maximum parameter size in bytes") func PrintHugeParams(fset *token.FileSet, info *types.Info, sizes types.Sizes, files []*ast.File) { @@ -2324,7 +2324,7 @@ is copied. -``` +```go % ./hugeparam encoding/xml /go/src/encoding/xml/marshal.go:167:50: "start" parameter: encoding/xml.StartElement = 56 bytes /go/src/encoding/xml/marshal.go:734:97: "" result: encoding/xml.StartElement = 56 bytes @@ -2408,7 +2408,7 @@ Here's an example: -``` +```go $ ./doc net/http File type net/http.File interface{Readdir(count int) ([]os.FileInfo, error); Seek(offset int64, whence int) (int64, error); Stat() (os.FileInfo, error); io.Closer; io.Reader} $GOROOT/src/io/io.go:92:2: method (net/http.File) Close() error @@ -2435,7 +2435,7 @@ // go get golang.org/x/example/gotypes/doc -``` +```go pkgpath, name := os.Args[1], os.Args[2] // Load complete type information for the specified packages, @@ -2465,7 +2465,7 @@ // go get golang.org/x/example/gotypes/doc -``` +```go // Print the object and its methods (incl. location of definition). fmt.Println(obj) for _, sel := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
diff --git a/internal/cmd/weave/weave.go b/internal/cmd/weave/weave.go index d833653..880b415 100644 --- a/internal/cmd/weave/weave.go +++ b/internal/cmd/weave/weave.go
@@ -27,6 +27,7 @@ import ( "bufio" "bytes" + "flag" "fmt" "io" "log" @@ -37,13 +38,14 @@ ) func main() { + flag.Parse() log.SetFlags(0) log.SetPrefix("weave: ") - if len(os.Args) != 2 { + if flag.NArg() != 1 { log.Fatal("usage: weave input.md\n") } - f, err := os.Open(os.Args[1]) + f, err := os.Open(flag.Arg(0)) if err != nil { log.Fatal(err) } @@ -100,26 +102,38 @@ } case strings.HasPrefix(line, "%include"): words := strings.Fields(line) - if len(words) < 2 { - log.Fatal(line) + var section string + caption := true + switch len(words) { + case 2: // %include filename + // Nothing to do. + case 3: // %include filename section OR %include filename - + if words[2] == "-" { + caption = false + } else { + section = words[2] + } + case 4: // %include filename section - + section = words[2] + if words[3] != "-" { + log.Fatalf("last word is not '-': %s", line) + } + caption = false + default: + log.Fatalf("wrong # words (want 2-4): %s", line) } filename := words[1] - // Show caption unless '-' follows. - if len(words) < 4 || words[3] != "-" { + if caption { fmt.Printf(" // go get golang.org/x/example/%s/%s\n\n", curDir, filepath.Dir(filename)) } - section := "" - if len(words) > 2 { - section = words[2] - } s, err := include(filename, section) if err != nil { log.Fatal(err) } - fmt.Println("```") + fmt.Println("```go") fmt.Println(cleanListing(s)) // TODO(adonovan): escape /^```/ in s fmt.Println("```") default:
diff --git a/slog-handler-guide/README.md b/slog-handler-guide/README.md index 01027cc..5342c06 100644 --- a/slog-handler-guide/README.md +++ b/slog-handler-guide/README.md
@@ -115,7 +115,7 @@ We begin with the `IndentHandler` type and the `New` function that constructs it from an `io.Writer` and options: -``` +```go type IndentHandler struct { opts Options // TODO: state for WithGroup and WithAttrs @@ -186,7 +186,7 @@ Our `IndentHandler` doesn't use the context. It just compares the argument level with its configured minimum level: -``` +```go func (h *IndentHandler) Enabled(ctx context.Context, level slog.Level) bool { return level >= h.opts.Level.Level() } @@ -232,7 +232,7 @@ That is how `IndentHandler.Handle` is structured: -``` +```go func (h *IndentHandler) Handle(ctx context.Context, r slog.Record) error { buf := make([]byte, 0, 1024) if !r.Time.IsZero() { @@ -287,7 +287,7 @@ At the heart of the handler is the `appendAttr` method, responsible for formatting a single attribute: -``` +```go func (h *IndentHandler) appendAttr(buf []byte, a slog.Attr, indentLevel int) []byte { // Resolve the Attr's value before doing anything else. a.Value = a.Value.Resolve() @@ -405,7 +405,7 @@ and loop over that slice in `Handle`. We start with a struct that can hold either a group name or some attributes: -``` +```go // groupOrAttrs holds either a group name or a list of slog.Attrs. type groupOrAttrs struct { group string // group name if non-empty @@ -415,7 +415,7 @@ Then we add a slice of `groupOrAttrs` to our handler: -``` +```go type IndentHandler struct { opts Options goas []groupOrAttrs @@ -429,7 +429,7 @@ To that end, we define a method that will copy our handler struct and append one `groupOrAttrs` to the copy: -``` +```go func (h *IndentHandler) withGroupOrAttrs(goa groupOrAttrs) *IndentHandler { h2 := *h h2.goas = make([]groupOrAttrs, len(h.goas)+1) @@ -446,7 +446,7 @@ The `With` methods are easy to write using `withGroupOrAttrs`: -``` +```go func (h *IndentHandler) WithGroup(name string) slog.Handler { if name == "" { return h @@ -465,7 +465,7 @@ The `Handle` method can now process the groupOrAttrs slice after the built-in attributes and before the ones in the record: -``` +```go func (h *IndentHandler) Handle(ctx context.Context, r slog.Record) error { buf := make([]byte, 0, 1024) if !r.Time.IsZero() { @@ -587,7 +587,7 @@ To pre-format the arguments to `WithAttrs`, we need to keep track of some additional state in the `IndentHandler` struct. -``` +```go type IndentHandler struct { opts Options preformatted []byte // data from WithGroup and WithAttrs @@ -608,7 +608,7 @@ This `WithGroup` is a lot like the previous one: it just remembers the new group, which is unopened initially. -``` +```go func (h *IndentHandler) WithGroup(name string) slog.Handler { if name == "" { return h @@ -624,7 +624,7 @@ `WithAttrs` does all the pre-formatting: -``` +```go func (h *IndentHandler) WithAttrs(attrs []slog.Attr) slog.Handler { if len(attrs) == 0 { return h @@ -668,7 +668,7 @@ It's the `Handle` method's job to insert the pre-formatted material in the right place, which is after the built-in attributes and before the ones in the record: -``` +```go func (h *IndentHandler) Handle(ctx context.Context, r slog.Record) error { buf := make([]byte, 0, 1024) if !r.Time.IsZero() { @@ -728,7 +728,7 @@ a function that returns its output formatted as a slice of maps. Here is the test function for our example handler: -``` +```go func TestSlogtest(t *testing.T) { var buf bytes.Buffer err := slogtest.TestHandler(New(&buf, nil), func() []map[string]any { @@ -754,7 +754,7 @@ Our example output is enough like YAML so that we can use the `gopkg.in/yaml.v3` package to parse it: -``` +```go func parseLogEntries(t *testing.T, data []byte) []map[string]any { entries := bytes.Split(data, []byte("---\n")) entries = entries[:len(entries)-1] // last one is empty @@ -985,7 +985,7 @@ Here is our pool and its associated functions: -``` +```go var bufPool = sync.Pool{ New: func() any { b := make([]byte, 0, 1024)