diff --git a/package.json b/package.json index 173162c..4c69cb2 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "gray-matter": "^4.0.3", "lib": "link:@extollo/lib:../extollo/lib", "marked": "^4.2.12", + "marked-footnote": "^1.2.2", "ts-expose-internals": "^4.5.4", "ts-node": "^10.9.2", "ts-patch": "^2.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee62d50..1610730 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ dependencies: marked: specifier: ^4.2.12 version: 4.2.12 + marked-footnote: + specifier: ^1.2.2 + version: 1.2.2(marked@4.2.12) ts-expose-internals: specifier: ^4.5.4 version: 4.8.4 @@ -2070,6 +2073,14 @@ packages: dev: false 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: resolution: {integrity: sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==} engines: {node: '>= 12'} diff --git a/src/app/configs/app.config.ts b/src/app/configs/app.config.ts index 0433560..614e68e 100644 --- a/src/app/configs/app.config.ts +++ b/src/app/configs/app.config.ts @@ -111,7 +111,7 @@ export default { line3: '#ef4c3f', highlightTheme: 'base16/chalk', }, - mashGreen: { + /*mashGreen: { displayName: "M*A*S*H Green", textVariant: 'light', background: '#202318', @@ -127,7 +127,7 @@ export default { line2: '#ecb653', line3: '#71490b', highlightTheme: 'base16/atelier-estuary', - }, + },*/ purpleAndWhite: { displayName: "Purple & White", textVariant: 'light', @@ -230,7 +230,7 @@ export default { line3: '#111', highlightTheme: 'base16/atelier-cave-light', }, - noir: { + /*noir: { displayName: "Noir", textVariant: 'light', background: '#2a333f', @@ -246,6 +246,40 @@ export default { line2: '#2d5060', line3: '#5c3d51', 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, } diff --git a/src/app/http/controllers/FoodBlog.controller.ts b/src/app/http/controllers/FoodBlog.controller.ts index 93edc7b..4cdf7a6 100644 --- a/src/app/http/controllers/FoodBlog.controller.ts +++ b/src/app/http/controllers/FoodBlog.controller.ts @@ -123,7 +123,6 @@ export class FoodBlog extends Controller { } const postsByCountry = (await this.blog.getAllPosts()) - .reverse() .groupBy(p => p.country) const mapValues: any = {} diff --git a/src/app/resources/food-blog/FR-Boeuf-Bourguignon.md b/src/app/resources/food-blog/FR-Boeuf-Bourguignon.md new file mode 100644 index 0000000..c252252 --- /dev/null +++ b/src/app/resources/food-blog/FR-Boeuf-Bourguignon.md @@ -0,0 +1,116 @@ +--- +title: Bœuf Bourguignon +date: 2024-07-06 19:00:00 +slug: FR-Boeuf-Bourguignon +country: FR +tags: + - stew + - beef +--- + + + +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. + +
+
+
+
+ +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. + + +
Here are the ingredients I used. Not pictured: flour, butter, salt.
+ +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] + +
+
+
+
+ +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. + +
+
+
+
+
+ +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. + + + +It then simmered in the oven at 325℉ for about 2 hours. + + +
That oven rack is holding on for dear life.
+ +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). + +
+
+
+
+
+ +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: + +
+
+
+
+ +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] + +
+
+
+
+
+ +With that, it was time to put it all together: + + +
Julia says this can be served over rice or noodles, but we elected to eat it plain. Yes, I forgot the parsley.
+ +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. + +
+
+
+
+
+ +
+
+
+
+ +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. diff --git a/src/app/resources/views/food/page.pug b/src/app/resources/views/food/page.pug index fdb6d77..db208cc 100644 --- a/src/app/resources/views/food/page.pug +++ b/src/app/resources/views/food/page.pug @@ -50,6 +50,10 @@ block append style background: rgba(0, 0, 0, 0); } + .svgMap-tooltip-title { + color: #333; + } + .svgMap-map-wrapper .svgMap-country { stroke: var(--c-hero); } diff --git a/src/app/services/blog/AbstractBlog.service.ts b/src/app/services/blog/AbstractBlog.service.ts index 4d18b57..40a06d5 100644 --- a/src/app/services/blog/AbstractBlog.service.ts +++ b/src/app/services/blog/AbstractBlog.service.ts @@ -1,6 +1,7 @@ import * as fs from 'fs/promises' import * as matter from 'gray-matter' import * as marked from 'marked' +import * as mf from 'marked-footnote' import * as RSSFeed from 'feed' import { appPath, @@ -109,6 +110,7 @@ export abstract class AbstractBlog { return undefined } + marked.marked.use((mf as any)()) const render = marked.marked(post.markdown) this.postRenderCache[slug] = render return render