Add support for marked-footnotes, tweak available color schemes, add boeuf bourguignon ETW post
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Garrett Mills 2024-07-07 00:16:04 -04:00
parent cb366b5aef
commit c52d8d15a1
7 changed files with 171 additions and 4 deletions

View File

@ -20,6 +20,7 @@
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"lib": "link:@extollo/lib:../extollo/lib", "lib": "link:@extollo/lib:../extollo/lib",
"marked": "^4.2.12", "marked": "^4.2.12",
"marked-footnote": "^1.2.2",
"ts-expose-internals": "^4.5.4", "ts-expose-internals": "^4.5.4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"ts-patch": "^2.0.1", "ts-patch": "^2.0.1",

View File

@ -41,6 +41,9 @@ dependencies:
marked: marked:
specifier: ^4.2.12 specifier: ^4.2.12
version: 4.2.12 version: 4.2.12
marked-footnote:
specifier: ^1.2.2
version: 1.2.2(marked@4.2.12)
ts-expose-internals: ts-expose-internals:
specifier: ^4.5.4 specifier: ^4.5.4
version: 4.8.4 version: 4.8.4
@ -2070,6 +2073,14 @@ packages:
dev: false dev: false
optional: true optional: true
/marked-footnote@1.2.2(marked@4.2.12):
resolution: {integrity: sha512-TFBEHwHLSSedub7P6XHHs+dMMOnDeNV5+kFDo4trU//gDd8iM57lg9jr9NGwDifPwLllHwKmFcRNp5uYvO2Fnw==}
peerDependencies:
marked: '>=7.0.0'
dependencies:
marked: 4.2.12
dev: false
/marked@4.2.12: /marked@4.2.12:
resolution: {integrity: sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==} resolution: {integrity: sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==}
engines: {node: '>= 12'} engines: {node: '>= 12'}

View File

@ -111,7 +111,7 @@ export default {
line3: '#ef4c3f', line3: '#ef4c3f',
highlightTheme: 'base16/chalk', highlightTheme: 'base16/chalk',
}, },
mashGreen: { /*mashGreen: {
displayName: "M*A*S*H Green", displayName: "M*A*S*H Green",
textVariant: 'light', textVariant: 'light',
background: '#202318', background: '#202318',
@ -127,7 +127,7 @@ export default {
line2: '#ecb653', line2: '#ecb653',
line3: '#71490b', line3: '#71490b',
highlightTheme: 'base16/atelier-estuary', highlightTheme: 'base16/atelier-estuary',
}, },*/
purpleAndWhite: { purpleAndWhite: {
displayName: "Purple & White", displayName: "Purple & White",
textVariant: 'light', textVariant: 'light',
@ -230,7 +230,7 @@ export default {
line3: '#111', line3: '#111',
highlightTheme: 'base16/atelier-cave-light', highlightTheme: 'base16/atelier-cave-light',
}, },
noir: { /*noir: {
displayName: "Noir", displayName: "Noir",
textVariant: 'light', textVariant: 'light',
background: '#2a333f', background: '#2a333f',
@ -246,6 +246,40 @@ export default {
line2: '#2d5060', line2: '#2d5060',
line3: '#5c3d51', line3: '#5c3d51',
highlightTheme: 'base16/atelier-estuary', highlightTheme: 'base16/atelier-estuary',
},*/
oceanBreeze: {
displayName: "Ocean Breeze",
textVariant: 'dark',
background: '#d3f6f3',
backgroundOffset: 'rgba(103, 191, 179, 0.2)',
backgroundOffset2: 'rgba(103, 191, 179, 0.4)',
hero: '#0a97b0',
font: '#0b3c5d',
fontMuted: '#68829e',
box: '#67bfb3',
link: 'var(--c-hero)',
noiseSize: '100px',
line1: '#5c97bc',
line2: '#0a97b0',
line3: '#0b3c5d',
highlightTheme: 'base16/atlantic-light',
},
sunnyMeadow: {
displayName: "Sunny Meadow",
textVariant: 'dark',
background: '#edf2f4',
backgroundOffset: 'rgba(237, 242, 244, 0.3)',
backgroundOffset2: 'rgba(237, 242, 244, 0.6)',
hero: '#8ac926',
font: '#2b2d42',
fontMuted: '#8d99ae',
box: '#d3d3d3',
link: 'var(--c-hero)',
noiseSize: '100px',
line1: '#a6a6a6',
line2: '#8ac926',
line3: '#2b2d42',
highlightTheme: 'base16/canary-light',
}, },
} as Record<string, ColorPalette>, } as Record<string, ColorPalette>,
} }

