diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a31ff8d7..9f825540 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -46,6 +46,8 @@ jobs: - name: Build book run: | go run cmd/docs/main.go api > docs/src/generated-api.md + go run cmd/docs/main.go frames > docs/src/generated-frames.md + go run cmd/docs/main.go animations > docs/src/generated-animations.md cd docs mdbook build diff --git a/cmd/docs/main.go b/cmd/docs/main.go index 004119cf..50b40e10 100644 --- a/cmd/docs/main.go +++ b/cmd/docs/main.go @@ -6,7 +6,9 @@ import ( "sort" "strings" + "github.com/cfoust/cy/pkg/anim" "github.com/cfoust/cy/pkg/cy" + F "github.com/cfoust/cy/pkg/frames" "github.com/cfoust/cy/pkg/janet" "github.com/alecthomas/kong" @@ -18,8 +20,9 @@ import _ "embed" var GEN_API string var CLI struct { - API struct { - } `cmd:"" help:"Generate Markdown for the full API."` + API struct{} `cmd:"" help:"Generate Markdown for the full API."` + Frames struct{} `cmd:"" help:"Generate Markdown for frames."` + Animations struct{} `cmd:"" help:"Generate Markdown for animations."` } type Symbol struct { @@ -127,6 +130,53 @@ func main() { `, symbol.Name, _type, first, rest, source) } + fmt.Println(output) + case "frames": + frames := make([]string, 0) + for name := range F.Frames { + frames = append(frames, name) + } + sort.SliceStable(frames, func(i, j int) bool { + return frames[i] < frames[j] + }) + + output := "\n---\n" + + for _, frame := range frames { + set := fmt.Sprintf("```janet\n(frame/set \"%s\")\n```\n", frame) + output += fmt.Sprintf(` +#### %s + +%s + +{{png frame/%s}} + +--- +`, frame, set, frame) + } + + fmt.Println(output) + case "animations": + animations := make([]string, 0) + for name := range anim.Animations { + animations = append(animations, name) + } + sort.SliceStable(animations, func(i, j int) bool { + return animations[i] < animations[j] + }) + + output := "\n---\n" + + for _, animation := range animations { + output += fmt.Sprintf(` +#### %s + +{{gif animation/%s}} + +--- +`, animation, animation) + } + fmt.Println(output) default: panic(ctx.Command()) diff --git a/cmd/stories/main.go b/cmd/stories/main.go index 2ebbfef9..002374e8 100644 --- a/cmd/stories/main.go +++ b/cmd/stories/main.go @@ -11,6 +11,7 @@ import ( "github.com/cfoust/cy/pkg/geom" "github.com/cfoust/cy/pkg/geom/image" "github.com/cfoust/cy/pkg/mux" + "github.com/cfoust/cy/pkg/mux/screen" _ "github.com/cfoust/cy/pkg/mux/screen/replay/stories" _ "github.com/cfoust/cy/pkg/mux/screen/splash/stories" "github.com/cfoust/cy/pkg/mux/stream/cli" @@ -29,6 +30,52 @@ var CLI struct { Single string `help:"Show a single story in full screen, overriding its config." name:"single" optional:"" short:"s"` } +func createInitial(size geom.Size) image.Image { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + story, ok := stories.Stories["input/find/top-left"] + if !ok { + panic(fmt.Errorf("no filler story")) + } + + viewer := stories.NewViewer( + ctx, + story.Init(ctx), + stories.Config{}, + ) + + innerLayers := screen.NewLayers() + innerLayers.NewLayer( + ctx, + viewer, + screen.PositionTop, + screen.WithOpaque, + screen.WithInteractive, + ) + margins := screen.NewMargins(ctx, innerLayers) + + outerLayers := screen.NewLayers() + frame := frames.NewFramer(ctx, frames.RandomFrame()) + outerLayers.NewLayer( + ctx, + frame, + screen.PositionTop, + ) + + outerLayers.NewLayer( + ctx, + margins, + screen.PositionTop, + screen.WithInteractive, + screen.WithOpaque, + ) + + outerLayers.Resize(size) + + return outerLayers.State().Image +} + func main() { kong.Parse(&CLI, kong.Name("cy-stories"), @@ -63,6 +110,8 @@ func main() { }(frame) } + initial := createInitial(geom.DEFAULT_SIZE) + for name, animation := range anim.Animations { func(a anim.Animation) { stories.Register( @@ -71,8 +120,7 @@ func main() { animator := anim.NewAnimator( ctx, a, - // TODO(cfoust): 11/17/23 replace with cy splash - image.New(geom.DEFAULT_SIZE), + initial.Clone(), 23, ) return animator diff --git a/docs/book.toml b/docs/book.toml index 3eb86aad..82e05eca 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -13,3 +13,4 @@ site-url = "/cy/" [preprocessor.storybook] command = "python3 storybook.py" +after = [ "links" ] diff --git a/docs/src/.gitignore b/docs/src/.gitignore index 853b820d..fa5f9ad7 100644 --- a/docs/src/.gitignore +++ b/docs/src/.gitignore @@ -1,2 +1,2 @@ -/generated-api.md +generated-*.md /images diff --git a/docs/src/animations.md b/docs/src/animations.md index 614c997f..d79099b7 100644 --- a/docs/src/animations.md +++ b/docs/src/animations.md @@ -1 +1,3 @@ # Animations + +{{#include generated-animations.md}} diff --git a/docs/src/frames.md b/docs/src/frames.md index ce4912f6..94927ca4 100644 --- a/docs/src/frames.md +++ b/docs/src/frames.md @@ -1 +1,3 @@ # Frames + +{{#include generated-frames.md}} diff --git a/docs/storybook.py b/docs/storybook.py index ae29a183..5739c248 100644 --- a/docs/storybook.py +++ b/docs/storybook.py @@ -19,13 +19,10 @@ # all the rendering jobs that need to be done jobs = {} - for section in book['sections']: - if not 'Chapter' in section: - continue - - content = section['Chapter']['content'] + def transform_chapter(chapter): replace = [] + content = chapter['content'] for ref in STORY_REGEX.finditer(content): type_ = ref.group(3) filename = ref.group(2) @@ -57,7 +54,19 @@ for start, end, text in reversed(replace): content = content[:start] + text + content[end:] - section['Chapter']['content'] = content + chapter['content'] = content + + for subitem in chapter['sub_items']: + if not 'Chapter' in subitem: + continue + + transform_chapter(subitem['Chapter']) + + for section in book['sections']: + if not 'Chapter' in section: + continue + + transform_chapter(section['Chapter']) Path("./src/images").mkdir(parents=True, exist_ok=True) @@ -66,6 +75,8 @@ if os.path.exists(filename): continue if os.path.exists(tape): os.unlink(tape) + print(f"~> building {filename} ({command})", file=sys.stderr) + script = "" if filename.endswith(".gif"): script = f""" @@ -82,11 +93,13 @@ """ elif filename.endswith(".png"): script = f""" +Set Padding 0 Hide Type "./stories -s {command} && clear" Enter Sleep 2s Show +Sleep 1s Screenshot {filename} """ @@ -103,4 +116,5 @@ if os.path.exists(tape): os.unlink(tape) + print("blah", file=sys.stderr) print(json.dumps(book)) diff --git a/pkg/anim/collapse.go b/pkg/anim/collapse.go index 1284594d..6cdd4440 100644 --- a/pkg/anim/collapse.go +++ b/pkg/anim/collapse.go @@ -45,3 +45,7 @@ func (c *Collapse) Update(delta time.Duration) image.Image { return c.current } + +func init() { + registerAnimation("collapse", &Collapse{}) +} diff --git a/pkg/anim/conway.go b/pkg/anim/conway.go index 098a243a..85a12c8e 100644 --- a/pkg/anim/conway.go +++ b/pkg/anim/conway.go @@ -94,3 +94,7 @@ func (c *Conway) Update(delta time.Duration) image.Image { c.image = next return c.image } + +func init() { + registerAnimation("conway", &Conway{}) +} diff --git a/pkg/anim/form.go b/pkg/anim/form.go index 10ffecf7..d7ce6663 100644 --- a/pkg/anim/form.go +++ b/pkg/anim/form.go @@ -51,3 +51,7 @@ func (c *Cyform) Update(delta time.Duration) image.Image { return c.start } + +func init() { + registerAnimation("cy", &Cyform{}) +} diff --git a/pkg/anim/midjo.go b/pkg/anim/midjo.go index 1a14c98d..c0a81993 100644 --- a/pkg/anim/midjo.go +++ b/pkg/anim/midjo.go @@ -44,3 +44,7 @@ func (mid *Midjo) Update(delta time.Duration) image.Image { } return mid.out } + +func init() { + registerAnimation("midjo", &Midjo{}) +} diff --git a/pkg/frames/frame.go b/pkg/frames/frame.go index 544e9440..41634778 100644 --- a/pkg/frames/frame.go +++ b/pkg/frames/frame.go @@ -29,6 +29,5 @@ func RandomFrame() Frame { } func init() { - registerFrame("none", func(state image.Image) { - }) + registerFrame("none", func(state image.Image) {}) }