- suite rule дописывает правило: номер берётся следующим за наибольшим, блоки раскладываются в порядке норма, ПОЧЕМУ, ПРИМЕРЫ, --after ставит правило рядом с тем, которое оно уточняет - ступень называется категорией (requirement, prohibition, ...), а не словом языка, поэтому вызывающему не нужно знать, на каком языке записан набор - suite list показывает темы со слоями, а с осью — что возьмёт компонент; отбор слоёв вынесен в suite.Assemble, откуда его возьмут проектные команды - слои темы теперь всегда возвращаются базовым вперёд
72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package suite
|
|
|
|
import "git.vakhrushev.me/av/convy/internal/doc"
|
|
|
|
// Component is what a copy is assembled for: one language, one stack, one kind
|
|
// of application. Both axes may stay empty — a flat suite has no axes at all,
|
|
// and a component of it selects the base layer and nothing else.
|
|
type Component struct {
|
|
Lang string
|
|
Stack string
|
|
}
|
|
|
|
// Assemble picks the layers of a topic a component takes, in the order they go
|
|
// into a copy: base, then language, then stack.
|
|
//
|
|
// A layer is chosen by the axis keys of its front matter rather than by where
|
|
// its file lies (META-38). A layer with no keys is the base one and travels
|
|
// always; a key the layer does not declare puts no demand on the component, so
|
|
// a language layer with no stack key fits any stack.
|
|
//
|
|
// This is the read-only half of assembly. The project commands write files out
|
|
// of the same selection, so the two must never come to differ — which is why
|
|
// the selection lives here rather than inside whichever command needs it.
|
|
func (s *Suite) Assemble(topic string, c Component) (taken, left []*doc.Document) {
|
|
for _, d := range s.Layers(topic) {
|
|
if fits(d, c) {
|
|
taken = append(taken, d)
|
|
continue
|
|
}
|
|
left = append(left, d)
|
|
}
|
|
return taken, left
|
|
}
|
|
|
|
// fits reports whether a component takes a layer.
|
|
func fits(d *doc.Document, c Component) bool {
|
|
if d.Front.Lang != "" && d.Front.Lang != c.Lang {
|
|
return false
|
|
}
|
|
if d.Front.Stack != "" && d.Front.Stack != c.Stack {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// rank orders the layers of a topic the way a copy carries them. A layer on
|
|
// both axes comes last: it narrows the most.
|
|
func rank(d *doc.Document) int {
|
|
switch {
|
|
case d.Front.Lang == "" && d.Front.Stack == "":
|
|
return 0
|
|
case d.Front.Stack == "":
|
|
return 1
|
|
case d.Front.Lang == "":
|
|
return 2
|
|
}
|
|
return 3
|
|
}
|
|
|
|
// Axis describes a layer in one word, for a report.
|
|
func Axis(d *doc.Document) string {
|
|
switch {
|
|
case d.Front.Lang != "" && d.Front.Stack != "":
|
|
return "lang=" + d.Front.Lang + " stack=" + d.Front.Stack
|
|
case d.Front.Lang != "":
|
|
return "lang=" + d.Front.Lang
|
|
case d.Front.Stack != "":
|
|
return "stack=" + d.Front.Stack
|
|
}
|
|
return "base"
|
|
}
|