View File

@ -123,7 +123,6 @@ export class FoodBlog extends Controller {
} }
const postsByCountry = (await this.blog.getAllPosts()) const postsByCountry = (await this.blog.getAllPosts())
.reverse()
.groupBy(p => p.country) .groupBy(p => p.country)
const mapValues: any = {} const mapValues: any = {}

View File

@ -0,0 +1,116 @@
---
title: Bœuf Bourguignon
date: 2024-07-06 19:00:00
slug: FR-Boeuf-Bourguignon
country: FR
tags:
- stew
- beef
---
<img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-1.jpg">
This week's dish is another French classic, bœuf bourguignon[^1] or "beef in the Burgundy style." I was surprised to learn that this dish is relatively new, at least by French standards, only making its first appearance in the late 1800s. "Burgundy style" -- à la bourguignon -- refers to a dish cooked in wine and served with onions and mushrooms.
Bœuf bourguignon is the most well-known example of this -- cubed stew beef is braised in a mixture of wine and beef stock for hours until tender. It's served (predictably) with small stewed onions, sautéd mushrooms, and a sauce reduced from the braising liquid.
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-2.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-3.jpg"></div>
</div>
I used the bœuf bourguignon recipe from the "From Julia Child's Kitchen" cookbook. After her service as a literal spy[^2], Julia moved to Paris with her husband where she studied French cuisine. She eventually co-authored "Mastering the Art of French Cooking" (where this recipe originally appears) along with Simone Beck and Louisette Bertholle and is largely credited with introducing French cuisine to the United States.
The recipe is deceptively straightforward, and yet somehow managed to have me touch nearly every pan in my kitchen.
<img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-4.jpg">
<center>Here are the ingredients I used. Not pictured: flour, butter, salt.</center>
I used a pretty cheap pinot noir as the wine, and yes I cheated and used _Better Than Bouillon_ instead of tacking on an extra 4 hours to make my own stock.
The recipe starts out with [_lardons_](https://en.wikipedia.org/wiki/Lardon) -- small pieces of fatty pork. I had some bacon on hand, so I used that. As a red-blooded American, I found what followed to be offensive:[^3]
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-5.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-6.jpg"></div>
</div>
Yes, we start this recipe by _boiling_ bacon. Julia says this removes some of the fat and smoke flavor from the final dish. (Don't worry, though, we redeem ourselves by then browning the _lardons_.)
Then it was time to contend with the bœuf. I used a large piece of chuck, cut into 2 inch-by-2 inch pieces, which were then browned on all sides and added to my trusty Dutch oven.
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-7.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-8.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-9.jpg"></div>
</div>
After browning a couple carrots and half an onion, they -- along with a small tomato, tomato paste, a head of garlic, and some herbs -- are added to the Dutch oven. After deglazing the pan with some of the wine[^4], the juices, rest of the wine, and some beef stock were added to nearly cover everything.
<img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-23.jpg">
It then simmered in the oven at 325℉ for about 2 hours.
<img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-10.jpg">
<center>That oven rack is holding on for dear life.</center>
After a brief respite, it was time to contend with the onions. Since the onions are stewed whole, they need to be quite small. I used some lovely yellow summer onions I found at a farmers' market.
The onions were blanched and peeled, then simmered in beef stock until tender (in my case, about 40 minutes).
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-11.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-12.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-13.jpg"></div>
</div>
The mushrooms (I used some shiitake) were simply sautéd in a small amount of oil. Shortly after, the beef was done. I started checking it after 90 minutes (per Julia's recommendation) and pulled it when I could stick a fork in it easily, but without it falling apart. What emerged was absolutely gorgeous:
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-14.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-15.jpg"></div>
</div>
After removing the beef and friends,[^5] I reduced the broth slightly, then thickened it with Julia's prescribed _buerre manié_. I had never heard of this technique before. It's similar to what I would call a roux, but it's a mixture of flour and soft-but-not-melted butter. Whisking this into the broth thickened it into a lovely sauce.[^6]
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-16.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-17.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-18.jpg"></div>
</div>
With that, it was time to put it all together:
<img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-19.jpg">
<center>Julia says this can be served over rice or noodles, but we elected to eat it plain. Yes, I forgot the parsley.</center>
Predictably, the beef was delicious. It was rich and hearty and tender, but still chewy. The sauce was the perfect consistency and thanks to the wine was almost tangy, providing a bit of brightness to a heavy dish.
I have to admit that the onions fell a bit flat for me. I think as a result of being stewed separate from the beef, they were quite plain -- especially once you got past the outer layer or two. Dousing them in sauce certainly helped, but I think I needed to add a bit more chutzpa to the actual liquid while cooking them. They weren't _bad_, but they didn't really add much for me.
Still, the bœuf bourguignon was undoubtedly the best braised stew I've ever made. Perhaps this is sacrilege, but next time I'll probably omit the onions. Doing so has the side benefit of reducing the active time commitment of cooking the dish.
<div style="display: flex; flex-direction: row">
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-21.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-22.jpg"></div>
<div><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-24.jpg"></div>
</div>
<div style="display: flex; flex-direction: row">
<div style="width: 33%"><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-25.jpg"></div>
<div style="width: 33%"><img src="https://static.garrettmills.dev/assets/blog-images/food/fr-boeuf/optimized/boeuf-26.jpg"></div>
</div>
All images in this post were taken by me. I borrowed "From Julia Child's Kitchen" from the fantastic Indianapolis Public Library.
[^1]: ...two words I could not spell correctly on my own if my life depended on it. (Look ma', a shiny new footnotes system!)
[^2]: [Yes, really.](https://web.archive.org/web/20170307163049/https://www.cia.gov/news-information/featured-story-archive/2007-featured-story-archive/julia-child.html)
[^3]: /s
[^4]: ...a process which I'm sure smells better if one were to use a nicer bottle of wine. Other than the initial scent, though, I don't think the dish suffered for it.
[^5]: I separately fished out the herbs and garlic. The garlic was nice and soft, and I'm sure would be delicious on bread, e.g.
[^6]: You can see in the first picture that I didn't do a very good job of removing the fat from the pan before deglazing. I was able to skim some of it off, and after thickening the sauce, it wasn't noticeable.

View File

@ -50,6 +50,10 @@ block append style
background: rgba(0, 0, 0, 0); background: rgba(0, 0, 0, 0);
} }
.svgMap-tooltip-title {
color: #333;
}
.svgMap-map-wrapper .svgMap-country { .svgMap-map-wrapper .svgMap-country {
stroke: var(--c-hero); stroke: var(--c-hero);
} }

View File

@ -1,6 +1,7 @@
import * as fs from 'fs/promises' import * as fs from 'fs/promises'
import * as matter from 'gray-matter' import * as matter from 'gray-matter'
import * as marked from 'marked' import * as marked from 'marked'
import * as mf from 'marked-footnote'
import * as RSSFeed from 'feed' import * as RSSFeed from 'feed'
import { import {
appPath, appPath,
@ -109,6 +110,7 @@ export abstract class AbstractBlog<TFrontMatter extends BlogPostFrontMatter> {
return undefined return undefined
} }
marked.marked.use((mf as any)())
const render = marked.marked(post.markdown) const render = marked.marked(post.markdown)
this.postRenderCache[slug] = render this.postRenderCache[slug] = render
return render return render