Documentation
¶
Overview ¶
Package concept reads concept.md, the editorial brief of a newsletter: who it is for, what it promises, how each issue is built, how often it comes, how long it is, how it sounds, and when to worry. Sections are fixed, the words are the author's, and decisions cite research by ID (V012 a voice, P003 a peer newsletter, E101 evidence). A few lines are machine-readable ("Every: weekly", "Words: 400-900", "Use: …") so lfr can hold every issue to the brief.
Index ¶
Constants ¶
const ( MinVoiceNotes = 8 MinAxes = 3 MinFormat = 2 MaxFormat = 8 MinPillars = 2 MaxPillars = 6 MinExamples = 3 MinUse = 2 MinAvoid = 2 )
Minimums the brief must meet.
const ( RuleFormat = "concept.format" RuleEvidence = "concept.evidence" RuleOpen = "concept.open" )
Rule IDs.
const File = "concept.md"
File is concept.md in the project root.
Variables ¶
var Sections = []Spec{ {"Diagnosis", true, "only when an existing newsletter is rebuilt: what works, what is generic, why readers stay or leave"}, {"Reader", false, "who subscribes, where they come from, what they want from each issue"}, {"Promise", false, "first line: one sentence of at most 160 characters for the signup page; then why it is credible"}, {"Voices", false, "coded observations from the voices, each citing its IDs"}, {"Axes", false, "table | Axis | Market | Readers | Chosen | where peers cluster and readers disagree"}, {"Format", false, "numbered parts of a typical issue: 1. <part>: <job>"}, {"Cadence", false, "Every: daily|weekly|biweekly|monthly|<n>d|<n>w, optional Day:, Time: HH:MM, Zone: <IANA>, and why it is sustainable"}, {"Length", false, "Words: <min>-<max> for the body, and why"}, {"Subject", false, "Max: <characters>, the style, and at least three Example: \"…\" lines"}, {"Voice", false, "tone in prose, Use: \"…\" phrases from readers and Avoid: \"…\" words"}, {"Pillars", false, "the recurring themes: - <name>: <what it covers>"}, {"Signup", false, "Headline:, Pitch: and Frequency: for the website: what the form promises and how often mail comes"}, {"Welcome", false, "what the welcome issue (welcome.md) says and why"}, {"Growth", false, "how readers find the newsletter without paid ads"}, {"Guardrails", false, "Unsubscribes: <n>% and Complaints: <n>% per issue that trigger a review, and what then"}, {"Changelog", true, "dated changes and the research batch or learning behind them"}, }
Sections are the sections of concept.md in order.
Functions ¶
func ParseEvery ¶
ParseEvery reads a cadence such as weekly or 3d.
Types ¶
type Cadence ¶
type Cadence struct {
Every time.Duration
Label string // as written
Day time.Weekday
HasDay bool
Hour, Minute int
HasTime bool
Zone *time.Location
}
Cadence is how often issues go out.
type Concept ¶
type Concept struct {
Title string
Sections map[string]*Section
Promise string
Cadence Cadence
MinWords int
MaxWords int
MaxSubject int
Examples []string
Use []string
Avoid []string
Pillars []string
Headline string
Pitch string
Frequency string // how often mail comes, in the readers' language, shown at signup
MaxUnsub float64 // percent
MaxComplaint float64 // percent
Open []Line
}
Concept is a parsed brief with its machine-readable fields.