heartwood every commit a ring

the garden learns who keeps good company and who does not

774f07dc by Isaac Bythewood · 2 days ago

added content/companions/early-fall.md
@@ -0,0 +1,22 @@---season: early-fallsection: who keeps good company---## good- garlic going in where the beans came out, the soil is sweet for it now- lettuce sown between the slow brassicas, gone before the cabbages fill in- crimson clover and rye in the empty beds, a green blanket that pays the soil back through winter- spring bulbs near the garlic, they wake at the same hour and ask for the same things- spinach beside the strawberry crowns, the cold they share keeps them both honest- a row of carrots beside the late onions, each one still hides the other from its own fly- chamomile and dill let to self-sow, they will come up early next year and bring the right insects with them## bad- never set garlic where the peas just left, what one called sweet the other calls bitter- onions and the new bean cover crop, keep them on opposite ends of the bed- a brassica patch is a brassica patch, do not plant another one in its footprint, the worms are still there- lettuce too close to the late broccoli, the broccoli will shadow it out before either is ready- fall potatoes where the tomatoes stood, the blight will follow them under the soil
added content/companions/early-spring.md
@@ -0,0 +1,23 @@---season: early-springsection: who keeps good company---## good- peas with carrots, the peas feed the soil and the carrots loosen it for what comes after- lettuce among the radishes, the radishes break the crust before the lettuce roots reach- spinach beside the strawberry rows, both like the cool and they share no quarrels- onions tucked between the carrots, each one hides the other from its own fly- potatoes and bush beans, the beans give back the nitrogen the potatoes pull out- chamomile by the young brassicas, an old wives' kindness that turns out to be true- marigolds at the edges of every bed, they earn their place from the first week to the last- borage near where the tomatoes will go, plant it now so the bees know the way## bad- onions and peas keep no peace, the alliums stunt the legumes and the legumes resent it- potatoes where the tomatoes lived last year, they share the same blight and the soil remembers- garlic too close to the peas will keep the vines small all season- fennel walks alone, plant it in a corner of its own or not at all- dill near the carrots, it crosses with them and confuses the seed
added content/companions/early-summer.md
@@ -0,0 +1,22 @@---season: early-summersection: who keeps good company---## good- borage still going strong by the tomatoes, the bees will not leave them alone now- nasturtium among the squash vines, a sacrifice the squash bug accepts in their place- basil thick around the peppers, the heat brings out the oils that keep the beetles off- marigold everywhere, the deeper the summer the more they earn their square of soil- dill allowed to flower near the cucumbers, it brings the wasps that take the cabbage worm- chives and parsley left to bloom, every flower is a contract with a pollinator- a row of buckwheat in any bed already finished, it feeds the bees and softens tired soil## bad- if anything new goes in, do not set it where the kin grew last year, the soil holds the memory- keep the squash out of the potato bed, the vines tangle and the soil is tired from both- sunflowers pull water and shade hard, do not crowd the beans against the stems- a second tomato never thrives where the first one stands, they will only fight for what is left- mint loose in any bed, root it in a pot or it will own the ground by autumn
added content/companions/late-fall.md
@@ -0,0 +1,20 @@---season: late-fallsection: who keeps good company---## good- a thick mulch of straw over the garlic, the cold cannot find it through the gold- compost spread where the heavy feeders worked all summer, the worms will turn it through the dark- a cover crop of rye sown thin into the bare beds, it will hold the soil through every wind that comes- daffodils tucked among the fruit trees, the deer pass them by and so leave the bark alone- a low hedge of garlic chives at the edge of the strawberry rows, they wake earlier than the slugs do- horseradish at the corner of the potato bed for next year, it asks for nothing and keeps the beetles off## bad- do not leave nightshade vines on the ground over winter, they carry the blight forward to spring- never compost the diseased leaves, burn them or send them out, the pile will not get hot enough now- do not mulch right up against the trunks of young trees, the voles winter in the warmth and chew through the bark- bean stalks left in the bed look like rest, but they hide the eggs that will hatch first thing
added content/companions/late-spring.md
@@ -0,0 +1,26 @@---season: late-springsection: who keeps good company---## good- basil under the tomatoes, old companions, it troubles the hornworm and they say it sweetens the fruit- carrots between the tomato stakes, they loosen the deep soil and ask for little light- borage near the tomatoes and the squash, the bees come for the flowers and stay for the fruit- corn, beans, and squash together, the three sisters, each one giving what the others need- nasturtium at the foot of the cucumbers, the aphids prefer it and leave the rest alone- marigold around the peppers, the nematodes turn back at the smell of the root- summer savory beside the bush beans, it troubles the bean beetle and asks for no room- chives or garlic in thin rows between the carrots and the lettuces, a quiet ward against aphids- parsley near the asparagus and the tomatoes, it brings the wasps that hunt the worms## bad- tomatoes and brassicas both eat heavy, planted close they starve each other- corn and tomatoes draw the same worm, keep them apart or share the loss- beans and onions, never together, the alliums turn the bean leaves pale and yellow- fennel near anything you mean to harvest, it sours the soil for company- cucumbers in the smell of sage, the cucumber will not thrive where the herb is strong- potatoes near the tomatoes invites blight to both- dill close to the tomatoes once they are setting fruit, the dill goes to seed and pulls them with it
added content/companions/midsummer.md
@@ -0,0 +1,22 @@---season: midsummersection: who keeps good company---## good- a second planting of bush beans beside the cucumbers, both will run together to the frost- a row of buckwheat where a bed has emptied, it brings the bees and feeds the soil for fall- borage left to flower fully, it is the bees' last reliable cup before the heat breaks- basil started again from cuttings, the second crop of the year is the strongest for pesto- marigolds sown thick where the brassicas will follow, they leave the ground cleaner than they found it- nasturtium tumbling between the squash hills, the bugs go to it and not the fruit- a few sunflowers at the north end of the bed, where the shade falls on no one important## bad- never put fall brassicas where the spring brassicas stood, the cabbage worms remember the place- do not return tomatoes to last year's tomato ground, the soil is asking for three years of rest- fennel anywhere near the new bean rows, the seedlings will sulk all the way to fall- garlic dropped in among the new peas, the peas will be small and bitter for it- another round of squash where the first one suffered, the bug eggs are already waiting
added content/companions/winter.md
@@ -0,0 +1,23 @@---season: wintersection: who keeps good company---## good- on paper now, set the tomatoes far from where they grew last summer, three years is the kindness they are owed- beside each tomato spot, a place for basil and a place for marigold, plan it now while the lines are clean- mark out a bed for the three sisters, corn at the center, beans up the stalks, squash spreading low between them- give the alliums a row of their own, the brassicas can sit beside them but the legumes must keep their distance- pencil in borage along the south edge, every garden is better for the bees it asks to come- group the heavy feeders together so the cover crop next fall has somewhere honest to do its work- draw the asparagus a permanent home, with parsley and tomatoes near, that bed will feed you for twenty years## bad- on the same paper, draw a line between the onions and the peas, do not let them meet again this year- do not pencil in tomatoes where the potatoes finished, the blight is patient and remembers the soil- never two seasons of brassicas in the same square, the soil keeps a grudge and the cabbage worms keep an address- fennel marked anywhere near another crop is a mistake, give it a corner of its own or leave it off the map- do not draw the strawberries next to the cabbages, the strawberries will quietly fail and you will not know why- a walnut tree casts more than shade, no garden bed should sit inside its drip line at all
modified content/manifest.json
@@ -56,6 +56,13 @@  { "path": "chores/early-fall.md", "season": "early-fall" },  { "path": "chores/late-fall.md", "season": "late-fall" },  { "path": "chores/winter.md", "season": "winter" },  { "path": "companions/early-spring.md", "season": "early-spring" },  { "path": "companions/late-spring.md", "season": "late-spring" },  { "path": "companions/early-summer.md", "season": "early-summer" },  { "path": "companions/midsummer.md", "season": "midsummer" },  { "path": "companions/early-fall.md", "season": "early-fall" },  { "path": "companions/late-fall.md", "season": "late-fall" },  { "path": "companions/winter.md", "season": "winter" },  { "path": "names/early-spring.md", "season": "early-spring" },  { "path": "names/late-spring.md", "season": "late-spring" },  { "path": "names/early-summer.md", "season": "early-summer" },
modified src/almanac.rs
@@ -3,7 +3,9 @@ use chrono_tz::Tz;use serde::Serialize;use crate::astro::{moon_phase, sky_data_lines};use crate::content::{parse_frontmatter, parse_list_items, ListItems, MoonTip, Season, SiteData};use crate::content::{    parse_frontmatter, parse_list_items, parse_named_lists, ListItems, MoonTip, Season, SiteData,};use crate::markdown::{render_block, render_inline};use crate::rng::{day_hash, pick_items, Mulberry32};
@@ -129,6 +131,15 @@ fn read_md_parts<'a>(path: &str, files: &'a std::collections::HashMap<String, St    Some(parse_list_items(&parsed.body))}fn read_named_lists(    path: &str,    files: &std::collections::HashMap<String, String>,) -> Option<Vec<(String, Vec<String>)>> {    let body = files.get(path)?;    let parsed = parse_frontmatter(body);    Some(parse_named_lists(&parsed.body))}#[derive(Debug)]struct Group {    label: &'static str,
@@ -219,6 +230,30 @@ fn section_garden(season: &Season, data: &SiteData, rng: &mut Mulberry32) -> Sec        }    }    if let Some(named) = read_named_lists(&format!("companions/{}.md", season.name), &data.files) {        // Map "good"/"bad" headings in the markdown to the labels rendered on        // the page. Other headings in the file are ignored.        let label_for = |name: &str| -> Option<&'static str> {            match name {                "good" => Some("good neighbors"),                "bad" => Some("bad neighbors"),                _ => None,            }        };        for (name, items) in &named {            let Some(label) = label_for(name) else { continue };            if items.is_empty() {                continue;            }            let n = items.len().min(3);            let picks = pick_items(items, n, rng);            groups.push(Group {                label,                items: picks.iter().map(|s| render_inline(s)).collect(),            });        }    }    Section {        key: "garden",        title: "garden",
modified src/content.rs
@@ -75,6 +75,31 @@ pub fn parse_list_items(body: &str) -> ListItems {    ListItems { bullets, prose }}/// Parse a body that contains multiple named bullet lists, each introduced by/// a `## name` heading. Order is preserved so callers can render sections in/// the same sequence the file declared them.pub fn parse_named_lists(body: &str) -> Vec<(String, Vec<String>)> {    let mut sections: Vec<(String, Vec<String>)> = Vec::new();    let mut current: Option<(String, Vec<String>)> = None;    for line in body.split('\n') {        let trimmed = line.trim();        if let Some(rest) = trimmed.strip_prefix("## ") {            if let Some(prev) = current.take() {                sections.push(prev);            }            current = Some((rest.trim().to_string(), Vec::new()));        } else if let Some(rest) = trimmed.strip_prefix("- ") {            if let Some((_, items)) = current.as_mut() {                items.push(rest.to_string());            }        }    }    if let Some(prev) = current.take() {        sections.push(prev);    }    sections}#[derive(Debug, Clone)]pub struct Season {    pub name: String,