Repos / s4g / 1fbb2934bb
commit 1fbb2934bb4ec0010a5b5f0ac8611c36f926312f
Author: Nhân <hi@imnhan.com>
Date: Sun Aug 6 12:37:08 2023 +0700
rename to s4g; remove gui
diff --git a/README.md b/README.md
index 03a3bc8..b308cf2 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,13 @@
**Warning: work in progress**
-WebMaker2000 is an in-place static site generator, meaning processed files are
-stored right next to their sources. This simplifies composing (source dir
-layout _is_ finished website layout; static assets no longer need to be moved
-around) and publishing (simply `rsync`/`git push` your whole dir). It aims to
-be beginner-friendly while encouraging users to fiddle with html/css. To that
-end, the core feature set is intentionally simple:
+`s4g` (Stupidly Simple Static Site Generator) is an in-place static site
+generator, meaning processed files are stored right next to their sources.
+This simplifies composing (source dir layout _is_ finished website layout;
+static assets no longer need to be moved around) and publishing
+(simply `rsync`/`git push` your whole dir).
+It aims to be beginner-friendly while encouraging users to fiddle with
+html/css. To that end, the core feature set is intentionally simple:
- [x] Finds all `*.dj` files, generates `*.html` in the same place
+ Per-page metadata allows using custom template
@@ -16,15 +17,13 @@
- [x] Generates RSS/Atom feed
- [x] Generates redirects from a `redirects.txt` file
-Quality-of-life features are not neglected:
+Quality-of-life features:
- [x] Livereload with no browser plugin (works but currently polls which is
noisy, should probably upgrade to websockets)
- [x] Shows user error messages on the livereloaded web page
-- [ ] Just enough GUI so user doesn't have to touch a terminal
-- [ ] 1-click deploy to popular static hosting targets (git push, rsync, etc.)
-There's a sample site up at <https://nhanb.github.io/webmaker2000/about/> which
+There's a sample site up at <https://nhanb.github.io/s4g/about/> which
also further explains why this project exists.
The markup language of choice is [Djot](https://djot.net/) because it's the
@@ -37,15 +36,13 @@
```sh
# Install
-go install go.imnhan.com/webmaker2000@latest
+go install go.imnhan.com/s4g@latest
# Create new site
-webmaker2000 new -f ~/my-blog
+s4g new -f ~/my-blog
# Run program, which:
# - listens to changes and automatically re-generates
# - starts a local HTTP server for preview, also livereloads on changes
-webmaker2000 serve -f ~/my-blog
+s4g serve -f ~/my-blog
```
-
-GUI Coming Soon (tm).
diff --git a/docs/_theme/includes.tmpl b/docs/_theme/includes.tmpl
index 7f9fdcb..aa3130b 100644
--- a/docs/_theme/includes.tmpl
+++ b/docs/_theme/includes.tmpl
@@ -23,7 +23,7 @@
{{- if .Site.ShowFooter -}}
<footer>
© {{if eq .StartYear .Now.Year}}{{.StartYear}}{{else}}{{.StartYear}}–{{.Now.Year}}{{end}} {{.Site.AuthorName}}<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
{{- end -}}
{{- end}}
diff --git a/docs/about/index.dj b/docs/about/index.dj
index eed959a..bbe60d5 100644
--- a/docs/about/index.dj
+++ b/docs/about/index.dj
@@ -2,7 +2,7 @@ Title: About
ShowInFeed: false
---
-This is a sample website to demonstrate some features of [WebMaker2000][1].
+This is a sample website to demonstrate some features of [s4g][1].
It also doubles as a lazy end-to-end test suite until the core design
stablizes. Its source code, as well as output, is in the [/docs/][src] dir.
@@ -11,23 +11,10 @@ Don't worry too much about their actual content.
## Sales pitch
-There are 2 main goals:
-
-### 1. Enable more people to Have Opinions On The Internet
-
-It's 2023. Bug-ridden CVE-infested custom-ordered Wordpress sites shouldn't be
-the layman's default option anymore. [Free][gh] [static][gl] [hosting][cf] is
-[available][nc] everywhere, yet it remains a privilege mostly enjoyed by a
-selective group of nerds who are already well versed with the command line. I
-aim to make a user-friendly static site generator that also allows publishing
-to neocities/git/rsync targets with one click.
-
-### 2. Encourage creativity in web design
-
-WebMaker2000 strives to assist, not obscure or constrain. It assumes little
-structure, and encourages personalization. {-The world needs more-} I want more
-creative, [weird][cozy], [neocities-frontpage-worthy][ncf] websites instead of
-yet another cookie-cutter jekyll template.
+s4g aims to assist, not obscure. All it does is reading `.dj` files and
+spitting out `.html`s, leaving unrelated files alone. This means the user is
+free to structure their web directory however they want, and relative links
+work out of the box.
## Features
@@ -40,9 +27,8 @@ So far we have:
Less obvious features:
- Flexible root dir (the finished site can be served from a subfolder)
-- Livereload on local server
-
-GUI Coming Soon™.
+- Livereload
+- In-browser error messages
``` =html
<style>
@@ -50,11 +36,5 @@ h3 { font-size: 1em; }
</style>
```
-[1]: https://github.com/nhanb/webmaker2000
-[gh]: https://pages.github.com/
-[gl]: https://docs.gitlab.com/ee/user/project/pages/
-[cf]: https://pages.cloudflare.com/
-[nc]: https://neocities.org/
-[ncf]: https://neocities.org/browse
-[cozy]: https://www.cozynet.org/
-[src]: https://github.com/nhanb/webmaker2000/tree/master/docs
+[1]: https://github.com/nhanb/s4g
+[src]: https://github.com/nhanb/s4g/tree/master/docs
diff --git a/docs/about/index.html b/docs/about/index.html
index d1681b2..4099f11 100644
--- a/docs/about/index.html
+++ b/docs/about/index.html
@@ -5,16 +5,16 @@
<meta charset="utf-8" />
<title>About | CoolZone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/webmaker2000/feed.xml">
- <link rel="stylesheet" href="/webmaker2000/_theme/base.css">
+ <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/s4g/feed.xml">
+ <link rel="stylesheet" href="/s4g/_theme/base.css">
</head>
<body>
-<link rel="stylesheet" href="/webmaker2000/_theme/navbar.css">
+<link rel="stylesheet" href="/s4g/_theme/navbar.css">
<nav>
- <a href="/webmaker2000/">Home</a>
- <a href="/webmaker2000/about/">About</a>
+ <a href="/s4g/">Home</a>
+ <a href="/s4g/about/">About</a>
</nav>
<hr class="nav-hr">
@@ -22,30 +22,17 @@
<main>
<h1>About</h1>
-<p>This is a sample website to demonstrate some features of <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>.
+<p>This is a sample website to demonstrate some features of <a href="https://github.com/nhanb/s4g">s4g</a>.
It also doubles as a lazy end-to-end test suite until the core design
-stablizes. Its source code, as well as output, is in the <a href="https://github.com/nhanb/webmaker2000/tree/master/docs">/docs/</a> dir.</p>
+stablizes. Its source code, as well as output, is in the <a href="https://github.com/nhanb/s4g/tree/master/docs">/docs/</a> dir.</p>
<p>The articles themselves are just, uh, <em>colorful</em> lorem ipsums.
Don’t worry too much about their actual content.</p>
<section id="Sales-pitch">
<h2>Sales pitch</h2>
-<p>There are 2 main goals:</p>
-<section id="1-Enable-more-people-to-Have-Opinions-On-The-Internet">
-<h3>1. Enable more people to Have Opinions On The Internet</h3>
-<p>It’s 2023. Bug-ridden CVE-infested custom-ordered Wordpress sites shouldn’t be
-the layman’s default option anymore. <a href="https://pages.github.com/">Free</a> <a href="https://docs.gitlab.com/ee/user/project/pages/">static</a> <a href="https://pages.cloudflare.com/">hosting</a> is
-<a href="https://neocities.org/">available</a> everywhere, yet it remains a privilege mostly enjoyed by a
-selective group of nerds who are already well versed with the command line. I
-aim to make a user-friendly static site generator that also allows publishing
-to neocities/git/rsync targets with one click.</p>
-</section>
-<section id="2-Encourage-creativity-in-web-design">
-<h3>2. Encourage creativity in web design</h3>
-<p>WebMaker2000 strives to assist, not obscure or constrain. It assumes little
-structure, and encourages personalization. <del>The world needs more</del> I want more
-creative, <a href="https://www.cozynet.org/">weird</a>, <a href="https://neocities.org/browse">neocities-frontpage-worthy</a> websites instead of
-yet another cookie-cutter jekyll template.</p>
-</section>
+<p>s4g aims to assist, not obscure. All it does is reading <code>.dj</code> files and
+spitting out <code>.html</code>s, leaving unrelated files alone. This means the user is
+free to structure their web directory however they want, and relative links
+work out of the box.</p>
</section>
<section id="Features">
<h2>Features</h2>
@@ -67,10 +54,12 @@ <h2>Features</h2>
Flexible root dir (the finished site can be served from a subfolder)
</li>
<li>
-Livereload on local server
+Livereload
+</li>
+<li>
+In-browser error messages
</li>
</ul>
-<p>GUI Coming Soon™.</p>
<style>
h3 { font-size: 1em; }
</style>
@@ -80,7 +69,7 @@ <h2>Features</h2>
<footer>
© 2008–2023 Coolio McCool<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
</body>
diff --git a/docs/feed.xml b/docs/feed.xml
index 4947aba..1d62a92 100644
--- a/docs/feed.xml
+++ b/docs/feed.xml
@@ -1,7 +1,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title>CoolZone</title>
<id>https://coolzone.example.com/</id>
- <link rel="self" href="/webmaker2000/feed.xml"></link>
+ <link rel="self" href="/s4g/feed.xml"></link>
<updated>2023-04-05T00:00:00+07:00</updated>
<author>
<name>Coolio McCool</name>
@@ -10,15 +10,15 @@
</author>
<entry>
<title>This is a motherfucking website.</title>
- <id>https://coolzone.example.com/webmaker2000/mfws.html</id>
- <link href="https://coolzone.example.com/webmaker2000/mfws.html"></link>
+ <id>https://coolzone.example.com/s4g/mfws.html</id>
+ <link href="https://coolzone.example.com/s4g/mfws.html"></link>
<published>2023-04-05T00:00:00+07:00</published>
<updated>2023-04-05T00:00:00+07:00</updated>
</entry>
<entry>
<title>I'm Going To Scale My Foot Up Your Ass</title>
- <id>https://coolzone.example.com/webmaker2000/scale/</id>
- <link href="https://coolzone.example.com/webmaker2000/scale/"></link>
+ <id>https://coolzone.example.com/s4g/scale/</id>
+ <link href="https://coolzone.example.com/s4g/scale/"></link>
<published>2008-04-24T00:00:00+07:00</published>
<updated>2008-04-24T00:00:00+07:00</updated>
</entry>
diff --git a/docs/index.html b/docs/index.html
index 839474d..5387fce 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -5,8 +5,8 @@
<meta charset="utf-8" />
<title>Home | CoolZone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/webmaker2000/feed.xml">
- <link rel="stylesheet" href="/webmaker2000/_theme/base.css">
+ <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/s4g/feed.xml">
+ <link rel="stylesheet" href="/s4g/_theme/base.css">
</head>
<body>
@@ -19,10 +19,10 @@ <h1 class="site-title">CoolZone</h1>
<hr>
<div class="pages">
- <a href="/webmaker2000/">Home</a>
- <a href="/webmaker2000/about/">About</a>
- <a class="feed-link" href="/webmaker2000/feed.xml">
- <img src="/webmaker2000/_theme/feed.svg" alt="Atom Feed" title="Atom Feed">
+ <a href="/s4g/">Home</a>
+ <a href="/s4g/about/">About</a>
+ <a class="feed-link" href="/s4g/feed.xml">
+ <img src="/s4g/_theme/feed.svg" alt="Atom Feed" title="Atom Feed">
</a>
</div>
@@ -35,12 +35,12 @@ <h1 class="site-title">CoolZone</h1>
<ul>
<li>
<span class="time-prefix">2023-04-05 — </span>
- <a href="/webmaker2000/mfws.html">This is a motherfucking website.</a>
+ <a href="/s4g/mfws.html">This is a motherfucking website.</a>
<span class="time-suffix">(2023-04-05)</span>
</li>
<li>
<span class="time-prefix">2008-04-24 — </span>
- <a href="/webmaker2000/scale/">I'm Going To Scale My Foot Up Your Ass</a>
+ <a href="/s4g/scale/">I'm Going To Scale My Foot Up Your Ass</a>
<span class="time-suffix">(2008-04-24)</span>
</li>
</ul>
@@ -96,7 +96,7 @@ <h1 class="site-title">CoolZone</h1>
<footer>
© 2008–2023 Coolio McCool<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
diff --git a/docs/mfws.html b/docs/mfws.html
index a45d28d..c3d0595 100644
--- a/docs/mfws.html
+++ b/docs/mfws.html
@@ -5,16 +5,16 @@
<meta charset="utf-8" />
<title>This is a motherfucking website. | CoolZone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/webmaker2000/feed.xml">
- <link rel="stylesheet" href="/webmaker2000/_theme/base.css">
+ <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/s4g/feed.xml">
+ <link rel="stylesheet" href="/s4g/_theme/base.css">
</head>
<body>
-<link rel="stylesheet" href="/webmaker2000/_theme/navbar.css">
+<link rel="stylesheet" href="/s4g/_theme/navbar.css">
<nav>
- <a href="/webmaker2000/">Home</a>
- <a href="/webmaker2000/about/">About</a>
+ <a href="/s4g/">Home</a>
+ <a href="/s4g/about/">About</a>
<span class="posted-on">
Posted on
<time datetime="2023-04-05">
@@ -123,7 +123,7 @@ <h2>Epilogue</h2>
<footer>
© 2008–2023 Coolio McCool<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
</body>
diff --git a/docs/mfws/index.html b/docs/mfws/index.html
index d3ca5e5..23fa9ae 100644
--- a/docs/mfws/index.html
+++ b/docs/mfws/index.html
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
- <title>Redirecting to /webmaker2000/mfws.html</title>
- <meta http-equiv="Refresh" content="0; URL=/webmaker2000/mfws.html" />
+ <title>Redirecting to /s4g/mfws.html</title>
+ <meta http-equiv="Refresh" content="0; URL=/s4g/mfws.html" />
</head>
<body>
- The page you're looking for has been moved to <a href="/webmaker2000/mfws.html">/webmaker2000/mfws.html</a>.
+ The page you're looking for has been moved to <a href="/s4g/mfws.html">/s4g/mfws.html</a>.
</body>
</html>
diff --git a/docs/scale.html b/docs/scale.html
index df77cf9..03d8901 100644
--- a/docs/scale.html
+++ b/docs/scale.html
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
- <title>Redirecting to /webmaker2000/scale/</title>
- <meta http-equiv="Refresh" content="0; URL=/webmaker2000/scale/" />
+ <title>Redirecting to /s4g/scale/</title>
+ <meta http-equiv="Refresh" content="0; URL=/s4g/scale/" />
</head>
<body>
- The page you're looking for has been moved to <a href="/webmaker2000/scale/">/webmaker2000/scale/</a>.
+ The page you're looking for has been moved to <a href="/s4g/scale/">/s4g/scale/</a>.
</body>
</html>
diff --git a/docs/scale/index.html b/docs/scale/index.html
index c22f440..e931c97 100644
--- a/docs/scale/index.html
+++ b/docs/scale/index.html
@@ -5,16 +5,16 @@
<meta charset="utf-8" />
<title>I'm Going To Scale My Foot Up Your Ass | CoolZone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/webmaker2000/feed.xml">
- <link rel="stylesheet" href="/webmaker2000/_theme/base.css">
+ <link rel="alternate" type="application/atom+xml" title="Atom feed" href="/s4g/feed.xml">
+ <link rel="stylesheet" href="/s4g/_theme/base.css">
</head>
<body>
<div class="navbar-container">
-<link rel="stylesheet" href="/webmaker2000/_theme/navbar.css">
+<link rel="stylesheet" href="/s4g/_theme/navbar.css">
<nav>
- <a href="/webmaker2000/">Home</a>
- <a href="/webmaker2000/about/">About</a>
+ <a href="/s4g/">Home</a>
+ <a href="/s4g/about/">About</a>
<span class="posted-on">
Posted on
<time datetime="2008-04-24">
@@ -96,7 +96,7 @@ <h2>tl;dr</h2>
<div class="footer-container">
<footer>
© 2008–2023 Coolio McCool<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
</div>
diff --git a/docs/website.wbmkr2k b/docs/website.s4g
similarity index 91%
rename from docs/website.wbmkr2k
rename to docs/website.s4g
index cf91244..d2055b0 100644
--- a/docs/website.wbmkr2k
+++ b/docs/website.s4g
@@ -1,7 +1,7 @@
Address: https://coolzone.example.com
Name: CoolZone
Tagline: Cool people only.
-Root: /webmaker2000/
+Root: /s4g/
NavbarLinks: index.dj, about/index.dj
AuthorName: Coolio McCool
diff --git a/errs/errs.go b/errs/errs.go
index 2614757..6a674f6 100644
--- a/errs/errs.go
+++ b/errs/errs.go
@@ -5,7 +5,7 @@
"html/template"
)
-// Represents a user input error, which in webmaker2000's case is almost
+// Represents a user input error, which in s4g's case is almost
// always some malformed file.
type UserErr struct {
File string
diff --git a/go.mod b/go.mod
index 622f03d..af3c911 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module go.imnhan.com/webmaker2000
+module go.imnhan.com/s4g
go 1.20
diff --git a/gui/gui.go b/gui/gui.go
deleted file mode 100644
index cb3ec50..0000000
--- a/gui/gui.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package gui
-
-import (
- "bufio"
- _ "embed"
- "fmt"
- "io"
- "os/exec"
- "path/filepath"
- "strings"
-
- "go.imnhan.com/webmaker2000/gui/ipc"
-)
-
-//go:embed tcl/main.tcl
-var tclMain []byte
-
-//go:embed tcl/choose-task.tcl
-var tclChooseTask []byte
-
-func Main(tclPath string) {
- interp := newInterp(tclPath)
-
- go func() {
- errscanner := bufio.NewScanner(interp.stderr)
- for errscanner.Scan() {
- errtext := errscanner.Text()
- fmt.Printf("XXX %s\n", errtext)
- }
- }()
-
- _, err := interp.stdin.Write(tclMain)
- if err != nil {
- panic(err)
- }
- println("Loaded main tcl script.")
-
- fmt.Fprintln(interp.stdin, "initialize")
-
- respond := func(values ...string) {
- ipc.Respond(interp.stdin, values)
- }
-
- for req := range ipc.Requests(interp.stdout) {
- switch req.Method {
-
- case "forcefocus":
- //err := forceFocus(req.Args[0])
- //if err != nil {
- //fmt.Printf("forcefocus: %s\n", err)
- //}
- respond("ok")
- }
-
- }
-
- println("Tcl process terminated.")
-}
-
-type Task string
-
-const (
- TaskOpen Task = "open"
- TaskCreate Task = "create"
-)
-
-func ChooseTask(tclPath string) (task Task, path string, ok bool) {
- interp := newInterp(tclPath)
- interp.stdin.Write(tclChooseTask)
- interp.stdin.Close()
- resp, err := io.ReadAll(interp.stdout)
- if err != nil {
- panic(err)
- }
-
- action, path, found := strings.Cut(strings.TrimSpace(string(resp)), " ")
- if !found {
- fmt.Println("No task chosen")
- return "", "", false
- }
-
- switch action {
- case string(TaskOpen):
- return TaskOpen, filepath.Dir(path), true
- case string(TaskCreate):
- return TaskCreate, path, true
- default:
- fmt.Printf("Unexpected tclChooseTask output: %s\n", string(resp))
- return "", "", false
- }
-}
-
-type tclInterp struct {
- cmd *exec.Cmd
- stdin io.WriteCloser
- stdout io.ReadCloser
- stderr io.ReadCloser
-}
-
-func newInterp(tclPath string) *tclInterp {
- cmd := exec.Command(tclPath, "-encoding", "utf-8")
- stdout, err := cmd.StdoutPipe()
- if err != nil {
- panic(err)
- }
-
- stdin, err := cmd.StdinPipe()
- if err != nil {
- panic(err)
- }
-
- stderr, err := cmd.StderrPipe()
- if err != nil {
- panic(err)
- }
-
- err = cmd.Start()
- if err != nil {
- panic(err)
- }
-
- return &tclInterp{
- cmd: cmd,
- stdin: stdin,
- stdout: stdout,
- stderr: stderr,
- }
-}
diff --git a/gui/gui_linux.go b/gui/gui_linux.go
deleted file mode 100644
index 877416f..0000000
--- a/gui/gui_linux.go
+++ /dev/null
@@ -1,7 +0,0 @@
-//go:build linux
-
-package gui
-
-const DefaultTclPath = "tclsh"
-
-func forceFocus(handle string) error { return nil }
diff --git a/gui/gui_windows.go b/gui/gui_windows.go
deleted file mode 100644
index f4cf208..0000000
--- a/gui/gui_windows.go
+++ /dev/null
@@ -1,25 +0,0 @@
-//go:build windows
-
-package gui
-
-import (
- "fmt"
- "strconv"
-
- "github.com/lxn/win"
-)
-
-const DefaultTclPath = "./IronTcl/bin/wish86t.exe"
-
-func forceFocus(handle string) error {
- hex := handle[2:] // trim the "0x" prefix
- uintHandle, err := strconv.ParseUint(hex, 16, 64)
- if err != nil {
- return fmt.Errorf("failed to parse handle: %w", err)
- }
-
- h := win.HWND(uintptr(uintHandle))
- win.SetForegroundWindow(h)
- win.SetFocus(h)
- return nil
-}
diff --git a/gui/ipc/ipc.go b/gui/ipc/ipc.go
deleted file mode 100644
index 2a8f426..0000000
--- a/gui/ipc/ipc.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package ipc
-
-import (
- "bufio"
- "fmt"
- "io"
- "log"
- "strconv"
- "strings"
-)
-
-type Request struct {
- Method string
- Args []string
-}
-
-func debug(prefix string, msg string) {
- out := prefix + " " + msg
- if len(out) > 35 {
- out = out[:35] + "[...]"
- }
- fmt.Println(out)
-}
-
-func Requests(r io.Reader) chan Request {
- scanner := bufio.NewScanner(r)
- ch := make(chan Request)
- next := func() string {
- scanner.Scan()
- v := scanner.Text()
- debug("-->", v)
- return v
- }
-
- go func() {
- for scanner.Scan() {
- line := scanner.Text()
- debug("-->", line)
- request := strings.SplitN(line, " ", 2)
- method := request[0]
- numArgs, err := strconv.Atoi(request[1])
- if err != nil {
- panic(err)
- }
- args := make([]string, numArgs)
- for i := 0; i < numArgs; i++ {
- args[i] = next()
- }
-
- ch <- Request{Method: method, Args: args}
- }
- if err := scanner.Err(); err != nil {
- log.Fatal(err)
- }
-
- close(ch)
- }()
-
- return ch
-}
-
-func Respond(w io.Writer, values []string) {
- numValues := strconv.Itoa(len(values))
- debug("<--", numValues)
- fmt.Fprintln(w, numValues)
- for i, val := range values {
- // Only print debug message for the first 10 items
- if i <= 10 {
- var msg string
- if i < 10 {
- msg = val
- } else if i == 10 {
- msg = "[...]"
- }
- debug("<--", msg)
- }
-
- fmt.Fprintln(w, val)
- }
-}
diff --git a/gui/tcl/choose-task.tcl b/gui/tcl/choose-task.tcl
deleted file mode 100644
index 74f92e2..0000000
--- a/gui/tcl/choose-task.tcl
+++ /dev/null
@@ -1,41 +0,0 @@
-package require Tk
-
-wm title . "Create or Open?"
-
-set OS [lindex $tcl_platform(os) 0]
-if {$OS == "Windows"} {
- ttk::style theme use vista
-} elseif {$OS == "Darwin"} {
- ttk::style theme use aqua
-} else {
- ttk::style theme use clam
-}
-
-set types {
- {{WebMaker2000 Files} {.wbmkr2k}}
-}
-
-ttk::frame .c -padding "10"
-ttk::label .c.label -text {Would you like to create a new blog, or open an existing one?}
-ttk::button .c.createBtn -text "Create..." -padding 5 -command {
- #set filename [tk_getSaveFile -title "Create" -filetypes $types]
- set filename [tk_chooseDirectory]
- if {$filename != ""} {
- puts "create ${filename}"
- exit
- }
-}
-ttk::button .c.openBtn -text "Open..." -padding 5 -command {
- set filename [tk_getOpenFile -filetypes $types]
- if {$filename != ""} {
- puts "open ${filename}"
- exit
- }
-}
-
-grid .c -column 0 -row 0
-grid .c.label -column 0 -row 0 -columnspan 2 -pady "0 10"
-grid .c.createBtn -column 0 -row 1 -padx 10
-grid .c.openBtn -column 1 -row 1 -padx 10
-
-tk::PlaceWindow . center
diff --git a/gui/tcl/main.tcl b/gui/tcl/main.tcl
deleted file mode 100644
index 7dbf5ea..0000000
--- a/gui/tcl/main.tcl
+++ /dev/null
@@ -1,225 +0,0 @@
-# Tcl on Windows has unfortunate defaults:
-# - cp1252 encoding, which will mangle utf-8 source code
-# - crlf linebreaks instead of unix-style lf
-# Let's be consistent cross-platform to avoid surprises:
-encoding system "utf-8"
-foreach p {stdin stdout stderr} {
- fconfigure $p -encoding "utf-8"
- fconfigure $p -translation lf
-}
-
-package require Tk
-
-wm title . "WebMaker2000"
-tk appname webmaker2000
-
-set OS [lindex $tcl_platform(os) 0]
-if {$OS == "Windows"} {
- ttk::style theme use vista
-} elseif {$OS == "Darwin"} {
- ttk::style theme use aqua
-} else {
- ttk::style theme use clam
-}
-
-wm protocol . WM_DELETE_WINDOW {
- exit 0
-}
-
-proc initialize {} {
- # By default this window is not focused and not even brought to
- # foreground on Windows. I suspect it's because tcl is exec'ed from Go.
- # The old "iconify, deiconify" trick no longer seems to work, so this time
- # I'm passing it to Go to call the winapi's SetForegroundWindow directly.
- if {$::tcl_platform(platform) == "windows"} {
- windows_forcefocus
- }
-}
-
-# Very simple line-based IPC system where Tcl client talks to Go server
-# via stdin/stdout
-proc ipc_write {method args} {
- puts "$method [llength $args]"
- foreach a $args {
- puts "$a"
- }
-}
-proc ipc_read {} {
- set results {}
- set numlines [gets stdin]
- for {set i 0} {$i < $numlines} {incr i} {
- lappend results [gets stdin]
- }
- return $results
-}
-proc ipc {method args} {
- ipc_write $method {*}$args
- return [ipc_read]
-}
-
-proc windows_forcefocus {} {
- # First call winapi's SetForegroundWindow()
- set handle [winfo id .]
- ipc "forcefocus" $handle
- # Then call force focus on tcl side
- focus -force .
- # We must do both in order to properly focus on main tk window.
- # Don't ask me why - that's just how it works.
- #
- # Alternatively we can try making Tcl our entrypoint instead of exec-ing
- # Tcl from Go. Maybe some other time.
-}
-
-proc loadicon {} {
- set iconblob [image create photo -file gorts.png]
- wm iconphoto . -default $iconblob
-}
-
-proc loadstartgg {} {
- set resp [ipc "getstartgg"]
- set ::startgg(token) [lindex $resp 0]
- set ::startgg(slug) [lindex $resp 1]
-}
-
-proc loadwebmsg {} {
- set resp [ipc "getwebport"]
- set webport [lindex $resp 0]
- set ::mainstatus "Point your OBS browser source to http://localhost:${webport}"
-}
-
-proc loadcountrycodes {} {
- set codes [ipc "getcountrycodes"]
- .n.m.players.p1country configure -values $codes
- .n.m.players.p2country configure -values $codes
-}
-
-proc loadscoreboard {} {
- set sb [ipc "getscoreboard"]
- set ::scoreboard(description) [lindex $sb 0]
- set ::scoreboard(subtitle) [lindex $sb 1]
- set ::scoreboard(p1name) [lindex $sb 2]
- set ::scoreboard(p1country) [lindex $sb 3]
- set ::scoreboard(p1score) [lindex $sb 4]
- set ::scoreboard(p1team) [lindex $sb 5]
- set ::scoreboard(p2name) [lindex $sb 6]
- set ::scoreboard(p2country) [lindex $sb 7]
- set ::scoreboard(p2score) [lindex $sb 8]
- set ::scoreboard(p2team) [lindex $sb 9]
- update_applied_scoreboard
-}
-
-proc applyscoreboard {} {
- set sb [ \
- ipc "applyscoreboard" \
- $::scoreboard(description) \
- $::scoreboard(subtitle) \
- $::scoreboard(p1name) \
- $::scoreboard(p1country) \
- $::scoreboard(p1score) \
- $::scoreboard(p1team) \
- $::scoreboard(p2name) \
- $::scoreboard(p2country) \
- $::scoreboard(p2score) \
- $::scoreboard(p2team) \
- ]
- update_applied_scoreboard
-}
-
-proc loadplayernames {} {
- set playernames [ipc "searchplayers" ""]
- .n.m.players.p1name configure -values $playernames
- .n.m.players.p2name configure -values $playernames
-}
-
-proc setupplayersuggestion {} {
- proc update_suggestions {_ key _} {
- if {!($key == "p1name" || $key == "p2name")} {
- return
- }
- set newvalue $::scoreboard($key)
- set widget .n.m.players.$key
- set matches [ipc "searchplayers" $newvalue]
- $widget configure -values $matches
-
- if {[llength matches] == 1 && [lindex $matches 0] == $newvalue} {
- set countryvar "p[string index $key 1]country"
- set country [lindex [ipc "getplayercountry" $newvalue] 0]
- set ::scoreboard($countryvar) $country
- }
- }
- trace add variable ::scoreboard write update_suggestions
-}
-
-proc fetchplayers {} {
- if {$::startgg(token) == "" || $::startgg(slug) == ""} {
- set ::startgg(msg) "Please enter token & slug first."
- return
- }
- .n.s.buttons.fetch configure -state disabled
- .n.s.buttons.clear configure -state disabled
- .n.s.token configure -state disabled
- .n.s.tournamentslug configure -state disabled
- .n state disabled
- set ::startgg(msg) "Fetching..."
- ipc_write "fetchplayers" $::startgg(token) $::startgg(slug)
-}
-
-proc fetchplayers__resp {} {
- set resp [ipc_read]
- set status [lindex $resp 0]
- set msg [lindex $resp 1]
-
- set ::startgg(msg) $msg
-
- if {$status == "ok"} {
- loadplayernames
- }
-
- .n.s.buttons.fetch configure -state normal
- .n.s.buttons.clear configure -state normal
- .n.s.token configure -state normal
- .n.s.tournamentslug configure -state normal
- .n state !disabled
-}
-
-proc clearstartgg {} {
- set ::startgg(token) ""
- set ::startgg(slug) ""
- set ::startgg(msg) ""
- ipc_write "clearstartgg"
-}
-
-proc discardscoreboard {} {
- foreach key [array names ::scoreboard] {
- set ::scoreboard($key) $::applied_scoreboard($key)
- }
- # Country is updated whenever player name is updated,
- # so make sure we set countries last.
- set ::scoreboard(p1country) $::applied_scoreboard(p1country)
- set ::scoreboard(p2country) $::applied_scoreboard(p2country)
-}
-
-proc update_applied_scoreboard {} {
- foreach key [array names ::scoreboard] {
- set ::applied_scoreboard($key) $::scoreboard($key)
- }
-}
-
-proc setupdiffcheck {} {
- # Define styling for "dirty"
- foreach x {TEntry TCombobox TSpinbox} {
- ttk::style configure "Dirty.$x" -fieldbackground #dffcde
- }
-
- trace add variable ::scoreboard write ::checkdiff
- trace add variable ::applied_scoreboard write ::checkdiff
-}
-
-proc checkdiff {_ key _} {
- set widget $::var_to_widget($key)
- if {$::scoreboard($key) == $::applied_scoreboard($key)} {
- $widget configure -style [winfo class $widget]
- } else {
- $widget configure -style "Dirty.[winfo class $widget]"
- }
-}
diff --git a/livereload/error.go b/livereload/error.go
index 5750618..30b3d42 100644
--- a/livereload/error.go
+++ b/livereload/error.go
@@ -7,7 +7,7 @@
"html/template"
"net/http"
- "go.imnhan.com/webmaker2000/errs"
+ "go.imnhan.com/s4g/errs"
)
//go:embed error.html
diff --git a/livereload/livereload.go b/livereload/livereload.go
index 4eb7615..e73eaeb 100644
--- a/livereload/livereload.go
+++ b/livereload/livereload.go
@@ -8,7 +8,7 @@
"strings"
"sync"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/writablefs"
)
const endpoint = "/_livereload"
diff --git a/livereload/livereload.html b/livereload/livereload.html
index 0333797..7f97f80 100644
--- a/livereload/livereload.html
+++ b/livereload/livereload.html
@@ -1,5 +1,5 @@
<!-- Start LiveReload script
-This <script> tag is injected by WebMaker2000's local server to force the
+This <script> tag is injected by s4g's local server to force the
browser tab to refresh whenever you make a change to your website folder.
It will not appear in your published website.
-->
diff --git a/main.go b/main.go
index b429160..82713a2 100644
--- a/main.go
+++ b/main.go
@@ -17,22 +17,21 @@
"sync"
"time"
- "go.imnhan.com/webmaker2000/djot"
- "go.imnhan.com/webmaker2000/errs"
- "go.imnhan.com/webmaker2000/gui"
- "go.imnhan.com/webmaker2000/livereload"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/djot"
+ "go.imnhan.com/s4g/errs"
+ "go.imnhan.com/s4g/livereload"
+ "go.imnhan.com/s4g/writablefs"
)
const DjotExt = ".dj"
-const SiteExt = ".wbmkr2k"
+const SiteExt = ".s4g"
const SiteFileName = "website" + SiteExt
const FeedPath = "feed.xml"
const RedirectsPath = "redirects.txt"
func main() {
invalidCommand := func() {
- fmt.Println("Usage: webfolder2000 new|serve|gui [...]")
+ fmt.Println("Usage: s4g new|serve [...]")
os.Exit(1)
}
@@ -40,7 +39,7 @@ func main() {
var cmd string
var args []string
if len(os.Args) < 2 {
- cmd = "gui"
+ cmd = "serve"
args = os.Args[1:]
} else {
cmd = os.Args[1]
@@ -63,8 +62,6 @@ func main() {
case "serve":
serveCmd.Parse(args)
handleServeCmd(serveFolder, servePort)
- case "gui":
- handleGuiCmd()
default:
invalidCommand()
}
@@ -78,22 +75,6 @@ func handleNewCmd(folder string) {
}
}
-func handleGuiCmd() {
- task, path, ok := gui.ChooseTask(gui.DefaultTclPath)
- if !ok {
- return
- }
-
- switch task {
- case gui.TaskOpen:
- fmt.Println(task, path)
- case gui.TaskCreate:
- fmt.Println(task, path)
- default:
- panic(task)
- }
-}
-
func handleServeCmd(folder, port string) {
djot.StartService()
fmt.Println("Started djot.js service")
diff --git a/manifest.go b/manifest.go
index 42c23f7..e8d2cab 100644
--- a/manifest.go
+++ b/manifest.go
@@ -6,12 +6,12 @@
"sort"
"strings"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/writablefs"
)
const ManifestPath = "manifest.txt"
-// Write list of files generated by webmaker2000
+// Write list of files generated by s4g
func WriteManifest(fsys writablefs.FS, files map[string]bool) {
lines := make([]string, 0, len(files))
for path := range files {
diff --git a/metadata.go b/metadata.go
index 0b5a3f4..ea68c76 100644
--- a/metadata.go
+++ b/metadata.go
@@ -11,8 +11,8 @@
"strings"
"time"
- "go.imnhan.com/webmaker2000/errs"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/errs"
+ "go.imnhan.com/s4g/writablefs"
)
type SiteMetadata struct {
diff --git a/redirects.go b/redirects.go
index a02e42c..603a3bb 100644
--- a/redirects.go
+++ b/redirects.go
@@ -9,8 +9,8 @@
"path/filepath"
"strings"
- "go.imnhan.com/webmaker2000/errs"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/errs"
+ "go.imnhan.com/s4g/writablefs"
)
// Returns list of generated files
diff --git a/theme/includes.tmpl b/theme/includes.tmpl
index 7f9fdcb..aa3130b 100644
--- a/theme/includes.tmpl
+++ b/theme/includes.tmpl
@@ -23,7 +23,7 @@
{{- if .Site.ShowFooter -}}
<footer>
© {{if eq .StartYear .Now.Year}}{{.StartYear}}{{else}}{{.StartYear}}–{{.Now.Year}}{{end}} {{.Site.AuthorName}}<br>
-Made with <a href="https://github.com/nhanb/webmaker2000">WebMaker2000</a>
+Made with <a href="https://github.com/nhanb/s4g">s4g</a>
</footer>
{{- end -}}
{{- end}}
diff --git a/watcher.go b/watcher.go
index e9e1e47..b7c3e2a 100644
--- a/watcher.go
+++ b/watcher.go
@@ -9,7 +9,7 @@
"time"
"github.com/fsnotify/fsnotify"
- "go.imnhan.com/webmaker2000/writablefs"
+ "go.imnhan.com/s4g/writablefs"
)
var WatchedExts = []string{DjotExt, SiteExt, ".tmpl"}