Help us shape the future of Go! Take the 2026 Go Developer Survey

printable

package
v0.1.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package printable is the printable deliverable: a planner, tracker, game or puzzle pack written as one HTML template of fixed-size pages, rendered for every paper size and variant the concept names, checked page by page, and printed to PDFs a buyer prints at home or imports into a note app.

Index

Constants

View Source
const (
	ImageWidth  = 1500
	ImageHeight = 1125
	ImageScale  = 2
	// PageScale is the density page rasters are rendered at for the images.
	PageScale = 2
)

Listing images are 3000×2250 pixels (4:3), drawn at 1500×1125 CSS pixels and twice the density. The product sits in the central 900 CSS pixels, so Etsy's square and portrait thumbnail crops keep it whole.

View Source
const (
	Dir          = "deliverables/printable"
	ConceptFile  = Dir + "/concept.md"
	TemplateName = "printable.html.tmpl"
	TemplateFile = Dir + "/" + TemplateName
	StyleName    = "printable.css"
	ListingFile  = Dir + "/listing.md"
	DataDir      = "data"
)

The fixed layout under deliverables/printable.

View Source
const (
	RuleConfig   = "printable.config"
	RuleConcept  = "printable.concept"
	RulePages    = "printable.pages"
	RuleBuild    = "printable.build"
	RuleLayout   = "printable.layout"
	RuleDelivery = "printable.delivery"
	RuleListing  = "printable.listing"
	RuleChannels = "printable.channels"
)

Rule IDs.

View Source
const EtsyImages = deliver.EtsyImages

EtsyImages is how many listing images Etsy takes.

View Source
const Safe = 6.35

Safe is the margin printers may cut or skip, in millimetres: nothing that matters may reach into it.

Variables

View Source
var ContentColumns = []string{"Part", "Pages", "Job"}

ContentColumns are the columns of the Contents table.

View Source
var Roles = []string{"cover", "guide", "contents", "puzzle", "key", "cut", "certificate", "extra"}

Roles a page can carry in data-role.

View Source
var Sections = []concept.SectionSpec{
	{Name: "Buyer"}, {Name: "Promise"}, {Name: "Contents"}, {Name: "Editions"}, {Name: "Look"}, {Name: "Changelog", Optional: true},
}

Sections of the printable concept, in order.

View Source
var Sizes = map[string]Size{
	"letter":      {Key: "letter", Label: "US Letter", Width: 215.9, Height: 279.4},
	"a4":          {Key: "a4", Label: "A4", Width: 210, Height: 297},
	"a5":          {Key: "a5", Label: "A5", Width: 148, Height: 210},
	"half-letter": {Key: "half-letter", Label: "Half Letter", Width: 139.7, Height: 215.9},
	"tablet":      {Key: "tablet", Label: "Tablet 3:4", Width: 157.5, Height: 210, Digital: true},
}

Sizes are the page sizes lfm renders. tablet is 3:4, the shape of every e-ink tablet and the 13-inch iPad.

Functions

func Distribution

func Distribution(r Report, p Printed, day string) (map[string][]byte, []string, []diagnostic.Diagnostic)

Distribution assembles the shop packages: every PDF and listing image once, a ZIP per paper size only when Etsy's five files would not hold the PDFs, a guide per shop in stores/, and a README.

func DownloadPage

func DownloadPage(r Report, files []deliver.File) []byte

DownloadPage renders the unlisted page buyers land on after paying: one file per edition, or a note while the files wait for their first print.

func Facts

func Facts(r Report) []string

Facts are the product's numbers, taken from the build so the listing never promises more pages, sizes or links than the files hold.

func FileNote

func FileNote(r Report, e Edition) string

FileNote is the line under an edition's download button.

func Present

func Present(p project.Project) bool

Present reports whether the project has deliverables/printable.

func Rules

func Rules() []diagnostic.RuleInfo

Rules describes every printable rule for the catalog.

func SizeNames

func SizeNames() string

SizeNames lists the size keys for messages.

Types

type Axis

type Axis struct {
	Name   string
	Values []string
}

Axis is one way editions vary besides the paper size.

type Bingo

type Bingo struct {
	Cards []BingoCard
	Calls []string // every item, for the caller's list
	// FirstWin is the median number of calls until the first card completes a
	// line when all cards play, from simulated games.
	FirstWin int
}

Bingo is a set of bingo cards with what the host needs to know.

func NewBingo

func NewBingo(items []string, count, size int, free bool, seed int) (Bingo, error)

