Profpatsch/users/Profpatsch/blocks
- static/ 27.5 KiB · 2 files
- .gitignore 249 B
- asset.go 4.2 KiB
- blocks.1 5.5 KiB
- blocks.service 913 B
- default.nix 3.1 KiB
- exif.go 5.7 KiB
- exif_test.go 4.6 KiB
- go.mod 829 B
- image.go 6.0 KiB
- image_test.go 5.4 KiB
- main.go 2.6 KiB
- model.go 14.8 KiB
- model_test.go 8.3 KiB
- page.go 12.2 KiB
- render.go 7.9 KiB
- render_test.go 7.1 KiB
- schema.go 7.0 KiB
- serve.go 12.5 KiB
- stl.go 8.0 KiB
- stl_test.go 6.4 KiB
- upload.go 5.0 KiB
- upload_test.go 5.2 KiB
blocks(1)
NAME
blocks - block-based authoring for blog posts, stored in SQLite
SYNOPSIS
blocks
serve
-db path
[-addr host:port]
blocks
render
-db path
-slug slug
[-asset-prefix prefix]
DESCRIPTION
blocks is a local web application for writing blog posts as an ordered list of typed blocks, in the manner of a notebook: a paragraph of prose, a code listing, a photograph and a 3D model are each their own block, moved and edited independently rather than being buried in one long file.
Dragging a file onto the page uploads it and inserts a matching block immediately after whichever block it was dropped on, so illustrations land where they belong instead of being appended and then moved.
Everything lives in a single SQLite file: the posts, their blocks, the uploaded originals and every derived rendition. Nothing is written to the filesystem, so the database file is the complete authoring state and can be copied, versioned or backed up as one unit.
Block kinds
markdown
Markdown source, rendered with GitHub-flavoured extensions. Fenced code blocks inside it are syntax-highlighted like a dedicated code block.
code
A code listing with an explicit language, syntax-highlighted. An unrecognised language falls back to content analysis rather than being rejected.
image
A PNG, JPEG or WebP upload, with alt text and an optional caption.
stl
A 3D model in either STL flavour, shown in an interactive viewer.
Images
Uploads are accepted as PNG, JPEG or WebP and always served as WebP, at widths of 1600 and 800 pixels, offered to the browser through srcset. An image is never enlarged: a source narrower than a target width is stored at its own size.
The pristine upload is kept alongside the derivatives, so the widths and quality can be revised later without re-encoding an already lossy copy.
EXIF metadata is stripped, because it carries GPS coordinates, camera serial numbers and timestamps. Since that also discards the orientation tag a browser would otherwise honour, the rotation it describes is applied to the pixels first, and photographs taken on a phone come out upright.
Encoding is performed by
cwebp(1),
which the packaged binary carries on its
PATH.
Neither the Go standard library nor
golang.org/x/image
can write WebP, and the pure-Go encoders are lossless-only, which for
photographs yields files larger than the JPEG they came from.
3D models
Both the binary and ASCII STL formats are read. The file is parsed on the server into a packed vertex buffer with per-face normals, centred on the origin and scaled to fit a unit box; the browser fetches that buffer and hands it to WebGL unchanged, with no parsing and no third-party JavaScript.
Normals absent from the file, which many exporters omit, are recomputed from the triangle winding.
A download link for the original file sits beneath every viewer, as a sibling rather than as a fallback the viewer replaces, so the file stays reachable whether or not the viewer starts: without JavaScript, without WebGL, and equally when the model displays perfectly and the reader simply wants the STL.
Interacting with a model
A viewer is inert until the reader activates it, and shows a "Click to interact" button. While inert it consumes no input at all: the wheel scrolls the page and a finger swipes past it, exactly as they would over an image.
This matters because a model sits in the middle of a page of prose. An embed that grabs the wheel is a trap: the reader scrolls, the pointer crosses the model, and the page stops moving.
Activating it, by clicking the button or the model, takes over the wheel, touch gestures and the arrow keys:
Drag
Orbit the model.
Wheel
Zoom.
Arrow keys
Orbit, so the model is usable without a mouse.
+ and -
Zoom.
Esc
Release the viewer.
Clicking anywhere outside the viewer, or moving focus away, also releases it, so the reader never has to hunt for a control to get their scroll wheel back. A reminder of the controls and of Esc is shown for as long as the viewer is active.
COMMANDS
serve -db path [-addr host:port]
Run the editor and preview server. The database is created if it does not exist.
The default address is 127.0.0.1:8791. There is no authentication and no CSRF protection, which is a deliberate consequence of it being a single-user tool on the author's own machine; both would be required before binding it to a public interface.
Pages served:
/
the list of posts
/edit/{slug}
the block editor
/posts/{slug}
the rendered preview
render -db path -slug slug [-asset-prefix prefix]
Print a post's rendered HTML fragment to standard output.
Asset links are built from prefix (default /asset), which is the same seam the preview uses to point at blobs in the database and that a static export will use to point at published files.
FILES
path
The SQLite database given to -db, holding posts, blocks and assets. WAL mode is used, so .sqlite-wal and .sqlite-shm files appear alongside it while the server runs.
EXAMPLES
Start the editor on the default port:
$ blocks serve -db ~/posts.sqlite
Render a post to a file:
$ blocks render -db ~/posts.sqlite -slug my-post > my-post.html
SEE ALSO
cwebp(1), sqlite3(1)
AUTHORS
Profpatsch