Skip to content

Commit 70c2daa

Browse files
committed
go25: generatehtml works by passing an arg instead of tags, which don't transfer across modules. verified that lab/docs and compcogneuro/web work, whereas they did not before. also, it uses -nogui instead of offscreen tags.
1 parent cbc567a commit 70c2daa

13 files changed

Lines changed: 102 additions & 126 deletions

File tree

base/websocket/websocket_generatehtml.go

Lines changed: 0 additions & 31 deletions
This file was deleted.

base/websocket/websocket_notjs.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build !js && !generatehtml
5+
//go:build !js
66

77
package websocket
88

99
import (
1010
"cogentcore.org/core/base/errors"
11+
"cogentcore.org/core/system"
1112
"github.com/gorilla/websocket"
1213
)
1314

@@ -24,6 +25,9 @@ type Client struct {
2425

2526
// Connect connects to a WebSocket server and returns a [Client].
2627
func Connect(url string) (*Client, error) {
28+
if system.GenerateHTMLArg() {
29+
return &Client{}, nil
30+
}
2731
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
2832
if err != nil {
2933
return nil, err
@@ -34,6 +38,9 @@ func Connect(url string) (*Client, error) {
3438
// OnMessage sets a callback function to be called when a message is received.
3539
// This function can only be called once.
3640
func (c *Client) OnMessage(f func(typ MessageTypes, msg []byte)) {
41+
if system.GenerateHTMLArg() {
42+
return
43+
}
3744
go func() {
3845
for {
3946
typ, msg, err := c.conn.ReadMessage()
@@ -48,19 +55,28 @@ func (c *Client) OnMessage(f func(typ MessageTypes, msg []byte)) {
4855

4956
// Send sends a message to the WebSocket server with the given type and message.
5057
func (c *Client) Send(typ MessageTypes, msg []byte) error {
58+
if system.GenerateHTMLArg() {
59+
return nil
60+
}
5161
return c.conn.WriteMessage(int(typ), msg)
5262
}
5363

5464
// Close cleanly closes the WebSocket connection.
5565
// It does not directly trigger [Client.OnClose], but once the connection
5666
// is closed, [Client.OnMessage] will trigger it.
5767
func (c *Client) Close() error {
68+
if system.GenerateHTMLArg() {
69+
return nil
70+
}
5871
return c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
5972
}
6073

6174
// OnClose sets a callback function to be called when the connection is closed.
6275
// This function can only be called once.
6376
func (c *Client) OnClose(f func()) {
77+
if system.GenerateHTMLArg() {
78+
return
79+
}
6480
go func() {
6581
<-c.done
6682
f()

cmd/web/build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func makeFiles(c *config.Config) error {
109109

110110
preRenderHTML := ""
111111
if c.Web.GenerateHTML {
112-
preRenderHTML, err = exec.Output("go", "run", "-tags", "offscreen,generatehtml", ".")
112+
preRenderHTML, err = exec.Output("go", "run", ".", "-generatehtml", "-nogui")
113113
if err != nil {
114114
return err
115115
}

content/generatehtml.go

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build generatehtml
6-
75
package content
86

97
import (
10-
"fmt"
11-
"os"
128
"strings"
139

1410
"cogentcore.org/core/base/errors"
@@ -18,51 +14,50 @@ import (
1814
"cogentcore.org/core/tree"
1915
)
2016

21-
// This file is activated by the core tool to pre-render Cogent Core apps
22-
// as HTML that can be used as a preview and for SEO purposes.
23-
2417
func init() {
25-
// We override the OnChildAdded set in core/generatehtml.go
26-
core.ExternalParent.AsWidget().SetOnChildAdded(func(n tree.Node) {
27-
var ct *Content
28-
n.AsTree().WalkDown(func(n tree.Node) bool {
29-
if ct != nil {
18+
core.GenerateHTML = generateHTML
19+
}
20+
21+
// GenerateHTML is called by the core tool to pre-render Cogent Core apps
22+
// as HTML that can be used as a preview and for SEO purposes.
23+
func generateHTML(w core.Widget) string {
24+
var ct *Content
25+
w.AsTree().WalkDown(func(n tree.Node) bool {
26+
if ct != nil {
27+
return tree.Break
28+
}
29+
if c, ok := n.(*Content); ok {
30+
ct = c
31+
return tree.Break
32+
}
33+
return tree.Continue
34+
})
35+
if ct == nil {
36+
return core.GenerateHTMLCore(w) // basic fallback
37+
}
38+
prps := []*bcontent.PreRenderPage{}
39+
ct.UpdateTree() // need initial update first
40+
for _, pg := range ct.pages {
41+
ct.Open(pg.URL)
42+
prp := &bcontent.PreRenderPage{
43+
Page: *pg,
44+
HTML: core.GenerateHTMLCore(ct),
45+
}
46+
// The first non-emphasized paragraph is used as the description
47+
// (<em> typically indicates a note or caption, not an introduction).
48+
ct.WalkDown(func(n tree.Node) bool {
49+
if prp.Description != "" {
3050
return tree.Break
3151
}
32-
if c, ok := n.(*Content); ok {
33-
ct = c
34-
return tree.Break
52+
if tx, ok := n.(*core.Text); ok {
53+
if tx.Property("tag") == "p" && !strings.HasPrefix(tx.Text, "<em>") {
54+
prp.Description = tx.Text
55+
return tree.Break
56+
}
3557
}
3658
return tree.Continue
3759
})
38-
if ct == nil {
39-
fmt.Println(core.GenerateHTML(n.(core.Widget))) // basic fallback
40-
os.Exit(0)
41-
}
42-
prps := []*bcontent.PreRenderPage{}
43-
ct.UpdateTree() // need initial update first
44-
for _, pg := range ct.pages {
45-
ct.Open(pg.URL)
46-
prp := &bcontent.PreRenderPage{
47-
Page: *pg,
48-
HTML: core.GenerateHTML(ct),
49-
}
50-
// The first non-emphasized paragraph is used as the description
51-
// (<em> typically indicates a note or caption, not an introduction).
52-
ct.WalkDown(func(n tree.Node) bool {
53-
if prp.Description != "" {
54-
return tree.Break
55-
}
56-
if tx, ok := n.(*core.Text); ok {
57-
if tx.Property("tag") == "p" && !strings.HasPrefix(tx.Text, "<em>") {
58-
prp.Description = tx.Text
59-
return tree.Break
60-
}
61-
}
62-
return tree.Continue
63-
})
64-
prps = append(prps, prp)
65-
}
66-
fmt.Println(string(errors.Log1(jsonx.WriteBytes(prps))))
67-
})
60+
prps = append(prps, prp)
61+
}
62+
return string(errors.Log1(jsonx.WriteBytes(prps)))
6863
}

core/generatehtml.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,24 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build generatehtml
6-
75
package core
86

97
import (
10-
"fmt"
118
"log/slog"
129
"os"
13-
14-
"cogentcore.org/core/tree"
1510
)
1611

17-
// This file is activated by the core tool to pre-render Cogent Core apps
18-
// as HTML that can be used as a preview and for SEO purposes.
12+
// GenerateHTML is the Function to call for the -generatehtml argument.
13+
// it returns generated HTML for the given widget.
14+
// It exits the program if there is an error, but does not exit
15+
// the program if there is no error.
16+
var GenerateHTML func(w Widget) string
1917

2018
func init() {
21-
wb := NewWidgetBase()
22-
ExternalParent = wb
23-
wb.SetOnChildAdded(func(n tree.Node) {
24-
fmt.Println(GenerateHTML(n.(Widget)))
25-
os.Exit(0)
26-
})
19+
GenerateHTML = GenerateHTMLCore
2720
}
2821

29-
// GenerateHTML returns generated HTML for the given widget.
30-
// It exits the program if there is an error, but does not exit
31-
// the program if there is no error.
32-
func GenerateHTML(w Widget) string {
22+
func GenerateHTMLCore(w Widget) string {
3323
wb := w.AsWidget()
3424
wb.UpdateTree()
3525
wb.StyleTree()

core/mainstage.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"image"
1010
"log/slog"
11+
"os"
1112

1213
"cogentcore.org/core/cursors"
1314
"cogentcore.org/core/events"
@@ -32,6 +33,19 @@ func newMainStage(typ StageTypes, sc *Scene) *Stage {
3233
return st
3334
}
3435

36+
func generateHTMLBody(bd *Body) {
37+
if !system.GenerateHTMLArg() || ExternalParent != nil {
38+
return
39+
}
40+
wb := NewWidgetBase()
41+
ExternalParent = wb
42+
wb.SetOnChildAdded(func(n tree.Node) {
43+
fmt.Println(GenerateHTML(n.(Widget)))
44+
os.Exit(0)
45+
})
46+
bd.handleExternalParent()
47+
}
48+
3549
// RunMainWindow creates a new main window from the body,
3650
// runs it, starts the app's main loop, and waits for all windows
3751
// to close. It should typically be called once by every app at
@@ -40,6 +54,7 @@ func newMainStage(typ StageTypes, sc *Scene) *Stage {
4054
// If you need to configure the [Stage] further, use [Body.NewWindow]
4155
// and then [Stage.RunMain] on the resulting [Stage].
4256
func (bd *Body) RunMainWindow() {
57+
generateHTMLBody(bd)
4358
if ExternalParent != nil {
4459
bd.handleExternalParent()
4560
return
@@ -54,6 +69,7 @@ func (bd *Body) RunMainWindow() {
5469
// on the [Stage]. It can not be called more than once for one app.
5570
// For secondary stages, see [Stage.Run].
5671
func (st *Stage) RunMain() {
72+
generateHTMLBody(st.Scene.Body)
5773
if ExternalParent != nil {
5874
st.Scene.Body.handleExternalParent()
5975
return
@@ -80,6 +96,7 @@ var waitCalled bool
8096
// For the first window of your app, you should typically call
8197
// [Body.RunMainWindow] instead.
8298
func (bd *Body) RunWindow() *Stage {
99+
generateHTMLBody(bd)
83100
if ExternalParent != nil && !waitCalled {
84101
bd.handleExternalParent()
85102
return nil

gpu/glfw.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build !offscreen && ((darwin && !ios) || windows || (linux && !android) || dragonfly || openbsd)
5+
//go:build (darwin && !ios) || windows || (linux && !android) || dragonfly || openbsd
66

77
package gpu
88

99
import (
1010
"image"
1111

1212
"cogentcore.org/core/base/errors"
13+
"cogentcore.org/core/system"
1314
"github.com/cogentcore/webgpu/wgpu"
1415
"github.com/cogentcore/webgpu/wgpuglfw"
1516
"github.com/go-gl/glfw/v3.3/glfw"
@@ -42,6 +43,9 @@ func Terminate() {
4243
// GLFWCreateWindow is a helper function intended only for use in simple examples that makes a
4344
// new window with glfw on platforms that support it and is largely a no-op on other platforms.
4445
func GLFWCreateWindow(size image.Point, title string, resize *func(size image.Point)) (surface *wgpu.Surface, terminate func(), pollEvents func() bool, actualSize image.Point, err error) {
46+
if system.GenerateHTMLArg() {
47+
return
48+
}
4549
if err = Init(); err != nil {
4650
return
4751
}

gpu/glfw_generatehtml.go

Lines changed: 0 additions & 26 deletions
This file was deleted.

system/app.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package system
1414

1515
import (
1616
"fmt"
17+
"os"
1718
"runtime/debug"
1819

1920
"cogentcore.org/core/styles"
@@ -283,3 +284,13 @@ func init() {
283284
}
284285
}
285286
}
287+
288+
// GenerateHTMLArg returns true if the first [os.Args] is -generatehtml.
289+
// Apps that process args should test this first and skip arg processing
290+
// if true.
291+
func GenerateHTMLArg() bool {
292+
if len(os.Args) < 2 {
293+
return false
294+
}
295+
return os.Args[1] == "-generatehtml"
296+
}

system/driver/driver_android.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build android && !offscreen
5+
//go:build android
66

77
package driver
88

0 commit comments

Comments
 (0)