Reference
Sample page
A page with most marker kinds: its empty markers, the same page after docgen update -module v2, and how that page renders. It is the test fixture of docgen, so the tests compare this output with the result of each change.
v2/machine/machine.go
// Package machine is a small state machine for the docgen tests.
//
// # Rates
//
// A Lamp blinks at these rates:
// - slow, every [DefaultWait]
// - fast, every period
//
// # Other
//
// Not copied.
package machine
import (
"errors"
"time"
"github.com/USA-RedDragon/docgen/v2"
)
// DefaultWait is the wait of a Lamp that Config does not set.
const DefaultWait = 250 * time.Millisecond
// MaxTries is the largest Config.Tries.
const MaxTries = 3
var (
// ErrBusy is returned by Start while the Lamp is on.
ErrBusy = errors.New("machine: busy")
// ErrOff is returned by Stop while the Lamp is off.
ErrOff = errors.New("machine: off")
)
// Config configures NewLamp.
type Config struct {
// Wait is how long the Lamp stays on. 0 means DefaultWait.
Wait time.Duration
// Tries is the number of blinks. 0 means 1, and it is at most MaxTries.
Tries int
// Name is a label.
Name string
}
// LampState is the state of a Lamp.
type LampState uint8
// The LampState values.
const (
// LampOff gives no light.
LampOff LampState = iota
// LampOn gives light.
LampOn
// LampBroken never gives light again.
LampBroken
)
// Lamp turns on and off.
type Lamp struct {
state LampState
wait time.Duration
tries int
until time.Duration
}
// NewLamp returns a Lamp. It returns a *docgen.ConfigError for a Tries
// above MaxTries.
func NewLamp(cfg Config) (*Lamp, error) {
if cfg.Tries > MaxTries {
return nil, &docgen.ConfigError{Field: "Tries"}
}
l := &Lamp{wait: cfg.Wait, tries: cfg.Tries}
if l.wait == 0 {
l.wait = DefaultWait
}
if cfg.Tries == 0 {
l.tries = 1
}
return l, nil
}
// State returns the state of the Lamp.
func (l *Lamp) State() LampState { return l.state }
// Start turns the Lamp on. It returns ErrBusy while the Lamp is on.
func (l *Lamp) Start(now time.Duration) error {
if l.state == LampOn {
return ErrBusy
}
if l.state == LampOff {
l.state, l.until = LampOn, now+l.wait
}
return nil
}
// Stop turns the Lamp off. It returns ErrOff while the Lamp is off.
func (l *Lamp) Stop() error {
if l.state != LampOn {
return ErrOff
}
l.off()
return nil
}
// Tick turns the Lamp off at the end of its wait.
func (l *Lamp) Tick(now time.Duration) {
if l.state == LampOn && now >= l.until {
l.off()
}
}
// Break breaks the Lamp.
func (l *Lamp) Break() { l.state = LampBroken }
func (l *Lamp) off() { l.state = LampOff }
// Counter counts and has no State method.
type Counter struct{ n int }
// Add adds one.
func (c *Counter) Add() { c.n++ }
// Clear sets the count to 0.
func (c *Counter) Clear() { c.n = 0 }
// Len returns the count.
func (c *Counter) Len() int { return c.n }
const period = 30 * time.Millisecond
var hold = 4 * period
// Side is one side of a Pair.
type Side uint8
// The Side values.
const (
// SideA is the first side.
SideA Side = iota + 1
// SideB is the second side.
SideB
)
// SideState is the state of one side of a Pair.
type SideState uint8
// The SideState values.
const (
// SideDown is down.
SideDown SideState = iota
// SideUp is up.
SideUp
)
// Pair has two sides.
type Pair struct{ up [3]bool }
// Raise raises side s.
func (p *Pair) Raise(s Side) {
if s == SideA || s == SideB {
p.up[s] = true
}
}
// SideState returns the state of side s.
func (p *Pair) SideState(s Side) SideState {
if s != SideA && s != SideB || !p.up[s] {
return SideDown
}
return SideUp
}docs/machines/machine-lamp.md
Before
# Lamp
This page covers every marker kind.
<!-- docgen:config pkg=machine type=Config -->
<!-- /docgen:config -->
The default wait is <!-- docgen:const pkg=machine name=DefaultWait --><!-- /docgen:const --> and at most <!-- docgen:const pkg=machine name=MaxTries --><!-- /docgen:const --> tries.
<!-- docgen:states pkg=machine type=Lamp -->
<!-- /docgen:states -->
<!-- docgen:states pkg=machine type=Counter -->
<!-- /docgen:states -->
<!-- docgen:errors pkg=machine type=Lamp -->
<!-- /docgen:errors -->
<!-- docgen:states pkg=machine type=SideState -->
<!-- /docgen:states -->
The period is <!-- docgen:const pkg=machine name=period --><!-- /docgen:const --> and the hold <!-- docgen:const pkg=machine name=hold --><!-- /docgen:const -->.
<!-- docgen:doc pkg=machine section=Rates -->
<!-- /docgen:doc -->
<!-- docgen:doc pkg=machine name=Lamp.Start -->
<!-- /docgen:doc -->
<!-- docgen:code file=v2/machine/machine.go lines=96-102 -->
<!-- /docgen:code -->
<!-- docgen:output test=machine.ExampleLamp -->
<!-- /docgen:output -->
<!-- docgen:output cmd=v2/examples/hello -->
<!-- /docgen:output -->
<!-- docgen:code file=v2/machine/example_test.go symbol=ExampleLamp -->
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=Lamp.Tick -->
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=SideState -->
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=SideB -->
<!-- /docgen:code -->
It needs Go <!-- docgen:gomod field=go --><!-- /docgen:gomod --> or later.
<!-- docgen:usage cmd=cmd/tool -->
<!-- /docgen:usage -->
<!-- docgen:doc pkg=cmd/tool section=Flags -->
<!-- /docgen:doc -->
<!-- docgen:code file=v2/examples/hello/main.go -->
<!-- /docgen:code -->
After
# Lamp
This page covers every marker kind.
<!-- docgen:config pkg=machine type=Config -->
| Field | Type | Default | Description |
|---|---|---|---|
| `Wait` | `time.Duration` | `DefaultWait` (250ms) | Wait is how long the Lamp stays on. 0 means DefaultWait. |
| `Tries` | `int` | `1` | Tries is the number of blinks. 0 means 1, and it is at most MaxTries. |
| `Name` | `string` | zero value | Name is a label. |
<!-- /docgen:config -->
The default wait is <!-- docgen:const pkg=machine name=DefaultWait -->`250ms`<!-- /docgen:const --> and at most <!-- docgen:const pkg=machine name=MaxTries -->`3`<!-- /docgen:const --> tries.
<!-- docgen:states pkg=machine type=Lamp -->
States of [`Lamp`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#Lamp), from [`Lamp.State`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#Lamp.State):
| State | Meaning | Seen in tests |
|---|---|---|
| [`LampOff`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#LampOff) | LampOff gives no light. | yes, first state |
| [`LampOn`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#LampOn) | LampOn gives light. | yes |
| [`LampBroken`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#LampBroken) | LampBroken never gives light again. | yes |
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| LampOff | `Start` | LampOn |
| LampOff | `Break` | LampBroken |
| LampOn | `Stop`, `Tick` | LampOff |

<!-- /docgen:states -->
<!-- docgen:states pkg=machine type=Counter -->
[`Counter`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#Counter) has no State method. The state in this table is the result of `Len()`. States seen in tests:
| State | Seen in tests |
|---|---|
| Len() 0 | yes, first state |
| Len() > 0 | yes |
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| Len() 0 | `Add` | Len() > 0 |
| Len() > 0 | `Clear` | Len() 0 |

<!-- /docgen:states -->
<!-- docgen:errors pkg=machine type=Lamp -->
| Error | Returned by | Meaning |
|---|---|---|
| [`docgen.ConfigError`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2#ConfigError) | `NewLamp` | ConfigError is the error of a constructor for a field with a value out of range. |
| [`machine.ErrBusy`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#ErrBusy) | `Lamp.Start` | ErrBusy is returned by Start while the Lamp is on. |
| [`machine.ErrOff`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#ErrOff) | `Lamp.Stop` | ErrOff is returned by Stop while the Lamp is off. |
<!-- /docgen:errors -->
<!-- docgen:states pkg=machine type=SideState -->
States of [`Pair`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#Pair), from [`Pair.SideState`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#Pair.SideState) for each `Side`:
| State | Meaning | Seen in tests |
|---|---|---|
| [`SideDown`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#SideDown) | SideDown is down. | yes, first state |
| [`SideUp`](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#SideUp) | SideUp is up. | yes |
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| SideDown | `Raise` | SideUp |

<!-- /docgen:states -->
The period is <!-- docgen:const pkg=machine name=period -->`30ms`<!-- /docgen:const --> and the hold <!-- docgen:const pkg=machine name=hold -->`120ms`<!-- /docgen:const -->.
<!-- docgen:doc pkg=machine section=Rates -->
A Lamp blinks at these rates:
- slow, every [DefaultWait](https://pkg.go.dev/github.com/USA-RedDragon/docgen/v2/machine#DefaultWait)
- fast, every period
<!-- /docgen:doc -->
<!-- docgen:doc pkg=machine name=Lamp.Start -->
Start turns the Lamp on. It returns ErrBusy while the Lamp is on.
<!-- /docgen:doc -->
<!-- docgen:code file=v2/machine/machine.go lines=96-102 -->
```go
func (l *Lamp) Stop() error {
if l.state != LampOn {
return ErrOff
}
l.off()
return nil
}
```
<!-- /docgen:code -->
<!-- docgen:output test=machine.ExampleLamp -->
```text
true
```
<!-- /docgen:output -->
<!-- docgen:output cmd=v2/examples/hello -->
```text
hello from the fixture
```
<!-- /docgen:output -->
<!-- docgen:code file=v2/machine/example_test.go symbol=ExampleLamp -->
```go
func ExampleLamp() {
l, _ := machine.NewLamp(machine.Config{})
_ = l.Start(0)
fmt.Println(l.State() == machine.LampOn)
}
```
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=Lamp.Tick -->
```go
func (l *Lamp) Tick(now time.Duration) {
if l.state == LampOn && now >= l.until {
l.off()
}
}
```
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=SideState -->
```go
type SideState uint8
```
<!-- /docgen:code -->
<!-- docgen:code file=v2/machine/machine.go symbol=SideB -->
```go
const (
// SideA is the first side.
SideA Side = iota + 1
// SideB is the second side.
SideB
)
```
<!-- /docgen:code -->
It needs Go <!-- docgen:gomod field=go -->`1.24.0`<!-- /docgen:gomod --> or later.
<!-- docgen:usage cmd=cmd/tool -->
```text
Usage of tool:
-n int
how many lines to print (default 3)
```
<!-- /docgen:usage -->
<!-- docgen:doc pkg=cmd/tool section=Flags -->
It takes one flag.
<!-- /docgen:doc -->
<!-- docgen:code file=v2/examples/hello/main.go -->
```go
// Command hello prints a greeting.
package main
import "fmt"
func main() {
fmt.Println("hello from the fixture")
}
```
<!-- /docgen:code -->
Preview
Lamp
This page covers every marker kind.
| Field | Type | Default | Description |
|---|---|---|---|
Wait |
time.Duration |
DefaultWait (250ms) |
Wait is how long the Lamp stays on. 0 means DefaultWait. |
Tries |
int |
1 |
Tries is the number of blinks. 0 means 1, and it is at most MaxTries. |
Name |
string |
zero value | Name is a label. |
The default wait is 250ms and at most 3 tries.
States of Lamp, from Lamp.State:
| State | Meaning | Seen in tests |
|---|---|---|
LampOff |
LampOff gives no light. | yes, first state |
LampOn |
LampOn gives light. | yes |
LampBroken |
LampBroken never gives light again. | yes |
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| LampOff | Start |
LampOn |
| LampOff | Break |
LampBroken |
| LampOn | Stop, Tick |
LampOff |
Counter has no State method. The state in this table is the result of Len(). States seen in tests:
| State | Seen in tests |
|---|---|
| Len() 0 | yes, first state |
| Len() > 0 | yes |
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| Len() 0 | Add |
Len() > 0 |
| Len() > 0 | Clear |
Len() 0 |
| Error | Returned by | Meaning |
|---|---|---|
docgen.ConfigError |
NewLamp |
ConfigError is the error of a constructor for a field with a value out of range. |
machine.ErrBusy |
Lamp.Start |
ErrBusy is returned by Start while the Lamp is on. |
machine.ErrOff |
Lamp.Stop |
ErrOff is returned by Stop while the Lamp is off. |
States of Pair, from Pair.SideState for each Side:
Transitions seen in tests:
| From | Method call | To |
|---|---|---|
| SideDown | Raise |
SideUp |
The period is 30ms and the hold 120ms.
A Lamp blinks at these rates:
- slow, every DefaultWait
- fast, every period
Start turns the Lamp on. It returns ErrBusy while the Lamp is on.
func (l *Lamp) Stop() error {
if l.state != LampOn {
return ErrOff
}
l.off()
return nil
}true
hello from the fixture
func ExampleLamp() {
l, _ := machine.NewLamp(machine.Config{})
_ = l.Start(0)
fmt.Println(l.State() == machine.LampOn)
}func (l *Lamp) Tick(now time.Duration) {
if l.state == LampOn && now >= l.until {
l.off()
}
}type SideState uint8const (
// SideA is the first side.
SideA Side = iota + 1
// SideB is the second side.
SideB
)It needs Go 1.24.0 or later.
Usage of tool:
-n int
how many lines to print (default 3)
It takes one flag.
// Command hello prints a greeting.
package main
import "fmt"
func main() {
fmt.Println("hello from the fixture")
}Source: docs/reference/sample-page.md