NewBingo deals count unique cards of size×size items (a free centre when free and size is odd), each item on about as many cards as any other.

type BingoCard

type BingoCard struct {
	N     int
	Cells [][]string
}

BingoCard is one numbered card; Cells holds rows, the free centre as "".

type Calendar

type Calendar struct {
	Start    time.Weekday // the first day of every week row
	Weekdays []Weekday    // the week's day names from Start
	Months   []Month
	Weeks    []Week // every week touching the range, in order
	Days     []Day  // every day of the range
}

Calendar is a run of months for planner pages, computed rather than typed: month lengths, leap years, weekdays and ISO week numbers come from the standard library. Every month, week and day has an ID to link to.

func NewCalendar

func NewCalendar(from, start string, months int, language string) (Calendar, error)

NewCalendar builds months from the first day of from (2027 or 2027-08) for the given number of months (12 by default), with weeks starting on start (monday or sunday) and names in language.

type Config

type Config struct {
	Path     string
	Offer    string
	Language string
	Shop     string // the seller's name on the cover and in the licence
	Version  string // printed in the guide, e.g. 2027.1
	Sell     string // page (default), shops or bundle
}

Config is deliverables.printable in lfm.json.

type Day

type Day struct {
	ID      string // d2027-01-05
	Date    time.Time
	Day     int
	Month   int
	Year    int
	Weekday Weekday
	Week    string // the ID of its week
	InRange bool
}

Day is one date. InRange is false for days a month grid shows from the neighbouring months.

func (Day) IsoDate

func (d Day) IsoDate() string

IsoDate is the date as 2027-01-05.

type Edition

type Edition struct {
	Key     string // a4-color-monday
	Label   string // A4 · color · monday
	Size    Size
	Options map[string]string // axis name, lowercased -> value
}

Edition is one rendering of the product: a size and one value per axis.

func (Edition) Is

func (e Edition) Is(v string) bool

Is reports whether any option of the edition has value v, for templates: {{if .Edition.Is "ink-saver"}}.

func (Edition) Option

func (e Edition) Option(axis string) string

Option returns the value of an axis: {{.Edition.Option "Start"}}.

type Image

type Image = deliver.Image

Image is one listing image.

type ImagePlan

type ImagePlan struct {
	Name string
	Doc  []byte
}

ImagePlan is one listing image: its document and the page rasters it shows.

type Maze

type Maze struct {
	Width, Height int
	Right, Bottom [][]bool
	Path          [][2]int // the solution from the top-left to the bottom-right cell
}

Maze is a perfect maze: every cell reachable by exactly one path. Walls are kept per cell: right and bottom.

func NewMaze

func NewMaze(width, height, seed int) (Maze, error)

NewMaze carves a maze by a randomized depth-first walk.

func (Maze) SVG

func (m Maze) SVG(cell int, solved bool) template.HTML

SVG draws the maze at cell px per cell, with the solution when solved.

type Month

type Month struct {
	ID          string // m2027-01
	Year, Num   int
	Name, Short string
	Rows        []Week // the grid: weeks from the one holding the 1st to the one holding the last day
	Days        []Day
}

Month is one month with its calendar grid.

type Page

type Page struct {
	N        int
	Part     string
	Role     string
	IDs      []string
	Links    []string // internal targets, without "#"
	External []string
	Images   []string // as written in src
}

Page is one rendered page as the checks see it.

type Part

type Part struct {
	Name  string
	Pages int
	Job   string
	Line  int
}

Part is one row of Contents: a group of pages with one job.

type Placement

type Placement struct {
	Word           string
	Row, Col       int
	DRow, DCol     int
	Cells          [][2]int
	ReadsBackwards bool
}

Placement is where a word lies: its first letter and direction.

type Plan

type Plan struct {
	Name     string
	Buyer    string
	Promise  string
	Parts    []Part
	Sizes    []string // paper size keys, in order
	Axes     []Axis   // variant axes beside the size, such as Ink: color, ink-saver
	Body     string   // font stacks and accent of the Look
	Headings string
	Accent   string
	Lines    map[string]int // section name -> line, for findings
}

Plan is the parsed concept.

func (Plan) Editions

func (p Plan) Editions() []Edition

Editions multiplies the sizes by every axis.

type Printed

type Printed struct {
	PDFs    map[string][]byte // edition key -> PDF
	Images  []Image
	Pending bool // some prints wait for the next release
}

