This repository creates signage diagrams (via Penrose) for laundry bins.
The Penrose Substance file for cottons.substance
:
Category C
HasLabel(C, "COTTONS")
HasFrequency(C, "washed weekly or upon request")
AcceptedItem(C, "100% cotton; or 1-5% elasthane blends")
RejectedItem(C, "wool, or any synthetics or special-care items")
AutoLabel All
will generate a sign like this:
domain/laundry-signs.domain
: The Penrose Domain file declares theCategory
type and our relevant predicates:HasLabel
HasFrequency
AcceptedItem
RejectedItem
style/laundry-signs.style
: The Penrose Style file specifying how to draw signage for eachCategory
.substance/
: Five different Substance files, one per laundry category:cottons.substance
synthetics.substance
underpants.substance
wool.substance
caps.substance
- Upon every push to
main
that changes a.domain
,.style
, or.substance
file:- GitHub Actions (see
.github/workflows/compile-penrose.yml
) installs roger. - For each Substance file, it produces a PDF sign in the
output/
directory. - Then merges them all into one PDF,
laundry-signs.pdf
. - Publishes a GitHub Release with
laundry-signs.pdf
attached.
- GitHub Actions (see
Check the Releases tab for the generated PDF signage, or simply clone and run:
npm install -g @penrose/roger@4.0.0-alpha.5
mkdir -p output
# Example for cottons only:
npx roger trio \
substance/cottons.substance \
style/laundry-signs.style \
domain/laundry-signs.domain \
--out "output/cottons.svg"
This project uses Penrose to automatically layout signs for various laundry categories. Penrose is a system that takes three files—Domain, Substance, and Style—and renders a diagram by optimizing shape placements. Here’s what each file does:
-
Domain (*.domain): Declares the types and relationships for a given domain. In our case, we have:
Category
: a type of laundry category (e.g., COTTONS).- Predicates like
HasLabel
,HasFrequency
,AcceptedItem
, andRejectedItem
.
-
Substance (*.substance): Specifies which objects and relationships to draw. For each laundry bin sign, we create:
- A
Category
object (e.g.,C
for COTTONS). - Calls to predicates like
HasLabel(C, "COTTONS")
.
- A
-
Style (*.style): Tells Penrose how to display the objects declared in Substance. Here, we define:
- A full
canvas { width=500, height=200 }
block. - A big green rectangle for each
Category
. - Additional text shapes placed relative to that rectangle’s center (e.g., label text, frequency text, accepted/rejected items).
- A full
Penrose then optimizes the positions and sizes of these shapes, subject to your constraints (e.g., “the label text is centered on the rectangle”). When you run our GitHub Action or local build, Roger (the Penrose CLI) compiles the trio:
- Reads the
.domain
and.substance
(defining the logical objects). - Reads the
.style
instructions. - Outputs an SVG (ultimately converted into a PDF) with the shapes arranged automatically.
You can easily customize the final diagram by editing the .style
file. Some common tweaks include:
-
Change the background color of the main sign:
fillColor : #FFD700 -- example: turn the rectangle gold
-
Adjust the rectangle corners:
cornerRadius : 50 -- make extremely rounded corners
-
Reposition or resize:
center : (400, 300) -- you could shift the sign to another part of the canvas width : 600 -- or make it wider
-
Change fonts:
fontFamily : "serif" fontSize : "36px"
-
Add more text: For example, you could add a smaller “Notes” line underneath
freqText
, or define separate lines for specific items, etc.
By editing just the Style, you can change the entire look without altering the Domain or Substance structure. Penrose automatically re-optimizes everything to maintain a good layout.