Printed is what the release printed for the printable: a PDF per edition and the listing images, in their order.

type Rendered

type Rendered struct {
	Edition Edition
	Doc     []byte
	Pages   []Page
	Links   int // internal links, the hyperlink count buyers are told
	Stray   int // elements outside a page section
}

Rendered is one edition rendered to its print document.

type Report

type Report struct {
	Config      Config
	Plan        Plan
	Summary     Summary
	Diagnostics []diagnostic.Diagnostic
	Editions    []Rendered
	Assets      map[string][]byte // flat name -> bytes, for printing
	Listing     deliver.ShopListing
	Buildable   bool // every edition rendered without errors
}

Report is the checked printable.

func Check

func Check(p project.Project, cfg Config, configured bool, offers map[string]*deliver.Price, site string) Report

Check reads deliverables/printable. configured tells whether lfm.json has deliverables.printable; site is the page URL the download path hangs off; offers are the page's offers by key.

func (Report) FileName

func (r Report) FileName(e Edition) string

FileName is the PDF name of an edition.

func (Report) Images

func (r Report) Images() []ImagePlan

Images plans the listing images in the order stores show them: the cover alone, everything included, each part, the sizes.

func (Report) Shots

func (r Report) Shots() []Shot

Shots lists the pages the listing images show: the cover, then the first and second page of every part.

func (Report) SizeCovers

func (r Report) SizeCovers() []Rendered

SizeCovers returns the first edition of every paper size, whose cover the sizes image shows as cover-<size>.png.

func (Report) Slug

func (r Report) Slug() string

Slug is the file name stem of the product.

type Shot

type Shot struct {
	Page int    // 1-based
	Name string // the asset name the image documents use, page-3.png
}

Shot asks for one page raster of the first edition.

type Size

type Size struct {
	Key, Label    string
	Width, Height float64
	Digital       bool // for note apps on tablets and e-ink, not for paper
}

Size is a page size in millimetres.

type Sudoku

type Sudoku struct {
	Puzzle   [9][9]int // 0 for an empty cell
	Solution [9][9]int
	Clues    int
}

Sudoku is a 9×9 puzzle with exactly one solution.

func NewSudoku

func NewSudoku(difficulty string, seed int) (Sudoku, error)

NewSudoku fills a grid and removes givens while the solution stays unique.

type Summary

type Summary struct {
	Name     string   `json:"name,omitempty"`
	Concept  bool     `json:"concept"`
	Template bool     `json:"template"`
	Editions []string `json:"editions,omitempty"`
	Pages    int      `json:"pages"` // per edition, as the first one renders
	Links    int      `json:"links"`
	Cut      int      `json:"cut"` // pages to cut out (data-role="cut")
	URL      string   `json:"url,omitempty"`
	Files    []string `json:"files,omitempty"`
	Pending  bool     `json:"pending"` // the PDFs print with --release
	Listing  bool     `json:"listing"`
	Channels []string `json:"channels,omitempty"`
	Images   int      `json:"images"` // listing images rendered
	Layout   string   `json:"layout,omitempty"`
	Sell     string   `json:"sell"` // page, shops or bundle
}

Summary is what the report and --json show about the printable.

type View

type View struct {
	Edition  Edition
	Name     string
	Promise  string
	Parts    []Part
	Language string
	Shop     string
	Version  string
	Data     map[string]any // data/<name>.json as .Data.<name>
}

View is what printable.html.tmpl sees for one edition.

type Week

type Week struct {
	ID     string // w2027-05: ISO year and week of the week's Thursday
	Number int    // ISO week number (KW)
	Year   int    // ISO year
	Days   []Day
}

Week is seven days from the calendar's start day.

type Weekday

type Weekday struct{ Name, Short string }

Weekday is a day name in the calendar's language.

type WordSearch

type WordSearch struct {
	Grid  [][]string
	Words []string // as listed for the solver, in the order given
	Found []Placement
}

WordSearch is a letter grid hiding every word exactly once.

func NewWordSearch

func NewWordSearch(words []string, size int, difficulty, language string, seed int) (WordSearch, error)

NewWordSearch hides words in a size×size grid. Letters are uppercased and, for German, umlauts and ß spelled out as puzzle books do; the filler draws from the language's letters and never spells a listed word a second time.

func (WordSearch) Hit

func (ws WordSearch) Hit(row, col int) bool

Hit reports whether the cell at row and col belongs to a hidden word, for drawing the answer key: {{if $ws.Hit $r $c}}.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL