Merge branch 'main' into 225-ebook-situation

This commit is contained in:
Ced
2023-12-14 09:01:14 +00:00
32 changed files with 1078 additions and 689 deletions

View File

@@ -1,9 +1,7 @@
name: Create and publish a Docker image name: Create and publish a Docker image
on: on:
push: workflow_call:
branches:
- main
env: env:
REGISTRY: ghcr.io REGISTRY: ghcr.io
@@ -26,20 +24,33 @@ jobs:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Figure out branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Determine docker image tag
shell: bash
id: determine_tag
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "tag=latest" >> $GITHUB_OUTPUT
else
echo "tag=${{ steps.extract_branch.outputs.branch }}" >> $GITHUB_OUTPUT
fi
- name: Extract metadata (tags, labels) for Docker - name: Extract metadata (tags, labels) for Docker
id: meta id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 uses: docker/metadata-action@v5
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: | # Buildx for caching
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} - uses: docker/setup-buildx-action@v3
- name: Build and push Docker image - name: Build and push Docker image
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 uses: docker/build-push-action@v5
with: with:
context: . context: .
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.determine_tag.outputs.tag }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -0,0 +1,100 @@
name: Release the book and website
on:
push:
branches:
- main
env:
IMAGE: ghcr.io/${{ github.repository }}:latest
jobs:
build-and-push-image:
uses: ./.github/workflows/docker-build-push.yml
release-book-website:
needs: build-and-push-image
runs-on: ubuntu-latest
steps:
- name: Set up git repository
uses: actions/checkout@v3
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make show_tools_version
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make printvars
- name: Bake the book
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make -j bake
- name: Release baked book to S3
uses: shallwefootball/s3-upload-action@master
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ secrets.AWS_BUCKET_BOOK }}
source_dir: book/release
destination_dir: release
- name: Upload book Artifacts
uses: actions/upload-artifact@v3
with:
name: books
path: |
book/book_serif/book.log
book/book_serif/book.pdf
book/book-epub/book.epub
- name: Bake the website
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make mrproper && make website
- name: Release baked website to S3
uses: shallwefootball/s3-upload-action@master
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ secrets.AWS_BUCKET_WEBSITE }}
source_dir: website/static_website_html
destination_dir: static_html_root
- name: Upload website Artifacts
uses: actions/upload-artifact@v3
with:
name: website
path: website/static_website_html
invalidate-book-website-cache:
needs: release-book-website
runs-on: ubuntu-latest
steps:
- name: Invalidate Cloudfront book cache
uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_BOOK }}
PATHS: "/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Invalidate Cloudfront website cache
uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_WEBSITE }}
PATHS: "/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

View File

@@ -1,51 +0,0 @@
name: Release the book
on:
push:
branches:
- main
jobs:
build_and_release:
runs-on: ubuntu-latest
steps:
- name: Set up git repository
uses: actions/checkout@v3
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make show_tools_version
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make printvars
- name: Bake the book
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make -j bake
- name: Release baked book to S3
uses: shallwefootball/s3-upload-action@master
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ secrets.AWS_BUCKET_BOOK }}
source_dir: book/release
destination_dir: release
- name: Invalidate Cloudfront book cache
uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_BOOK }}
PATHS: "/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

View File

@@ -1,51 +0,0 @@
name: Release the website
on:
push:
branches:
- main
jobs:
build_and_release:
runs-on: ubuntu-latest
steps:
- name: Set up git repository
uses: actions/checkout@v3
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make show_tools_version
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make printvars
- name: Bake the book
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make website
- name: Release baked website to S3
uses: shallwefootball/s3-upload-action@master
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY}}
aws_bucket: ${{ secrets.AWS_BUCKET_WEBSITE }}
source_dir: website/static_website_html
destination_dir: static_html_root
- name: Invalidate Cloudfront website cache
uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ secrets.CLOUDFRONT_DISTRIBUTION_WEBSITE }}
PATHS: "/*"
AWS_REGION: "us-east-1"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

63
.github/workflows/test-book-website.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Test building book and website
on:
pull_request:
env:
IMAGE: ghcr.io/${{ github.repository }}:${{ github.event.pull_request.head.ref }}
jobs:
build-and-push-image:
uses: ./.github/workflows/docker-build-push.yml
test-building-book-website:
needs: build-and-push-image
runs-on: ubuntu-latest
steps:
- name: Set up git repository
uses: actions/checkout@v3
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make show_tools_version
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make printvars
- name: Test baking the release versions
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make -j build_serif_pdf build_ebook
- name: Upload book Artifacts
uses: actions/upload-artifact@v3
with:
name: books
path: |
book/book_serif/book.log
book/book_serif/book.pdf
book/book-epub/book.epub
- name: Test building website
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make mrproper && make website
- name: Upload website Artifacts
uses: actions/upload-artifact@v3
with:
name: website
path: website/static_website_html

View File

@@ -1,32 +0,0 @@
name: Validate LaTeX Document
on: [ push, pull_request ]
jobs:
test_building_book:
runs-on: ubuntu-latest
steps:
- name: Set up git repository
uses: actions/checkout@v3
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make show_tools_version
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make printvars
- name: Test baking the release versions
uses: addnab/docker-run-action@v3
with:
image: ghcr.io/hendricius/the-sourdough-framework:latest
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make -j build_serif_pdf build_ebook

View File

@@ -1,4 +1,4 @@
FROM registry.gitlab.com/islandoftex/images/texlive FROM debian:trixie
LABEL "maintainer"="Hendrik Kleinwächter <hendrik.kleinwaechter@gmail.com>" LABEL "maintainer"="Hendrik Kleinwächter <hendrik.kleinwaechter@gmail.com>"
LABEL "repository"="https://github.com/hendricius/the-sourdough-framework" LABEL "repository"="https://github.com/hendricius/the-sourdough-framework"
@@ -6,7 +6,7 @@ LABEL "homepage"="https://github.com/hendricius/the-sourdough-framework"
LABEL org.opencontainers.image.source="https://github.com/hendricius/the-sourdough-framework" LABEL org.opencontainers.image.source="https://github.com/hendricius/the-sourdough-framework"
# Print release information if needed # Print release information if needed
# RUN cat /etc/*release* RUN cat /etc/*release*
# Install base depdendencies # Install base depdendencies
RUN apt-get update && \ RUN apt-get update && \
@@ -21,7 +21,43 @@ RUN apt-get update && \
ruby3.1 \ ruby3.1 \
ruby-dev \ ruby-dev \
imagemagick \ imagemagick \
build-essential rsync \
wget \
perl \
xzdec \
# dvisvgm dependencies
build-essential \
fonts-texgyre \
fontconfig \
libfontconfig1 \
libkpathsea-dev \
libptexenc-dev \
libsynctex-dev \
libx11-dev \
libxmu-dev \
libxaw7-dev \
libxt-dev \
libxft-dev \
libwoff-dev
# Install TeX
RUN apt-get update && \
apt-get install -y --no-install-recommends \
texlive-full \
texlive-luatex
# Compile latest dvisvgm
RUN wget https://github.com/mgieseki/dvisvgm/releases/download/3.1.2/dvisvgm-3.1.2.tar.gz && \
mv dvisvgm-3.1.2.tar.gz dvisvgm.tar.gz && \
tar -xzf dvisvgm.tar.gz && \
cd dvisvgm-* && \
./configure && \
make && \
make install
# Make sure everything is UTF-8
RUN echo "export LC_ALL=en_US.UTF-8" >> /root/.bashrc && \
echo "export LANG=en_US.UTF-8" >> /root/.bashrc
WORKDIR /root WORKDIR /root

View File

@@ -1,34 +1,28 @@
\chapter{Baking}%
\label{chapter:baking}
\begin{quoting} \begin{quoting}
Baking refers to the part of the process where you are loading Baking refers to the part of the process where you are loading your dough into
your dough into the oven. This is typically done after your the oven\footnote{While some breads like flatbreads could also be baked on the
dough has gone through the bulk fermentation and proofing stage. stove. This chapter focuses on the home oven.}. Baking is typically done after
your dough has gone through the bulk fermentation and proofing stage. This
chapter will review what happens to your dough during baking, as well as
several techniques used to improve the final result.
\end{quoting} \end{quoting}
\begin{flowchart}[!htb] \section{The process of baking}
\begin{center} Once temperature starts to rise, the dough will go through several stages as
\input{figures/fig-baking-process.tex} summarized in Table~\ref{tab:baking-stages}. As the dough heats up, the water
\caption[Different steaming methods]{A schematic visualization of the baking and acids in your dough start to evaporate. When baking a gluten based dough,
process using different sources of steam in a home oven.}% the bubbles in your dough start to expand. The dough starts to vertically
\label{fig:baking-process} rise, this is called oven spring. Your bread starts to build a crust of
\end{center} gel-like consistency, the crust is still extensible and can be stretched.
\end{flowchart}
Some other breads like flatbreads
could also be baked on the stove. This chapter focuses on the
home oven.
As the dough heats up, the water and acids
in your dough start to evaporate. When baking
a gluten based dough, the bubbles in your dough start to expand.
Your dough starts to vertically rise. This is called oven spring.
Your bread starts to build a crust of gel-like consistency. The crust is still
extensible and can be stretched.
\begin{table}[htp!] \begin{table}[htp!]
\begin{center} \begin{center}
\input{tables/table-baking-process-stages.tex} \input{tables/table-baking-process-stages.tex}
\caption[Stages of dough during baking]{The different stages that \caption[Stages of dough during baking]{The different stages that
your dough undergoes during the baking process.} your dough undergoes during the baking process.}%
\label{tab:baking-stages}
\end{center} \end{center}
\end{table} \end{table}
@@ -41,28 +35,32 @@ More research should be done here to validate or invalidate this
claim. claim.
At \qty{75}{\degreeCelsius} (\qty{167}{\degF}) the surface of your dough turns into a gel. It At \qty{75}{\degreeCelsius} (\qty{167}{\degF}) the surface of your dough turns into a gel. It
holds together nicely and is still extensible. This gel is essential holds together nicely but is still extensible. This gel is essential
for oven spring as it retains the gas of your dough very well. for oven spring as it retains the gas inside your dough.
At around \qty{100}{\degreeCelsius} (\qty{212}{\degF}) the water starts to evaporate out of your At around \qty{100}{\degreeCelsius} (\qty{212}{\degF}) the water starts to evaporate out of your
dough. If this weren't the case, your dough would taste soggy and dough. If this weren't the case, your dough would taste soggy and
doughy. The higher hydration your dough has, the more water your bread doughy. The higher hydration your dough has, the more water your bread
still contains after the bake. The crumb is going to taste a bit still contains after the bake, changing its consistency. As a result the
more moist. The consistency will be different. crumb is going to taste a bit more moist.
Another often undervalued step is the evaporation of acids. At Another often undervalued step is the evaporation of acids.
\qty{118}{\degreeCelsius} (\qty{244}{\degF}) the acetic acid in your dough starts to evaporate. At~\qty{118}{\degreeCelsius} (\qty{244}{\degF}) the acetic acid in your dough
Shortly after at \qty{122}{\degreeCelsius} (\qty{252}{\degF}) the lactic acid begins evaporating. starts to evaporate.
This is crucial to understand and opens a door to many interesting Shortly after at~\qty{122}{\degreeCelsius} (\qty{252}{\degF}) the lactic acid begins evaporating.
This is crucial to understand and it opens the door to many interesting
ways to influence your final bread's taste. As more and more water ways to influence your final bread's taste. As more and more water
begins to evaporate the acids in your dough become more concentrated. begins to evaporate the acids in your dough become more concentrated.
There is less water but in relation you have more acids. A shorter There is less water but in relation you have more acids, therefore a shorter
bake will therefore lead to a more tangy dough. The longer you bake the bread, bake will lead to a more tangy dough. The longer you bake the bread,
the more of the water evaporates, but also ultimately the acids will follow. the more of the water evaporates, but also ultimately the acids will follow.
They will be more concentrated. In absolute units, though, they The longer you bake, the less sour your bread is going to be. By controlling
will become less and less. The longer you bake, the less sour baking time you can influence which sourness level you would like to achieve.
your bread is going to be. By baking you can
influence which sourness level you would like to achieve. It would be a very interesting experiment to bake a bread at different exact
temperatures. How would a bread taste with only evaporated water but
full acidity? What if you were to just completely get rid of the acetic
acid? How would the taste change?
\begin{figure}[!htb] \begin{figure}[!htb]
\includegraphics[width=\textwidth]{baking-experiment-temperatures.png} \includegraphics[width=\textwidth]{baking-experiment-temperatures.png}
@@ -74,18 +72,14 @@ influence which sourness level you would like to achieve.
the surface temperature increases.} the surface temperature increases.}
\end{figure} \end{figure}
It would be a very interesting experiment to bake a bread at different exact As the temperature increases further the crust thickens. The Maillard reaction
temperatures. How would a bread taste with only evaporated water but kicks in, deforming proteins and starches. The outside of your dough starts to
full acidity? What if you were to just completely get rid of the acetic become browner and crisper, this process begins at
acid? How would the taste change? around~\qty{140}{\degreeCelsius} (\qty{284}{\degF})
As the temperature increases Once the temperature increases even more to around~\qty{170}{\degreeCelsius}
the crust thickens. The Maillard reaction kicks in, further deforming (\qty{338}{\degF}),
proteins and starches. The outside of your dough starts to become the caramelization process begins, the remaining sugars and the microbes which
browner and crisper. This process begins at around \qty{140}{\degreeCelsius} (\qty{284}{\degF})
Once the temperature increases even more to around \qty{170}{\degreeCelsius} (\qty{338}{\degF}),
the caramelization process begins. The remaining sugars the microbes
did not convert yet start to brown and darken. You can keep baking did not convert yet start to brown and darken. You can keep baking
for as long as you like to achieve the crust color that you for as long as you like to achieve the crust color that you
like\footnote{This really depends a lot on your personal preference. like\footnote{This really depends a lot on your personal preference.
@@ -95,66 +89,53 @@ heat your bread in the oven one more time to continue building a
darker crust.}. darker crust.}.
The best method to know that your dough is done is to take The best method to know that your dough is done is to take
the temperature of your dough. You can use a barbecue thermometer the temperature of your dough, you can use a barbecue thermometer
to measure it. Once the core temperature is at around \qty{92}{\degreeCelsius} (\qty{197}{\degF}), to measure it. Once the core temperature is at around~\qty{92}{\degreeCelsius}
(\qty{197}{\degF}),
you can stop the baking process. This is typically not done though you can stop the baking process. This is typically not done though
as the crust hasn't been built yet\footnote{The thermometer is as the crust hasn't been built yet\footnote{The thermometer is
especially important when using a large loaf pan. It is sometimes especially important when using a large loaf pan. It is sometimes
very hard to judge from the outside if the dough is done. I~failed very hard to judge from the outside if the dough is done. I~failed
many times and ended up having a semi baked dough.}. many times and ended up having a semi baked dough.}.
Once your dough has finished baking, it is ready to eat. Your Once your dough has finished baking, it is ready to eat: your
dough has turned into a bread. At this dough has turned into a bread. At this
point, your bread is sterile as the temperature was too hot for point, your bread is sterile as the temperature was too hot for
for the microorganisms to survive\footnote{I~wonder though for the microorganisms to survive\footnote{I~wonder though
if a starter culture could be grown again from a slice of bread. if a starter culture could be grown again from a slice of bread.
Under heat stress the microorganisms begin sporulating. Maybe Under heat stress the microorganisms begin sporulating. Maybe
some of the spores survive the baking process and could be reactivated some of the spores survive the baking process and could be reactivated
later? If this worked, you could use any store bought sourdough later? If this works, you could use any store bought sourdough
bread as a source for a new starter.}. bread as a source for a new starter.}.
\section{The role of steam} \section{The role of steam}
\begin{figure}[!htb]
\includegraphics[width=\textwidth]{oven-example}
\caption[Home oven baking example to maximize steam]{My default home oven setup. The tray of rocks
and tray on top of the rolls greatly improve the steaming capabilities. This way the bread can
rise more during the initial stage of the baking process.}
\end{figure}
Steam is essential when baking as it helps to counter premature Steam is essential when baking as it helps to counter premature
crust building. During the first stage of the bake, the dough crust building. During the first stage of the bake, the dough
increases in size. The water in your dough evaporates and pushes increases in size as the water in your dough evaporates and pushes
the whole dough upwards. the whole dough upwards.
\begin{figure}[!htb]
\includegraphics[width=\textwidth]{baking-process-steam.jpg}
\caption[Steam building with inverted tray]{How steam builds in your oven
using the later described inverted tray method.}%
\label{flc:inverted-tray}
\end{figure}
Normally, under high heat a crust would form. Just like Normally, under high heat a crust would form. Just like
if you were to bake vegetables in your home oven, at some point if you were to bake vegetables in your home oven, at some point
they become darker and crisper. This is the same thing that they become darker and crisper. This is the same thing that
happens with your dough. You want to delay this process happens with your dough, and you want to delay this process
as long as possible until your dough no longer expands. as long as possible until your dough no longer expands.
Expansion stops when most of the microbes have died and Expansion stops when most of the microbes have died and
the evaporating water no longer stays inside the alveoli. the evaporating water no longer stays inside the alveoli.
The stronger the gluten network, the more gas can be retained The stronger the gluten network, the more gas can be retained
during the baking process. This gluten network at some point during the baking process. This gluten network at some point
loses its ability to contain gas as the temperature heats loses its ability to contain gas as the temperature heats
up. The dough stops increasing in size. The steam plays up. The dough stops increasing in size. The steam plays
an important role as it condenses and evaporates on top an important role as it condenses and evaporates on top
of your dough. The surface temperature is rapidly increasing of your dough. The surface temperature is rapidly increasing
to around \qty{75}{\degreeCelsius} (\qty{160}{\degF}). At this temperature the gel starts to around~\qty{75}{\degreeCelsius} (\qty{160}{\degF}). At this temperature the
to build. This gel is still extensible and allows expansion. gel starts to build, and is still extensible and allows expansion.
Without the steam, the dough would never enter the gel stage, Without the steam, the dough would never enter the gel stage,
but instead directly go to the Maillard reaction zone. You but instead directly go to the Maillard reaction zone. You
want your dough to stay in this gel stage as long as possible want your dough to stay in this gel stage as long as possible
to achieve maximum expansion\footnote{You can remove your to achieve maximum expansion\footnote{You can remove your
dough from the oven after 5~minutes to see the gel. You will notice dough from the oven after 5~minutes to see the gel. You will notice
that it holds the dough's structure. It has a very interesting consistency.}. that it holds the dough's structure and it has a very interesting consistency.}.
\begin{figure}[!htb] \begin{figure}[!htb]
\includegraphics[width=\textwidth]{baking-process-stage-2.jpg} \includegraphics[width=\textwidth]{baking-process-stage-2.jpg}
@@ -165,10 +146,9 @@ that it holds the dough's structure. It has a very interesting consistency.}.
When not steaming enough, you will notice that the scoring When not steaming enough, you will notice that the scoring
incisions do not properly open up during the bake. They stay incisions do not properly open up during the bake. They stay
closed as the dough is unable to push through the crust. closed as the dough is unable to push through the crust.
Another common sign, as you can see in Figure~\ref{fig:too-little-steam} is
Another common sign is that you have larger pockets that you have larger pockets of air towards the crust of your dough. As the
of air towards the crust of your dough. As the dough increases dough increases vertically, expansion is halted by the crust. The pockets
vertically, expansion is halted by the crust. The pockets
of air converge into larger pockets as the pressure increases. of air converge into larger pockets as the pressure increases.
This can also happen when you are baking at too high a temperature. This can also happen when you are baking at too high a temperature.
@@ -185,10 +165,35 @@ way.
\caption[Bread baked too hot]{A submission by Karomizu showing a bread that \caption[Bread baked too hot]{A submission by Karomizu showing a bread that
has been baked at too high a temperature or with too little steam. Note has been baked at too high a temperature or with too little steam. Note
the large pockets of air towards the crust. They are a typical the large pockets of air towards the crust. They are a typical
indicator.} indicator.}%
\label{fig:too-little-steam}
\end{figure} \end{figure}
\section{Dutch ovens} \section{Building up steam}
\begin{flowchart}[!htb]
\begin{center}
\input{figures/fig-baking-process.tex}
\caption[Different steaming methods]{A schematic visualization of the baking
process using different sources of steam in a home oven.}%
\label{fig:baking-process}
\end{center}
\end{flowchart}
\begin{figure}[!htb]
\includegraphics[width=\textwidth]{oven-example}
\caption[Home oven baking example to maximize steam]{My default home oven setup. The tray of rocks
and tray on top of the rolls greatly improve the steaming capabilities. This way the bread can
rise more during the initial stage of the baking process.}
\end{figure}
\begin{figure}[!htb]
\includegraphics[width=\textwidth]{baking-process-steam.jpg}
\caption[Steam building with inverted tray]{How steam builds in your oven
using the later described inverted tray method.}%
\label{flc:inverted-tray}
\end{figure}
\subsection{Dutch ovens}
\begin{figure}[!htb] \begin{figure}[!htb]
\includegraphics[width=\textwidth]{dutch-oven-example} \includegraphics[width=\textwidth]{dutch-oven-example}
@@ -261,10 +266,10 @@ top of other tools can be quite a hefty investment. For
this reason, I advocate the inverted tray method visualized this reason, I advocate the inverted tray method visualized
in the next section. In case you do not own an oven consider trying in the next section. In case you do not own an oven consider trying
the simple flatbread recipe which is baked in a pan. Please the simple flatbread recipe which is baked in a pan. Please
refer to Section~\ref{section:flat-bread-recipe} for more details. refer to Section~\ref{subsec:flat-bread-recipe} for more details.
\section{Inverted tray method} \subsection{Inverted tray method}
The inverted tray method simulates a Dutch oven. The inverted tray method simulates a Dutch oven.
By placing another tray on top of your dough, the steam By placing another tray on top of your dough, the steam

View File

@@ -79,5 +79,6 @@ a sample of your brew and checking the color.
\listoftables \listoftables
\listoffigures \listoffigures
} }
\printbibliography
\end{document} \end{document}

View File

@@ -1,11 +1,23 @@
\chapter{Bread types}%
\label{ch:bread-types}
\begin{quoting} \begin{quoting}
In this chapter you will learn about different bread types and their In this chapter you will learn about different bread types and their
advantages and disadvantages. At the end of this chapter you can find a very advantages and disadvantages. You can also find very simple recipes for
simple flatbread recipe. This is probably the most accessible, least effort flatbread and pan loaf. The former is probably the most accessible, least
type of bread you can make. If you are a busy person and/or don't have an effort type of bread you can make, while the latter is a little more involved.
oven, this might be exactly the type of bread you should consider. Free standing bread has its own chapter, due to its increased complexity.
\end{quoting} \end{quoting}
\section{Introduction}%
\label{sec:intro}
In this section we classify bread by its baking techniques. The appearance and
taste will of course be different, but you can get excellent bread with each
of them. Some breads will require investment and technique, as depicted in
Table~\ref{tab:bread-types-comparison}. Flatbread is probably the most
accessible, least effort type of bread you can make. If you are a busy person
and/or dont have an oven, this might be exactly the type of bread you should
consider.
\begin{table}[!htb] \begin{table}[!htb]
\begin{center} \begin{center}
\input{tables/table-overview-bread-types.tex} \input{tables/table-overview-bread-types.tex}
@@ -15,7 +27,8 @@ oven, this might be exactly the type of bread you should consider.
\end{center} \end{center}
\end{table} \end{table}
\section{Flatbread} \section{Flatbread}%
\label{sec:flatbread}
Flatbread is probably the simplest sourdough bread to make. Flatbread is probably the simplest sourdough bread to make.
To make a flatbread no oven is required; all you need is a stove. To make a flatbread no oven is required; all you need is a stove.
@@ -24,7 +37,7 @@ To make a flatbread no oven is required; all you need is a stove.
\includegraphics[width=\textwidth]{flat-breads-selection} \includegraphics[width=\textwidth]{flat-breads-selection}
\caption[Flatbread selection with different flours]{An assorted selection of \caption[Flatbread selection with different flours]{An assorted selection of
different flatbreads made with sourdough. From left to right: different flatbreads made with sourdough. From left to right:
Wheat tortilla, rye, spelt and corn.}% Wheat~tortilla, rye, spelt and corn.}%
\end{figure} \end{figure}
This type of bread is super simple to make as you can skip This type of bread is super simple to make as you can skip
@@ -33,19 +46,258 @@ can be made with all kinds of flours. You can even use
flour without gluten, such as corn or rice flour, to make the flour without gluten, such as corn or rice flour, to make the
dough. To make the flatbread a little more fluffy, you dough. To make the flatbread a little more fluffy, you
can use a little bit of wheat flour. The developing gluten can use a little bit of wheat flour. The developing gluten
will trap the gasses. During baking, these gasses will will trap the gases. During baking, these gases will
inflate the dough. inflate the dough.
Another trick to improve the texture of the flatbread is to Another trick to improve the texture of the flatbread is to
make a very wet dough. A lot of the water will evaporate make a very wet dough. A lot of the water will evaporate
during the baking process and thus make the bread fluffier. during the baking process and thus make the bread fluffier.
If your water content is very high, it will produce a If your water content is very high, it will produce a
pancake-like consistency. pancake-like consistency, as you can see in
Table~\ref{tab:flat-bread-ingredients}
Refer to Section~\ref{section:flat-bread-recipe}~``\nameref{section:flat-bread-recipe}'' \begin{table}[!htb]
to see a full recipe including the process of making such a flatbread. \begin{center}
\input{tables/table-flat-bread-pancake-recipe.tex}
\caption[Flatbread recipe]{Flatbread or pancake recipe for 1 person.
Multiply the ingredients to increase portion size. Refer to the
Section~\ref{section:bakers-math}
``\nameref{section:bakers-math}'' to learn how to understand and
use the percentages properly.}%
\label{tab:flat-bread-ingredients}
\end{center}
\end{table}
For a full recipe including the process of making such a flatbread, refer to
Subsection~\ref{subsec:flat-bread-recipe}
\subsection{Flatbread framework}%
\label{subsec:flat-bread-framework}
As explained above, if you are just getting started, making a flatbread is the
easiest way to start making great bread at home. With just a
few steps, you can stop buying bread forever. This works with
any flour, including gluten-free options.
\begin{flowchart}[!htb]
\begin{center}
\input{figures/fig-process-flat-bread.tex}
\caption[The process to make a sourdough flatbread]{The process of making a flatbread is very
simple, requiring very little effort. This type of bread is especially
handy for busy bakers.}%
\label{fig:flat-bread-process}
\end{center}
\end{flowchart}
This is my go-to recipe that I~use to make bread whenever
I~have little time or when I~am abroad. You can choose
between two options:
%
\begin{enumerate}
\item A flatbread similar to a roti or naan bread
\item Sourdough pancakes.
\end{enumerate}
To get started prepare your sourdough starter. If it has not been used for a very
long time, consider giving it another feed. To do so, simply take \qty{1}{\gram} of your
existing sourdough starter and feed it with \qty{5}{\gram} of flour and \qty{5}{\gram} of water.
If you do this in the morning, your sourdough starter will be ready in the evening. The
warmer it is, the sooner it will be ready, consider
using warm water if it is very cold where you live.
\begin{figure}[htb!]
\begin{center}
\includegraphics[width=1.0\textwidth]{flat-bread-wheat}
\caption[Wheat flatbread]{A flatbread made with purely wheat flour. The
dough is drier at around \qty{60}{\percent} hydration. The drier dough
is a little harder to mix. As wheat contains more gluten, the dough
puffs up during the baking process.}
\end{center}
\end{figure}
This way you should have around \qty{11}{\gram} of sourdough ready in the evening. You will have
the perfect quantity to make a dough for one person. In case you want to make more
bread, simply multiply the quantities shown in
Table~\ref{tab:flat-bread-ingredients}.
Then in the evening simply mix the ingredients as shown in the table. Your dough
is going to be ready in the morning. It's typically ready after 6--12~hours. If
you use more sourdough starter it will be ready faster, conversely it will take
longer if you use less. Try to aim for a fermentation time of 8--12~hours as
by using your dough too soon, the flavor might not be as good. By using your
dough later it might become a little more sour. The best option is to
experiment and see what you personally like the most.
After mixing the ingredients together cover the container, this prevents the
dough from drying out and makes
sure no fruit flies get access. A transparent container will be helpful
when getting started. You can observe the dough more easily and see when
it is ready.
\begin{figure}[htb]
\begin{center}
\includegraphics[width=1.0\textwidth]{ethiopian-woman-checking-bread}
\caption[Ethiopian \emph{injera}]{An Ethiopian woman baking an \emph{injera}
made using teff flour. The image has been provided by Charliefleurene
via Wikipedia.}
\end{center}
\end{figure}
If you used the flatbread option with less water, look at the size increase
of your dough. It should have increased at least \qty{50}{\percent} in size.
Also look out for bubbles on the sides of your container.
When using the pancake recipe, look out for bubbles on the surface of your dough.
In both cases use your nose to check the scent of your dough. Depending
on your sourdough starter's microbiome your dough will have
dairy, fruity, alcoholic notes or vinegary, acetic notes. Relying
on the smell of your dough is the best way to judge whether your
dough is ready or not. Timings are not reliable as they
depend on your starter and the temperature. If your dough
is ready too soon, you can now move it directly to the fridge and bake
it at a later, more convenient time. The low temperature will halt the fermentation
process\footnote{There are some exceptions. In some rare cases your starter
might also work at lower temperatures. You might have cultivated microbes that work best at
low temperatures. Nevertheless, fermentation
is always slower the colder it gets. A fridge really helps to preserve the state
of your dough.}
and your dough will last for several days. The longer you wait, the more sour the
bread is going to be. The fridge is a great option in case you want to
take the dough with you when visiting friends. People are going
to love you for the freshly baked flatbreads or pancakes. If you dare,
you can also taste a little bit of your raw uncooked dough. It is likely
going to taste relatively sour. I~do this frequently to better evaluate the
state of my doughs.
\begin{figure}[!htb]
\begin{center}
\includegraphics[width=1.0\textwidth]{injera-pancake-texture.jpg}
\caption[Teff sourdough pancake]{A sourdough pancake made with teff flour.
The pockets come from evaporated water and \ch{CO2} created by the
microbes. The image has been provided by Łukasz Nowak via Wikipedia.}
\end{center}
\end{figure}
If you are feeling lazy or don't have time, you could also use older sourdough starter
to make the dough directly without any prior starter feedings. Your sourdough starter
is going to regrow inside your dough. Remember that the
final bread might be a bit more on the sour side as the balance of yeast to
bacteria could be off. In the Table~\ref{tab:flat-bread-ingredients}
I~recommended using around \qtyrange{5}{20}{\percent}
of sourdough starter based on the flour to make the dough. If you were to follow
this approach, just use around \qty{1}{\percent} and make the dough directly.
The dough is probably going to be ready 24~hours later, depending on the temperature.
If you want to make sweet pancakes, add some sugar and optional eggs to your dough
now. A good quantity of eggs is around one~egg per \qty{100}{\gram} of flour.
Stir your dough a little bit and it will be ready to be used. You'll
have delicious sweet savory pancakes, the perfect combination. By
adding the sugar now, you make sure that the microbes don't have
enough time to fully ferment it. If you had added the sugar
earlier, no sweet flavor would be left 12~hours later.
To bake your dough heat your stove to medium temperature. Add a little bit of
oil to the pan. This helps with heat distribution and ensures even cooking.
With a spatula or a spoon place your dough in the pan. If your dough
was sitting in the fridge, bake it directly. There is no need to wait for your
dough to come to room temperature. If you have a lid,
place it on your pan. The lid helps to cook your dough from the top.
The evaporating water will circulate and heat up the dough's surface. When
making a flatbread, make the dough around \qty{1}{\cm} thick. When using the
pancake option, opt for around \qtyrange{0.1}{0.5}{\cm} depending on what you
like.
\begin{figure}[htb]
\begin{center}
\includegraphics[width=1.0\textwidth]{einkorn-crumb.jpg}
\caption[Einkorn crum]{The crumb of a flatbread made with einkorn as flour.
Einkorn is very low in gluten and thus does not trap as much \ch{CO2} as
a wheat based dough. To make the dough fluffier use more water or
consider adding more wheat to the mix of your dough.}
\end{center}
\end{figure}
After 2--4~minutes flip over the pancake or flatbread. Bake it for the same
time from the other side. Depending on what you like, you can wait a little
longer to allow the bread to become a bit charred. The longer you
bake your bread, the more of the acidity is going to evaporate. If your
dough is a bit more on the sour side, you can use this trick to balance
out the acidity. This really depends on which flavor you are looking for.
When making a flatbread I~recommend wrapping the baked flatbreads in a kitchen
towel. This way more of the evaporating humidity stays inside of your bread,
making sure your flatbreads stay nice and fluffy for a longer period after the
bake. A similar strategy is used when making corn tortillas.
You can safely store the baked flatbreads or pancakes in your fridge
for weeks. When storing make sure to store them in an airtight plastic bag so that
they do not dry out.
Keep a little bit of your unbaked dough. You can use it to make the next
batch of bread or pancakes for the next day. If you want to bake a few days later, add
a little bit of water and flour and store this mixture in your fridge
for as long as you like\footnote{The starter will stay good for months. If you expect to
leave it longer, consider drying a little bit of your sourdough starter.}.
\subsection{Simple flatbread recipe}%
\label{subsec:flat-bread-recipe}
By following the steps outlined in this section,
you'll be introduced to a versatile bread that's perfect for a myriad of
culinary applications. Whether you're scooping up a savory dip,
wrapping a flavorful filling, or simply enjoying a piece with a drizzle
of olive oil, these flatbreads are sure to impress.
\subsubsection*{Ingredients}
\begin{tabular}{r@{}rl@{}}
\qty{400}{\gram} &~(\qty{100}{\percent}) & Flour (wheat, rye, corn, whatever you have at hand)\\
\qty{320}{\gram} & (\qty{80}{\percent}) & Water, preferably at room temperature\\
\qty{80}{\gram} & (\qty{20}{\percent}) & Active sourdough starter\\
\qty{8}{\gram} & (\qty{2}{\percent}) & Salt\\
\end{tabular}
\subsubsection*{Instructions}
\begin{description}
\item[Prepare the dough] In a large mixing bowl, combine the flour and water.
Mix until you have a shaggy dough with no dry spots.
Add the sourdough starter and salt to the mixture. Incorporate them thoroughly
until you achieve a smooth and homogenized dough.
\item[Fermentation:] Cover the bowl with a lid or plastic wrap. Allow the dough
to rest and ferment until it has increased by at least \qty{50}{\percent}
in size. Depending on the temperature and activity of your starter, this
can take anywhere from 4 to 24~hours.
\item[Cooking preparation:] Once the dough has risen, heat a pan over medium heat.
Lightly oil the pan, ensuring to wipe away any excess oil with a paper towel.
\item[Shaping and cooking:] With a ladle or your hands, scoop out a portion of
the dough and place it onto the hot pan, spreading it gently like a pancake.
Cover the pan with a lid. This traps the steam and ensures even cooking
from the top, allowing for easier flipping later.
After about 5~minutes, or when the bottom of the flatbread has a
golden-brown crust, carefully flip it using a spatula.
\emph{Adjusting cook time.} If the flatbread appears too dark,
remember to reduce the cooking time slightly for the next one.
Conversely, if it's too pale, allow it to cook a bit longer before flipping.
Cook the flipped side for an additional 5~minutes or until it's also golden
brown.
\item[Storing:] Once cooked, remove the flatbread from the pan and place it on a
kitchen towel. Wrapping the breads in the towel will help retain their
softness and prevent them from becoming overly crisp.
Repeat the cooking process for the remaining dough.
\item[Serving suggestion:] Enjoy your sourdough flatbreads warm,
paired with your favorite dips, spreads, or as a side to any meal.
\end{description}
\section{Loaf pan bread} \section{Loaf pan bread}
Loaf pan bread is made using the help of a special loaf pan Loaf pan bread is made using the help of a special loaf pan
@@ -133,15 +385,13 @@ and tools are required.
\end{center} \end{center}
\end{figure} \end{figure}
Normally you mix your dough. When using wheat you make sure Normally you mix your dough, when using wheat you make sure that you mix
that you mix enough to develop a gluten network. enough to develop a gluten network. You allow the dough to reach a certain
You allow the dough to reach size increase during the fermentation, afterwards you divide and pre-shape the
a certain size increase during the fermentation. Afterwards you divide and pre-shape dough into the desired visual shape that you like. Each shape requires a
the dough into the desired visual shape that you like. different technique. Sometimes achieving exactly the right shape can be
Each shape requires a different technique. Sometimes achieving challenging, making a baguette for instance, requires you to perform more
exactly the right shape can be challenging. Making a baguette, steps. Mastering this technique takes several attempts.
for instance, requires you to perform more steps. Mastering this
technique takes several attempts.
Once the dough is shaped, it is proofed again for a certain Once the dough is shaped, it is proofed again for a certain
period of time. Once the dough is ready, a sharp tool such period of time. Once the dough is ready, a sharp tool such
@@ -154,245 +404,4 @@ But after baking you will be rewarded with a beautiful bread
with great taste and consistency. with great taste and consistency.
There is a fully dedicated recipe and tutorial There is a fully dedicated recipe and tutorial
for this type of bread in the~''\nameref{chapter:wheat-sourdough}''~chapter. for this type of bread in the~''\nameref{chapter:wheat-sourdough}''~Chapter.
\section{Flatbread framework}%
\label{section:flat-bread-framework}
If you are just getting started, making a flatbread is the
easiest way to start making great bread at home. With just a
few steps, you can stop buying bread forever. This works with
any flour, including gluten-free options.
\begin{flowchart}[!htb]
\begin{center}
\input{figures/fig-process-flat-bread.tex}
\caption[The process to make a sourdough flatbread]{The process of making a flatbread is very
simple, requiring very little effort. This type of bread is especially
handy for busy bakers.}%
\label{fig:flat-bread-process}
\end{center}
\end{flowchart}
This is my go-to recipe that I~use to make bread whenever
I~have little time or when I~am abroad. You can choose
between two options:
%
\begin{enumerate}
\item A flatbread similar to a roti or naan bread
\item sourdough pancakes.
\end{enumerate}
\begin{table}[!htb]
\begin{center}
\input{tables/table-flat-bread-pancake-recipe.tex}
\caption[Flatbread recipe]{Flatbread or pancake recipe for 1 person.
Multiply the ingredients to increase portion size. Refer to the
Section~\ref{section:bakers-math}
``\nameref{section:bakers-math}'' to learn how to understand and
use the percentages properly.}%
\label{tab:flat-bread-ingredients}
\end{center}
\end{table}
To get started prepare your sourdough starter. If it has not been used for a very
long time, consider giving it another feed. To do so simply take \qty{1}{\gram} of your
existing sourdough starter and feed it with \qty{5}{\gram} of flour and \qty{5}{\gram} of water.
If you do this in the morning, your sourdough starter will be ready in the evening. The
warmer it is, the sooner it will be ready. If it is very cold where you live, consider
using warm water.
\begin{figure}[htb!]
\begin{center}
\includegraphics[width=1.0\textwidth]{flat-bread-wheat}
\caption[Wheat flatbread]{A flatbread made with purely wheat flour. The
dough is drier at around \qty{60}{\percent} hydration. The drier dough
is a little harder to mix. As wheat contains more gluten, the dough
puffs up during the baking process.}
\end{center}
\end{figure}
This way you should have around \qty{11}{\gram} of sourdough ready in the evening. You will have
the perfect quantity to make a dough for one person. In case you want to make more
bread, simply multiply the quantities shown in
Table~\ref{tab:flat-bread-ingredients}.
Then in the evening simply mix the ingredients as shown in the table. Your dough
is going to be ready in the morning. It's typically ready after 6--12~hours. If
you use more sourdough starter, it will be ready faster. If you use less it will take
longer. Try to aim for a fermentation time of 8--12~hours. If you use
your dough too soon, the flavor might not be as good. If you use it later
your dough might be a little more sour. The best option is to experiment
and see what you personally like the most.
After mixing the ingredients together, cover the container in which
you made the dough. This prevents the dough from drying out and makes
sure no fruit flies get access. A transparent container will be helpful
when getting started. You can observe the dough more easily and see when
it is ready.
\begin{figure}[htb!]
\begin{center}
\includegraphics[width=1.0\textwidth]{ethiopian-woman-checking-bread}
\caption[Ethiopian \emph{injera}]{An Ethiopian woman baking an \emph{injera}
made using teff flour. The image has been provided by Charliefleurene
via Wikipedia.}
\end{center}
\end{figure}
If you used the flatbread option with less water, look at the size increase
of your dough. The dough should have increased at least \qty{50}{\percent} in size.
Also look out for bubbles on the sides of your container.
When using the pancake recipe, look out for bubbles on the surface of your dough.
In both cases use your nose to check the scent of your dough. Depending
on your sourdough starter's microbiome your dough will have
dairy, fruity, alcoholic notes or vinegary, acetic notes. Relying
on the smell of your dough is the best way to judge whether your
dough is ready or not. Timings are not reliable as they
depend on your starter and the temperature. If your dough
is ready too soon, you can now move it directly to the fridge and bake
it at a later, more convenient time. The low temperature will halt the fermentation
process\footnote{There are some exceptions. In some rare cases your starter
might also work at lower temperatures. You might have cultivated microbes that work best at
low temperatures. Nevertheless, fermentation
is always slower the colder it gets. A fridge really helps to preserve the state
of your dough.}.
and your dough will last for several days. The longer you wait, the more sour the
bread is going to be. The fridge is a great option in case you want to
take the dough with you when visiting friends. People are going
to love you for the freshly baked flatbreads or pancakes. If you dare,
you can also taste a little bit of your raw uncooked dough. It is likely
going to taste relatively sour. I~do this frequently to better evaluate the
state of my doughs.
\begin{figure}[htb!]
\begin{center}
\includegraphics[width=1.0\textwidth]{injera-pancake-texture.jpg}
\caption[Teff sourdough pancake]{A sourdough pancake made with teff flour.
The pockets come from evaporated water and \ch{CO2} created by the
microbes. The image has been provided by Lukasz Nowak via Wikipedia.}
\end{center}
\end{figure}
If you are feeling lazy or don't have time, you could also use older sourdough starter
to make the dough directly without any prior starter feedings. Your sourdough starter
is going to regrow inside your dough. The
final bread might be a bit more on the sour side as the balance of yeast to
bacteria could be off. In the Table~\ref{tab:flat-bread-ingredients}
I~recommended using around \qtyrange{5}{20}{\percent}
of sourdough starter based on the flour to make the dough. If you were to follow
this approach, just use around \qty{1}{\percent} and make the dough directly.
The dough is probably going to be ready 24~hours later, depending on the temperature.
If you want to make sweet pancakes, add some sugar and optional eggs to your dough
now. A good quantity of eggs is around 1 egg per \qty{100}{\gram} of flour.
Stir your dough a little bit and it will be ready to be used. You'll
have delicious sweet savory pancakes, the perfect combination. By
adding the sugar now, you make sure that the microbes don't have
enough time to fully ferment it. If you had added the sugar
earlier, no sweet flavor would be left 12~hours later.
To bake your dough heat your stove to medium temperature. Add a little bit of
oil to the pan. This helps with heat distribution and ensures even cooking.
With a spatula or a spoon place your dough in the pan. If your dough
was sitting in the fridge, bake it directly. There is no need to wait for your
dough to come to room temperature. If you have a lid,
place it on your pan. The lid helps to cook your dough from the top.
The evaporating water will circulate and heat up the dough's surface. When
making a flatbread, make the dough around \qty{1}{\cm} thick. When using the
pancake option, opt for around \qtyrange{0.1}{0.5}{\cm} depending on what you
like.
\begin{figure}[htb!]
\begin{center}
\includegraphics[width=1.0\textwidth]{einkorn-crumb.jpg}
\caption[Einkorn crum]{The crumb of a flatbread made with einkorn as flour.
Einkorn is very low in gluten and thus does not trap as much \ch{CO2} as
a wheat based dough. To make the dough fluffier use more water or
consider adding more wheat to the mix of your dough.}
\end{center}
\end{figure}
After 2--4~minutes flip over the pancake or flatbread. Bake it for the same
time from the other side. Depending on what you like, you can wait a little
longer to allow the bread to become a bit charred. The longer you
bake your bread, the more of the acidity is going to evaporate. If your
dough is a bit more on the sour side, you can use this trick to balance
out the acidity. This really depends on which flavor you are looking for.
When making a flatbread I~recommend wrapping the baked flatbreads
in a kitchen towel. This way more of the evaporating humidity
stays inside of your bread. This makes sure your flatbreads stay
nice and fluffy for a longer period after the bake. A similar strategy is
used when making corn tortillas.
You can safely store the baked flatbreads or pancakes in your fridge
for weeks. When storing make sure to store them in an airtight plastic bag so that
they do not dry out.
Keep a little bit of your unbaked dough. You can use it to make the next
batch of bread or pancakes for the next day. If you want to bake a few days later, add
a little bit of water and flour and store this mixture in your fridge
for as long as you like\footnote{The starter will stay good for months. If you expect to
leave it longer, consider drying a little bit of your sourdough starter.}.
\section{Simple flatbread recipe}%
\label{section:flat-bread-recipe}
By following the steps outlined in this section,
you'll be introduced to a versatile bread that's perfect for a myriad of
culinary applications. Whether you're scooping up a savory dip,
wrapping a flavorful filling, or simply enjoying a piece with a drizzle
of olive oil, these flatbreads are sure to impress.
\subsection*{Ingredients}
\begin{tabular}{r@{}rl@{}}
\qty{400}{\gram} &~(\qty{100}{\percent}) & Flour (wheat, rye, corn, whatever you have at hand)\\
\qty{320}{\gram} & (\qty{80}{\percent}) & Water, preferably at room temperature\\
\qty{80}{\gram} & (\qty{20}{\percent}) & Active sourdough starter\\
\qty{8}{\gram} & (\qty{2}{\percent}) & Salt\\
\end{tabular}
\subsection*{Instructions}
\begin{description}
\item[Prepare the Dough] In a large mixing bowl, combine the flour and water.
Mix until you have a shaggy dough with no dry spots.
Add the sourdough starter and salt to the mixture. Incorporate them thoroughly
until you achieve a smooth and homogenized dough.
\item[Fermentation] Cover the bowl with a lid or plastic wrap. Allow the dough
to rest and ferment until it has increased by at least \qty{50}{\percent}
in size. Depending on the temperature and activity of your starter, this
can take anywhere from 4 to 24~hours.
\item[Cooking Preparation] Once the dough has risen, heat a pan over medium heat.
Lightly oil the pan, ensuring to wipe away any excess oil with a paper towel.
\item[Shaping and Cooking] With a ladle or your hands, scoop out a portion of
the dough and place it onto the hot pan, spreading it gently like a pancake.
Cover the pan with a lid. This traps the steam and ensures even cooking
from the top, allowing for easier flipping later.
After about 5~minutes, or when the bottom of the flatbread has a
golden-brown crust, carefully flip it using a spatula.
\item[Adjusting Cook Time] If the flatbread appears too dark,
remember to reduce the cooking time slightly for the next one.
Conversely, if it's too pale, allow it to cook a bit longer before flipping.
Cook the flipped side for an additional 5~minutes or until it's also golden
brown.
\item[Storing] Once cooked, remove the flatbread from the pan and place it on a
kitchen towel. Wrapping the breads in the towel will help retain their
softness and prevent them from becoming overly crisp.
Repeat the cooking process for the remaining dough.
\item[Serving Suggestion] Enjoy your sourdough flatbreads warm,
paired with your favorite dips, spreads, or as a side to any meal.
\end{description}

View File

@@ -1,23 +1,22 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 4cm, auto]
\node [start] (heat_oven) {Heat oven to \qty{230}{\degreeCelsius} (\qty{446}{\degF}) for 30~minutes}; \node [start] (heat_oven) {Heat oven to \qty{230}{\degreeCelsius} (\qty{446}{\degF}) for 30~minutes};
\node [block, right of=heat_oven, node distance=3cm] (score_dough) {Score your dough}; \node [block, right of=heat_oven] (score_dough) {Score your dough};
\node [decision, right of=score_dough, node distance=4cm] (decide_steam) {Choose your steaming method}; \node [decision, right of=score_dough, node distance=4cm] (decide_steam) {Choose your steaming method};
\node [block, below of=heat_oven, node distance=4cm] (inverted_tray_method) {Inverted tray method}; \node [block, below of=decide_steam, node distance=3.5cm] (dutch_oven) {Dutch oven};
\node [block, right of=inverted_tray_method, node distance=3cm] (dutch_oven) {Dutch oven}; \node [block, left of=dutch_oven] (inverted_tray_method) {Inverted tray method};
\node [block, right of=dutch_oven, node distance=3cm] (steam_injection) {Steam injection oven}; \node [block, right of=dutch_oven] (steam_injection) {Steam injection oven};
\node [block, below of=inverted_tray_method, node distance=3cm] (bake_30) {Bake dough for 30~minutes with steam}; \node [block, below of=dutch_oven, node distance=3cm] (bake_30) {Bake dough for 30~minutes with steam};
\node [block, right of=bake_30, node distance=3cm] (remove_steam) {Remove source of steam}; \node [block, below of=bake_30, node distance=3cm] (remove_steam) {Remove source of steam};
\node [block, right of=remove_steam, node distance=3cm] (build_crust) {Build the crust}; \node [success, right of=remove_steam] (finish_baking) {Stop baking 10--30~minutes later depending on crust preference};
\node [success, right of=build_crust, node distance=3cm] (finish_baking) {Stop baking 10--30~minutes later depending on crust preference};
\path [line] (heat_oven) -- (score_dough); \path [line] (heat_oven) -- (score_dough);
\path [line] (score_dough) -- (decide_steam); \path [line] (score_dough) -- (decide_steam);
\path [line] (decide_steam) -- (inverted_tray_method); \path [line] (decide_steam) -- (inverted_tray_method.north east);
\path [line] (decide_steam) -- (dutch_oven); \path [line] (decide_steam) -- (dutch_oven);
\path [line] (decide_steam) -- (steam_injection); \path [line] (decide_steam) -- (steam_injection.north west);
\path [line] (steam_injection) -- (bake_30); \path [line] (steam_injection.south west) -- (bake_30.north east);
\path [line] (inverted_tray_method) -- (bake_30); \path [line] (inverted_tray_method.south east) -- (bake_30.north west);
\path [line] (dutch_oven) -- (bake_30); \path [line] (dutch_oven) -- (bake_30);
\path [line] (bake_30) -- (remove_steam); \path [line] (bake_30) -- (remove_steam);
\path [line] (remove_steam) -- (build_crust); \path [line] (remove_steam) -- (finish_baking);
\path [line] (build_crust) -- (finish_baking); \draw[BC, decoration=mirror] (remove_steam.south west) ++(0, -0.3) -- node[below=1em]{Building crust}(finish_baking.south east);
\end{tikzpicture} \end{tikzpicture}

View File

@@ -1,25 +1,28 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 3cm, auto]
\node [start] (init) {Bulk fermentation}; \node [start] (init) {Bulk fermentation};
\node [block, right of=init] (check_dough) {Check the dough}; \node [block, right of=init, node distance=4cm] (check_dough) {Check the dough};
\node [block, right of=check_dough, node distance=4cm] (size_increase) {Check dough size increase}; \node [block, right of=check_dough, node distance=4cm] (size_increase) {Check dough size increase};
\node [block, below of=size_increase, node distance=2cm] (ph_value) {Check dough pH value}; \node [block, below of=size_increase, node distance=2cm] (ph_value) {Check dough pH value};
\node [block, below of=ph_value, node distance=2cm] (smell) {Check dough smell}; \node [block, below of=ph_value, node distance=2cm] (smell) {Check dough smell};
\node [decision, right of=ph_value, node distance=4cm] (dough_ready) {Dough ready?}; \node [decision, right of=size_increase, node distance=4cm] (dough_ready) {Dough ready?};
\node [success, below of=dough_ready] (divide_preshape) {Divide and preshape}; \node [success] at(dough_ready |- smell) (divide_preshape) {Divide and preshape};
\node [decision, below of=smell] (dough_flattened) {Dough flattened out?}; \node [decision, above of=size_increase] (dough_flattened) {Dough flattened out?};
\node [block, below of=check_dough, node distance=3cm] (wait_60_minutes) {Wait\\ 60~minutes}; \node [block, above of=check_dough] (wait_60_minutes) {Wait\\ 60~minutes};
\node [block, below of=wait_60_minutes, node distance=4cm] (stretch_fold) {Stretch and fold}; \node [block, above of=wait_60_minutes] (stretch_fold) {Stretch and fold};
\path [line] (init) -- (check_dough); \path [line] (init) -- (check_dough);
\path [line] (check_dough) -- (size_increase); \path [line] (check_dough) -- (size_increase);
\path [line] (check_dough) -- node{or} (ph_value); % Tricks not to get double lines
\path [line] (check_dough) -- node{or} (smell); \path [line] (check_dough) ++(2, -2) -- node{or} (ph_value);
\path [line] (check_dough) ++(2, 0) -- node{} ++(0, -4) -- node{or} (smell);
\path [line] (check_dough) ++(2, -4) -- node{or} (smell);
\path [line] (size_increase) -- (dough_ready); \path [line] (size_increase) -- (dough_ready);
\path [line] (ph_value) -- (dough_ready); % Same tricks not to get double lines and also we do _not_ want arrows
\path [line] (smell) -- (dough_ready); \path [draw, thick] (ph_value) -- node{} ++(2, 0);
\path [draw, thick] (smell) -| node{} ++(2, 4);
\path [line] (dough_ready) -- node{yes} (divide_preshape); \path [line] (dough_ready) -- node{yes} (divide_preshape);
\path [line] (dough_ready) -- node{no} (dough_flattened); \path [line] (dough_ready) |- node[right=3pt]{no} (dough_flattened);
\path [line] (dough_flattened) -- node{yes} (stretch_fold); \path [line] (dough_flattened) |- node[right=3pt]{yes} (stretch_fold);
\path [line] (dough_flattened) -- node{no} (wait_60_minutes); \path [line] (dough_flattened) -- node{no} (wait_60_minutes);
\path [line] (stretch_fold) -- (wait_60_minutes); \path [line] (stretch_fold) -- (wait_60_minutes);
\path [line] (wait_60_minutes) -- (check_dough); \path [line] (wait_60_minutes) -- (check_dough);

View File

@@ -2,8 +2,8 @@
\node [start] (init) {Dividing required?}; \node [start] (init) {Dividing required?};
\node [decision, right of=init, node distance=5cm] (more_than_one_loaf) {More than 1 loaf?}; \node [decision, right of=init, node distance=5cm] (more_than_one_loaf) {More than 1 loaf?};
\node [success, right of=more_than_one_loaf, node distance=5cm] (yes) {Yes}; \node [success, right of=more_than_one_loaf, node distance=5cm] (yes) {Yes};
\node [success, below of=yes, node distance=3cm] (no) {No}; \node [success, below of=yes] (no) {No};
\path [line] (init) -- (more_than_one_loaf); \path [line] (init) -- (more_than_one_loaf);
\path [line] (more_than_one_loaf) -- (yes); \path [line] (more_than_one_loaf) -- (yes);
\path [line] (more_than_one_loaf) -- (no); \path [line] (more_than_one_loaf.south) -- node{} ++(0, -1) |- (no);
\end{tikzpicture} \end{tikzpicture}

View File

@@ -1,26 +1,26 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 4cm, auto]
\node [start] (init) {Homogenize recipe ingredients}; \node [start] (init) {Homogenize recipe ingredients};
\node [block, right of=init, node distance=3cm] (wait1) {Wait\\15~minutes}; \node [block, right of=init] (wait1) {Wait\\15~minutes};
\path [line] (init) -- (wait1); \path [line] (init) -- (wait1);
\node [block, right of=wait1, node distance=3cm] (knead1) {Knead 5~minutes}; \node [block, right of=wait1] (knead) {Knead 5~minutes};
\path [line] (wait1) -- (knead1); \path [line] (wait1) -- (knead);
\node [block, right of=knead1, node distance=3cm] (wait2) {Wait\\15~minutes}; \node [block, right of=knead] (wait2) {Wait\\15~minutes};
\path [line] (knead1) -- (wait2); \path [line] (knead) -- (wait2);
\node [decision, below of=wait2, node distance=3cm] (windowpane_test) {Window-pane?}; \node [decision, below of=wait2, node distance=4cm] (windowpane_test) {Window-pane?};
\path [line] (wait2) -- (windowpane_test); \path [line] (wait2) -- (windowpane_test);
\path [line] (windowpane_test) -- node{no} (knead1); \path [line] (windowpane_test.east) -- node{no} ++(1, 0) -- node{} ++(0, 5.7) -| (knead.north);
\node [decision, left of=windowpane_test, node distance=4.5cm] (more_water) {Bassinage for more water?}; \node [decision] at (windowpane_test -| knead) (more_water) {Bassinage for more water?};
\path [line] (windowpane_test) -- node{yes} (more_water); \path [line] (windowpane_test) -- node{yes} (more_water);
\node [block, left of=more_water, node distance=4.5cm] (add_water) {Add water}; \node [block] at (wait1 |- more_water) (add_water) {Add water};
\path [line] (more_water) -- node{yes} (add_water); \path [line] (more_water) -- node{yes} (add_water);
\path [line] (add_water) -- (knead1); \path [line] (add_water.north east) -- (knead.south west);
\node [decision, below of=more_water, node distance=3.5cm] (dough_sample) {Aliquot sample?}; \node [decision, below of=more_water, node distance=4.5cm] (dough_sample) {Aliquot sample?};
\path [line] (more_water) -- node{no} (dough_sample); \path [line] (more_water) -- node{no} (dough_sample);
\node [block, right of=dough_sample, node distance=4.5cm] (dough_ball) {Make round dough ball}; \node [block] at (dough_sample -| wait2) (dough_ball) {Make round dough ball};
\path [line] (dough_sample) -- node{no} (dough_ball); \path [line] (dough_sample) -- node{no} (dough_ball);
\node [block, below of=dough_sample, node distance=3cm] (extract_sample) {Extract sample}; \node [block, below of=dough_sample] (extract_sample) {Extract sample};
\path [line] (dough_sample) -- node{yes} (extract_sample); \path [line] (dough_sample) -- node{yes} (extract_sample);
\path [line] (extract_sample) -- (dough_ball); \path [line] (extract_sample.north east) -- (dough_ball.south west);
\node [success, below of=dough_ball, node distance=3cm] (begin_bulk) {Begin bulk fermentation}; \node [success, below of=dough_ball] (begin_bulk) {Begin bulk fermentation};
\path [line] (dough_ball) -- (begin_bulk); \path [line] (dough_ball) -- (begin_bulk);
\end{tikzpicture} \end{tikzpicture}

View File

@@ -26,12 +26,15 @@
\draw[line width=1pt] (11.6*\segmentwidth,1) -- (11.6*\segmentwidth,0.2); \draw[line width=1pt] (11.6*\segmentwidth,1) -- (11.6*\segmentwidth,0.2);
% Dinosaur extinction % Dinosaur extinction
\draw[line width=1pt] (11.9*\segmentwidth,1.5) -- (11.9*\segmentwidth,0.2); \draw[line width=1pt] (11.9*\segmentwidth,1.5) -- (11.9*\segmentwidth,0.2);
% Additional line for dinosaurs since it is so close
\draw[line width=1pt] (11.9*\segmentwidth,1.49) -- (11.70*\segmentwidth,1.85);
% Special lines for december events since they are so close togehter % Special lines for december events since they are so close togehter
\draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (12.0*\segmentwidth,0.2); % Main branch \draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (12.0*\segmentwidth,0.2); % Main branch
\draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (11.75*\segmentwidth,2.5); % Branch to first humans \draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (11.75*\segmentwidth,2.5); % Branch to first humans
\draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (11.75*\segmentwidth,3.0); % Branch to Jordan \draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (11.75*\segmentwidth,3.0); % Branch to Jordan
\draw[line width=1pt] (12.0*\segmentwidth,3.0) -- (11.75*\segmentwidth,3.5); % Branch to Pasteur % Move pasteur down a bit so the lines look like they cross
\draw[line width=1pt] (12.0*\segmentwidth,2.99) -- (11.75*\segmentwidth,3.5); % Branch to Pasteur
% Draw months and month separators % Draw months and month separators
\foreach \i/\month in {0/Jan, 1/Feb, 2/Mar, 3/Apr, 4/May, 5/Jun, 6/Jul, 7/Aug, 8/Sep, 9/Oct, 10/Nov, 11/Dec} { \foreach \i/\month in {0/Jan, 1/Feb, 2/Mar, 3/Apr, 4/May, 5/Jun, 6/Jul, 7/Aug, 8/Sep, 9/Oct, 10/Nov, 11/Dec} {
@@ -43,28 +46,24 @@
\draw[line width=1pt] (\textwidth,0.1) -- (\textwidth,-0.1); \draw[line width=1pt] (\textwidth,0.1) -- (\textwidth,-0.1);
% Full timeline width for billion years % Full timeline width for billion years
\draw[line width=1pt] (0,-3.8) -- node[midway, timeline_timespan] {5.45 billion years} (\textwidth,-3.8); \draw[stealth-stealth, line width=1pt] (0,-3.8) -- node[midway, timeline_timespan] {5.45 billion years} (\textwidth,-3.8);
\draw[line width=1pt] (0,-3.7) -- (0,-3.9);
\draw[line width=1pt] (\textwidth,-3.7) -- (\textwidth,-3.9);
% Indicator for the period of 3 months = 1.1 billion years % Indicator for the period of 3 months = 1.1 billion years
\draw[line width=1pt] (0,-1.0) -- node[midway, timeline_timespan] {1.11 billion years} ({\segmentwidth * 3},-1.0); \draw[stealth-stealth, line width=1pt] (0,-1.0) -- node[midway, timeline_timespan] {1.11 billion years} ({\segmentwidth * 3},-1.0);
\draw[line width=1pt] (0,-0.9) -- (0,-1.1);
\draw[line width=1pt] ({\segmentwidth * 3},-0.9) -- ({\segmentwidth * 3},-1.1);
% Place events on the timeline with dates using the timeline_event style % Place events on the timeline with dates using the timeline_event style
% As a calculation I used (4.54 billion years / 12 months = 0.3785 billion years/month. % As a calculation I used (4.54 billion years / 12 months = 0.3785 billion years/month.
\node[timeline_event, above] at (2.0*\segmentwidth,1) {Mar 25 - First maritime bacteria and archae}; \node[timeline_event, above] at (2.5*\segmentwidth,1) {Mar 25:~First maritime bacteria and archae};
\node[timeline_event, above] at (4.50*\segmentwidth,1.5) {June 25 - First organisms with nuklei (eukaryotes)}; \node[timeline_event, above] at (4.50*\segmentwidth,1.5) {June 25:~First organisms with nuklei (eukaryotes)};
\node[timeline_event, above] at (7.8*\segmentwidth,-1.5) {Oct 4 - First bacteria on land}; \node[timeline_event, above] at (7.8*\segmentwidth,-1.5) {Oct 4:~First bacteria on land};
\node[timeline_event, above] at (8.0*\segmentwidth,-2.25) {Oct 15 - First maritime ancestors of fungi}; \node[timeline_event, above] at (8.0*\segmentwidth,-2.25) {Oct 15:~First maritime ancestors of fungi};
\node[timeline_event, above] at (9.7*\segmentwidth,-2.75) {Nov 24 - Fungi on land}; \node[timeline_event, above] at (9.7*\segmentwidth,-2.75) {Nov 24:~Fungi on land};
\node[timeline_event, above] at (10.5*\segmentwidth,-3.25) {Dec 3 - Yeasts on land}; \node[timeline_event, above] at (10.5*\segmentwidth,-3.25) {Dec 3:~Yeasts on land};
\node[timeline_event, above] at (10.2*\segmentwidth,0.5) {Dec 14 - First dinosaurs}; \node[timeline_event, above] at (10.2*\segmentwidth,0.5) {Dec 14:~First dinosaurs};
\node[timeline_event, above] at (9.8*\segmentwidth,1) {Dec 17 - Pangea begins to rift apart}; \node[timeline_event, above] at (9.8*\segmentwidth,1) {Dec 17:~Pangea begins to rift apart};
\node[timeline_event, above] at (10.33*\segmentwidth,1.5) {Dec 29 - Dinosaurs go extinct}; \node[timeline_event, above] at (10.15*\segmentwidth,1.5) {Dec 29:~Dinosaurs go extinct};
\node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,2.5) {Dec 31 - First humans}; \node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,2.5) {Dec 31:~First humans};
\node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,3.0) {Dec 31 - Sourdough in Jordan (23:59:55)}; \node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,3.0) {Dec 31:~Sourdough in Jordan (23:59:55)};
\node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,3.5) {Dec 31 - Louis Pasteur isolated yeast (23:59:59)}; \node[timeline_event, above, anchor=east, align=right] at (11.75*\segmentwidth,3.5) {Dec 31:~Louis Pasteur isolated yeast (23:59:59)};
\end{tikzpicture} \end{tikzpicture}

View File

@@ -1,22 +1,20 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 3cm, auto]
\node [decision_start] (init) {Room temperature proofing?}; \node [decision_start] (init) {Room temperature proofing?};
\node [decision, right of=init, node distance=9cm] (retard_bake_decision) {Bake in less than \qty{10}{\hour} from now?}; \node [decision, right of=init, node distance=8cm] (retard_bake_decision) {Bake in less than \qty{10}{\hour} from now?};
\node [block, below of=init, node distance=4cm] (poke) {Poke the dough}; \node [block, below of=init, node distance=4cm] (poke) {Poke the dough};
\node [block, right of=poke, node distance=4cm] (wait_poke) {Wait\\ 15~minutes}; \node [block, left of=poke] (wait_poke) {Wait\\ 15~minutes};
\node [decision, below of=poke, node distance=3cm] (dent_visible_decision) {Dent still visible after 1~minute?}; \node [decision, below of=poke] (dent_visible_decision) {Dent still visible after one~minute?};
\node [success, right of=dent_visible_decision, node distance=4cm] (bake) {Score and bake}; \node [success, right of=dent_visible_decision, node distance=4cm] (bake) {Score and bake};
\node [block, below of=retard_bake_decision, node distance=3cm] (wait_retard) {Wait\\ 15~minutes}; \node [block] at (retard_bake_decision |- poke) (wait_retard) {Wait\\ 15~minutes};
\node [block, below of=wait_retard, node distance=3cm] (retard) {Proof in fridge at \qty{4}{\degreeCelsius} (\qty{40}{\degF})}; \node [block] at (wait_retard |- bake) (retard) {Proof in fridge at \qty{4}{\degreeCelsius} (\qty{40}{\degF})};
\node [block, right of=wait_retard, node distance=3cm] (move_to_fridge) {Move dough directly to fridge};
\path [line] (init) -- node{yes} (poke); \path [line] (init) -- node{yes} (poke);
\path [line] (init) -- node{no} (retard_bake_decision); \path [line] (init) -- node{no} (retard_bake_decision);
\path [line] (poke) -- (dent_visible_decision); \path [line] (poke) -- (dent_visible_decision);
\path [line] (dent_visible_decision) -- node{yes} (bake); \path [line] (dent_visible_decision) -- node{yes} (bake);
\path [line] (dent_visible_decision) -- node{no} (wait_poke); \path [line] (dent_visible_decision.west) -- node{no} ++(-1.4, 0) -- node{} (wait_poke.south);
\path [line] (wait_poke) -- (poke); \path [line] (wait_poke) -- (poke);
\path [line] (retard_bake_decision) -- node{yes} (wait_retard); \path [line] (retard_bake_decision) -- node{yes} (wait_retard);
\path [line] (retard_bake_decision) -- node{no} (move_to_fridge); \path [line] (retard_bake_decision.east) -- node{no} ++(1, 0) |- node{} (retard.east);
\path [line] (wait_retard) -- (retard); \path [line] (wait_retard) -- (retard);
\path [line] (move_to_fridge) -- (retard);
\path [line] (retard) -- (bake); \path [line] (retard) -- (bake);
\end{tikzpicture} \end{tikzpicture}

View File

@@ -1,12 +1,12 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 3cm, auto]
\node [start] (init) {Begin shaping}; \node [start] (init) {Begin shaping};
\node [decision, right of=init, node distance=5cm] (overfermented_decision) {Dough overly sticky or dough tears?}; \node [decision, right of=init, node distance=4cm] (overfermented_decision) {Dough overly sticky or dough tears?};
\node [block, right of=overfermented_decision, node distance=4cm] (overfermented) {Your dough is likely overfermented}; \node [block, right of=overfermented_decision, node distance=4cm] (overfermented) {Your dough is likely overfermented};
\node [fail, right of=overfermented, node distance=3cm] (loafpan) {Move to loaf pan, short proof, then bake directly}; \node [fail, right of=overfermented, node distance=4cm] (loafpan) {Move to loaf pan, short proof, then bake directly};
\node [block, below of=init, node distance=4cm] (shaping_technique) {Proceed with shaping technique}; \node [block, below of=overfermented_decision, node distance=4cm] (shaping_technique) {Proceed with shaping technique};
\node [block, right of=shaping_technique, node distance=3cm] (flour) {Flour shaped dough}; \node [block, right of=shaping_technique] (flour) {Flour shaped dough};
\node [block, right of=flour, node distance=3cm] (banneton) {Place upside down in banneton}; \node [block, right of=flour] (banneton) {Place upside down in banneton};
\node [success, right of=banneton, node distance=3cm] (proof) {Begin proofing}; \node [success, right of=banneton] (proof) {Begin proofing};
\path [line] (init) -- (overfermented_decision); \path [line] (init) -- (overfermented_decision);
\path [line] (overfermented_decision) -- node{yes} (overfermented); \path [line] (overfermented_decision) -- node{yes} (overfermented);
\path [line] (overfermented_decision) -- node{no} (shaping_technique); \path [line] (overfermented_decision) -- node{no} (shaping_technique);

View File

@@ -0,0 +1,69 @@
\begin{tikzpicture}
\pgfmathsetlengthmacro{\timelinewidth}{(\textwidth-0.5cm)}
% Define the width of each segment
\pgfmathsetlengthmacro{\segmentwidth}{\timelinewidth/12}
% Draw horizontal lines
\draw[line width=1pt, color=hlorange] (0,0) -- (\timelinewidth/2,0);
\draw[line width=1pt] (\timelinewidth/2,0) -- (\timelinewidth/2 +1.5*\segmentwidth/3,0);
\draw[line width=1pt] (\timelinewidth/2 + 2*\segmentwidth/3,0) --(\timelinewidth, 0);
\draw[line width=1pt] (\timelinewidth/2+1.5*\segmentwidth/3-5,-0.2) -- (\timelinewidth/2+1.5*\segmentwidth/3+5, 0.2);
\draw[line width=1pt] (\timelinewidth/2+2*\segmentwidth/3-5,-0.2) -- (\timelinewidth/2+2*\segmentwidth/3+5, 0.2);
% Lines for periods
\draw[stealth-stealth, line width=1pt] (0,-3.7)
-- node[midway, timeline_timespan] {Historic breadmaking} ({\segmentwidth * 7.8},-3.7);
\draw[stealth-stealth, line width=1pt] ({\segmentwidth * 7.8},-3.7)
-- node[midway, timeline_timespan] {Modern bread} ({\segmentwidth * 12},-3.7);
% Regularly placed events, not in chronological order
% since should be placed on top of others on the timeline
% BC
\draw[line width=1pt] ({\segmentwidth*3},1.0) -- ({\segmentwidth*3},0.3)
node[at start, left, timeline_event] {6000~BC: First beer in Egypt};
\draw[line width=1pt] ({\segmentwidth*5.95},1.5) -- ({\segmentwidth*5.95},0.3)
node[at start, left, timeline_event] {70~BC:~First water mill};
% Sourdough in Jordan
\draw[line width=1pt] (0,-0.3) -- (0,-1.5);
\draw[line width=1pt] (0,-1.5) -- (0.25,-1.5);
\node[timeline_event, below, anchor=west] at (0.25,-1.5)
{\begin{tabular}{@{}l@{}l@{}}
\num{12000}~BC:&~Sourdough in Jordan\\
&~Cultivation of Einkorn\\
\end{tabular}};
% AD
\draw[line width=1pt] ({\segmentwidth*10.50},1.0) -- ({\segmentwidth*10.50},0.3)
node[at start, above, timeline_event] {\hspace{1.0cm}1950:~Modern Wheat};
\draw[line width=1pt] ({\segmentwidth*9.60},1.5) -- ({\segmentwidth*9.60},0.3)
node[at start, above, timeline_event] {1868:~Commercial yeast};
\draw[line width=1pt] ({\segmentwidth*7.8},2) -- ({\segmentwidth*7.8},0.3)
node[at start, above, timeline_event] {1680:~Discovery of microorganisms};
\draw[line width=1pt] ({\segmentwidth*8.80},-1.25) -- ({\segmentwidth*8.80},-0.3)
node[at start, left, timeline_event] {1785:~Steam mill};
\draw[line width=1pt] ({\segmentwidth*9.57},-1.75) -- ({\segmentwidth*9.57},-0.3)
node[at start, left, timeline_event] {1857:~Isolated Yeast};
\draw[line width=1pt] ({\segmentwidth*9.80},-2.25) -- ({\segmentwidth*9.80},-0.3)
node[at start, left, timeline_event] {1885:~Electrical mixer};
\draw[line width=1pt] ({\segmentwidth*11.20},-2.75) -- ({\segmentwidth*11.20},-0.3)
node[at start, left, timeline_event] {2020:~COVID-19 Pandemic};
% Indicators for period
% Draw millenary and century separators
\foreach \i/\century in {0/-12000, 1/-10000, 2/-8000, 3/-6000, 4/-4000, 5/-2000}{
% Separators
\draw[line width=1pt, color=hlorange] (\i*\segmentwidth,0.1) -- (\i*\segmentwidth,-0.1);
% Events for timeline
\node[timeline_event, below, text=hlorange] at ({(\i)*\segmentwidth},-0.1) {\num{\century}};
}
\foreach \i/\century in {6/0, 7/1600, 8/1700, 9/1800, 10/1900, 11/2000, 12/2100}{
% Separators
\draw[line width=1pt] (\i*\segmentwidth,0.1) -- (\i*\segmentwidth,-0.1);
% Events for timeline
\node[timeline_event, below] at ({(\i)*\segmentwidth},-0.1) {\num{\century}};
}
\end{tikzpicture}

View File

@@ -1,14 +1,14 @@
\begin{tikzpicture}[node distance = 3cm, auto] \begin{tikzpicture}[node distance = 3.2cm, auto]
\node [start] (init) {Ready starter}; \node [start] (init) {Ready starter};
\node [block, right of=init, node distance=3cm] (mix_ingredients) {Mix ingredients}; \node [block, right of=init] (mix_ingredients) {Mix ingredients};
\node [block, right of=mix_ingredients, node distance=3cm] (dough_strength) {Create dough strength}; \node [block, right of=mix_ingredients] (dough_strength) {Create dough strength};
\node [block, right of=dough_strength, node distance=3cm] (bulk) {Bulk ferment}; \node [block, right of=dough_strength] (bulk) {Bulk ferment};
\node [decision, below of=dough_strength, node distance=3cm] (divide_test) {Making 1 loaf?}; \node [decision, below of=bulk] (divide_test) {Making one loaf?};
\node [block, left of=divide_test, node distance=3cm] (divide) {Divide}; \node [block, right of=divide_test] (divide) {Divide};
\node [block, left of=divide, node distance=3cm] (preshape) {Preshape}; \node [block, below of=divide] (preshape) {Preshape};
\node [block, below of=preshape, node distance=3cm] (shape) {Shape}; \node [block, below of=divide_test] (shape) {Shape};
\node [block, right of=shape, node distance=3cm] (proof) {Proof}; \node [block, left of=shape] (proof) {Proof};
\node [success, right of=proof, node distance=3cm] (bake) {Bake}; \node [success, left of=proof] (bake) {Bake};
\path [line] (init) -- (mix_ingredients); \path [line] (init) -- (mix_ingredients);
\path [line] (mix_ingredients) -- (dough_strength); \path [line] (mix_ingredients) -- (dough_strength);
\path [line] (dough_strength) -- (bulk); \path [line] (dough_strength) -- (bulk);

View File

@@ -1,6 +1,6 @@
\tikzstyle{every picture}+=[font=\footnotesize\sffamily] \tikzstyle{every picture}+=[font=\footnotesize\sffamily]
\usetikzlibrary{calc, shapes, arrows, decorations.pathreplacing, calligraphy, \usetikzlibrary{calc, shapes, arrows, decorations.pathreplacing, calligraphy,
calligraphy} positioning}
\tikzstyle{decision} = [diamond, draw=codeblack, fill=codeblack, text=white, \tikzstyle{decision} = [diamond, draw=codeblack, fill=codeblack, text=white,
text width=4.5em, text badly centered, node distance=3cm, inner sep=0pt, text width=4.5em, text badly centered, node distance=3cm, inner sep=0pt,
line width=2mm] line width=2mm]

View File

@@ -21,17 +21,6 @@ addition to our planet, so young that we made our first appearance on
the evening of December~31. It seems that humans managed to arrive just the evening of December~31. It seems that humans managed to arrive just
in time to join the celebration at the end of the year. in time to join the celebration at the end of the year.
The story of sourdough bread begins in ancient oceans. These oceans were the
birthplace of all Earth's life. To better envision the vast history of
our planet lets create a timeline of 1~year. On this scale, January~1 signifies Earth's
formation 4.54~billion years ago. Midnight on December~31 is our present.
Each day represents roughly 12~million years. This technique simplifies the
complexity of time but also renders the extraordinary expanse of our planet's
history into a more graspable frame. We humans are in fact a recent addition
to our planet, so young that we made appearance on the evening of December~31.
It seems that humans managed to arrive just in time to join
the celebration at year's end.
On March~25, the oceans birthed the first single-celled bacteria. In these On March~25, the oceans birthed the first single-celled bacteria. In these
waters, another single-celled life form, \emph{archaea}, also thrived. These waters, another single-celled life form, \emph{archaea}, also thrived. These
organisms inhabit extreme environments, from boiling vents to icy waters. organisms inhabit extreme environments, from boiling vents to icy waters.
@@ -44,10 +33,11 @@ organisms inhabit extreme environments, from boiling vents to icy waters.
divided into months, and extending to the present day, divided into months, and extending to the present day,
marked at midnight. This visualization shows the pivotal steps marked at midnight. This visualization shows the pivotal steps
of life and sourdough on earth.}% of life and sourdough on earth.}%
\label{fig:planet-timeline}
\end{center} \end{center}
\end{figure} \end{figure}
Whoever comes first first, bacteria or archaea, remains debated. For three Whoever comes first, bacteria or archaea, remains debated. For three
months (or approximately 1.1~billion years), these life forms dominated months (or approximately 1.1~billion years), these life forms dominated
the oceans. Then, on June~25 in an highly unlikely event, an archaeon consumed a bacterium. the oceans. Then, on June~25 in an highly unlikely event, an archaeon consumed a bacterium.
Instead of digesting it, they formed a symbiotic relationship. This led to the Instead of digesting it, they formed a symbiotic relationship. This led to the
@@ -59,9 +49,9 @@ On October~4, bacteria first colonized land. By October~15, the
first aquatic fungi appeared. They adapted and, by November~24, had colonized first aquatic fungi appeared. They adapted and, by November~24, had colonized
land. land.
By December~3rd, yeasts emerged on land. This laid groundwork for bread-making. By December~3, yeasts emerged on land. This laid groundwork for bread-making.
Jump 140~million years to December~14, and dinosaurs arose. Just a couple Jump 140~million years to December~14, and dinosaurs arose. Just a couple
of days after their appearance on December~17 the super continent pangea of days after their appearance on December~17 the super continent Pangea
started to rift apart, reshaping the continents into their current form. started to rift apart, reshaping the continents into their current form.
The dinosaurs reigned until December~29 when they faced extinction. The dinosaurs reigned until December~29 when they faced extinction.
Another 25~million years later, or our timeline's 2~days after the dinosaur Another 25~million years later, or our timeline's 2~days after the dinosaur
@@ -72,12 +62,22 @@ revolution was unfolding. By \num{12000}~BC, just 5 seconds before our metaphor
midnight, the first sourdough breads were being baked in ancient Jordan. A blink of midnight, the first sourdough breads were being baked in ancient Jordan. A blink of
an eye later, or 4~seconds in our time compression, Pasteur's groundbreaking work an eye later, or 4~seconds in our time compression, Pasteur's groundbreaking work
with yeasts set the stage for modern bread-making. From the moment this book with yeasts set the stage for modern bread-making. From the moment this book
began to take shape to your current reading, only milliseconds have ticked by~\cite{Yong_2017}. began to take shape to your current reading, only milliseconds have ticked
by~\cite{Yong+2017}.
Now delving deeper into the realm of sourdough, it can likely be traced to aforementioned Now delving deeper into the realm of sourdough, it can likely be traced to aforementioned
Ancient Jordan~\cite{jordan+bread}. Looking at the earth's timeline sourdough Ancient Jordan~\cite{jordan+bread}. Looking at the earth's timeline sourdough
bread can be considered a very recent invention. bread can be considered a very recent invention.
\begin{figure}[!htb]
\begin{center}
\input{figures/fig-sourdough-history-timeline.tex}
\caption[Sourdough history timeline]{Timeline of significant discoveries and
events leading to modern sourdough bread.}%
\label{fig:sourdough-timeline}
\end{center}
\end{figure}
The exact origins of fermented The exact origins of fermented
bread are, however, unknown. One of the most ancient preserved bread are, however, unknown. One of the most ancient preserved
sourdough breads has been excavated in Switzerland~\cite{switzerland+bread}. sourdough breads has been excavated in Switzerland~\cite{switzerland+bread}.
@@ -101,10 +101,11 @@ Little did the people back then know that tiny microorganisms
were the reason the bread was better. It is not clear when were the reason the bread was better. It is not clear when
they started using a bit of the dough from the previous they started using a bit of the dough from the previous
day for the next batch of dough. But by doing so, sourdough day for the next batch of dough. But by doing so, sourdough
bread making was born: Wild yeast in the flour and in the air bread making---as we know it today---was born: Wild yeast
plus bacteria start to decompose the flour-water mixture, also in the flour and in the air, with bacteria
known as your dough. The yeast makes the dough fluffy, and starting to decompose the flour-water mixture.
the bacteria primarily creates acidity. The different The yeast makes the dough fluffy,
and the bacteria primarily creates acidity. The different
microorganisms work in a symbiotic relationship. Humans microorganisms work in a symbiotic relationship. Humans
appreciated the enhanced airy structure and slight acidity appreciated the enhanced airy structure and slight acidity
of the dough. Furthermore, the shelf life of such bread of the dough. Furthermore, the shelf life of such bread
@@ -113,18 +114,18 @@ was extended due to the increased acidity.
Quickly, similar processes were discovered when brewing beer Quickly, similar processes were discovered when brewing beer
or making wine. A small tiny batch of the previous production or making wine. A small tiny batch of the previous production
would be used for the next production. In this way, humans created would be used for the next production. In this way, humans created
modern bread yeasts, wine yeasts, and beer yeasts. Only in 1680, modern bread yeasts, wine yeasts, and beer yeasts~\cite{egypt+beer}.
the scientist Anton van~Leeuwenhoek first studied yeast microorganisms
under a microscope. Over time with each batch, the yeasts and bacteria Over time with each batch, the yeasts and bacteria
would become better at consuming whatever they were thrown at. would become better at consuming whatever they were thrown at.
By feeding your sourdough starter, you are selectively breeding By feeding your sourdough starter, you are selectively breeding
microorganisms that are good at eating your flour. With microorganisms that are good at eating your flour. With
each iteration, your sourdough knows how to better ferment the flour each iteration, your sourdough knows how to better ferment the flour
at hand. This is also the reason why more mature sourdough starters sometimes at hand. This is also the reason\footnote{It is crazy if you think about it.
tend to leaven doughs faster~\cite{review+of+sourdough+starters}. It is crazy if you People have been using this process despite not knowing what was going on for
think about it. People have been using this process despite not thousands of years!} why more mature sourdough starters sometimes tend to
knowing what was actually going on for thousands of years! The leaven doughs faster~\cite{review+of+sourdough+starters}. The sourdough in
sourdough in itself is a symbiotic relationship. But the sourdough itself is a symbiotic relationship, but the sourdough
also adapted to humans and formed a symbiotic relationship with us. also adapted to humans and formed a symbiotic relationship with us.
For food and water, we are rewarded with delicious bread. In exchange, For food and water, we are rewarded with delicious bread. In exchange,
we shelter and protect the sourdough. Spores from the starter we shelter and protect the sourdough. Spores from the starter
@@ -132,39 +133,122 @@ are spread through aerial contamination or insects like fruit flies.
This allows the sourdough starter to spread its spores even This allows the sourdough starter to spread its spores even
further all around the world. further all around the world.
Brewers would start to experiment with utilizing the muddy leftovers Evidence suggests early grain grinding in northern Australia around
of the beer fermentation to start making doughs. They would notice \num{60000}~BC, notably at the Madjedbebe rock shelter in Arnhem
Land~\cite{aboriginal+grinding+stones}. However, a more significant
advancement occurred later, as documented by the ancient Greek geographer
Strabo in \num{71}~BC\@. Strabo's writings described the first water-powered
stone mill, known as a \emph{gristmill}. These mills advanced flour production
from a few kilograms up to several metric tons per day~\cite{history+mills}.
These early mills featured horizontal paddle wheels, eventually termed
\emph{Norse wheels} due to their prevalence in Scandinavia. The paddle wheels
connected to a shaft, which, in turn, linked to the central runner stone for
grinding. Water flow propelled the paddle wheels, transferring the grinding
force to the stationary \emph{bed}, typically a stone of similar size and
shape. This design was straightforward, avoiding the need for gears. However,
it had a limitation: the stone's rotation speed relied on water volume and
flow rate, making it most suitable for regions with fast-flowing streams,
often found in mountainous areas~\cite{mills+scandinavia}.
In the year \num{1680}, a remarkable scientist by the name of
Antonie~van~Leeuwenhoek introduced a groundbreaking innovation that would
forever alter our understanding of the microscopic world and ultimately bread
making. Van~Leeuwenhoek, a master of lens craftsmanship, possessed an
insatiable fascination with realms invisible to the naked eye. His pioneering
work birthed the first modern microscope. What set Van~Leeuwenhoek apart was
the exceptional quality of his lenses, capable of magnifying tiny
microorganisms by an astounding factor of \num{270}. Driven by an unrelenting
curiosity to unveil the unseen, he embarked on a journey of exploration. He
scrutinized flies, examined lice-infested hair, and ultimately turned his gaze
toward the tranquil waters of a small lake near Delft.
In this serene aquatic habitat, he made astonishing observations, discovering
algae and minuscule, dancing creatures hitherto hidden from human perception.
Eager to share his revelatory findings with the scientific community,
Van~Leeuwenhoek faced skepticism, as it was difficult to fathom that someone
had witnessed thousands of diminutive, dancing entities—entities so tiny that
they eluded the human eye.
Undeterred by skepticism, he continued his relentless pursuit of the unseen,
directing his lens towards a brewer's beer sludge. In this obscure medium,
Van~Leeuwenhoek made history by becoming the first human to lay eyes upon
bacteria and yeast, unraveling a previously concealed world that would
revolutionize our understanding of microbiology~\cite{Yong+2017+Leeuwen}.
At the same time brewers would start to experiment with utilizing the muddy
leftovers of the beer fermentation to start making doughs. They would notice
that the resulting bread doughs were becoming fluffy and compared that the resulting bread doughs were becoming fluffy and compared
to the sourdough process would lack the acidity in the final product. to the sourdough process would lack the acidity in the final product.
A popular example is shown in a report from 1875. Eben Norton Horsford A popular example is shown in a report from \num{1875}. Eben Norton Horsford
wrote about the famous \emph{Kaiser Semmeln} (Emperor's bread rolls). wrote about the famous \emph{Kaiser Semmeln} (Emperor's bread rolls).
These are essentially bread rolls made with brewer's yeast instead These are essentially bread rolls made with brewer's yeast instead
of the sourdough leavening agent. As the process is more expensive, of the sourdough leavening agent. As the process is more expensive,
bread rolls like these were ultimately consumed by the noble people bread rolls like these were ultimately consumed by the noble people
in Vienna~\cite{vienna+breadrolls}. in Vienna~\cite{vienna+breadrolls}.
As industrialisation began the first steam-powered grain mill was developed by
Oliver Evans in \num{1785}. Evans' design incorporated several innovations,
including automated machinery for various milling processes, making it more
efficient than traditional water or animal-powered mills. His steam-powered
mill marked a significant advancement in industrial technology for bread
making~\cite{evans+mill}.
\begin{figure}[ht] \begin{figure}[ht]
\includegraphics[width=\textwidth]{sourdough-stove} \includegraphics[width=\textwidth]{sourdough-stove}
\caption{A bread made over the stove without an oven.}% \caption{A bread made over the stove without an oven.}%
\label{sourdough-stove} \label{sourdough-stove}
\end{figure} \end{figure}
Only in 1857, the French microbiologist Louis Pasteur discovered The biggest advancement of industrial breadmaking happened in \num{1857}.
The French microbiologist Louis Pasteur discovered
the process of alcoholic fermentation. He would prove that the process of alcoholic fermentation. He would prove that
yeast microorganisms are the reason for alcoholic fermentation yeast microorganisms are the reason for alcoholic fermentation
and not other chemical catalysts. What would then start is and not other chemical catalysts. He continued with his research and
what I~describe as the 150 lost years of bread making. In 1879 was the first person to isolate and grow pure yeast strains.
the first machines and centrifuges were developed to centrifuge Soon later in \num{1868} in the Fleischmann brothers Charles
pure yeast. This yeast would be extracted from batches of sourdough. and Maximilian were the first to patent pure yeast strains
for bread making. The yeasts offered
were isolated from batches of sourdough. By \num{1879} the machinery was built
to multiply the yeast in large centrifuges~\cite{fleischmann+history}.
The pure yeast would prove to be excellent and turbocharged The pure yeast would prove to be excellent and turbocharged
at leavening bread doughs. What would previously take 10~hours at leavening bread doughs. What would previously take 10~hours
to leaven a bread dough could now be done within 1~hour. to leaven a bread dough could now be done within 1~hour.
The process became much more efficient. During World~War~II The process became much more efficient. What ultimately made making large
the first packaged dry yeast was developed. This would ultimately batches of dough possible, was the invention of the electrical kneader. Rufus
allow bakeries and home bakers to make bread much faster. Eastman, an American inventor, is often credited with an important advancement
Thanks to pure yeast, building bread making machines was in mixer technology. In \num{1885}, he received a patent for an electric mixer
possible. Provided you maintain the same temperature, with a mechanical hand-crank mechanism. This device was not as advanced or as
your yeast would always ferment exactly the same way. widely adopted as later electric mixers, but it was an early attempt to
mechanize mixing and kneading processes in the kitchen using electricity.
Eastman's invention represented an important step in the development of
electric mixers, but it wasn't as sophisticated or popular as later models
like the KitchenAid mixer. The KitchenAid mixer, introduced in \num{1919}, is
often recognized as one of the first widely successful electric mixers and
played a significant role in revolutionizing kitchen appliances for home
cooks~\cite{first+mixer}~\cite{kitchenaid+history}.
During World~War~II the first packaged dry yeast was developed. This would
ultimately allow bakeries and home bakers to make bread much faster and more
consistently. Thanks to pure yeast, building industrial bread making machines
was now possible. Provided you maintain the same temperature, same flour and
yeast strains fermentation became precisely reproducible. This ultimately lead
to the development of giga bakeries and flour blenders. The bakeries demanded
the same flour from year to year to bake bread in their machines. For this
reason, none of the supermarket flour you buy today is single origin. It is
always blended to achieve exactly the same product throughout the years.
Modern wheat, specifically the high-yielding and disease-resistant varieties
commonly grown today, began to be developed in the mid-20th century. This
period is often referred to as the \emph{Green Revolution.}
One of the key figures in this development was American scientist Norman
Borlaug, who is credited with breeding high-yield wheat varieties,
particularly dwarf wheat varieties, that were resistant to diseases and could
thrive in various environmental conditions. His work, which started in the
1940s and continued through the \num{1960}s, played a crucial role in
increasing wheat production worldwide and alleviating food
shortages~\cite{green+revolution}.
As fermentation As fermentation
times sped up, the taste of the final bread would deteriorate. times sped up, the taste of the final bread would deteriorate.
@@ -178,7 +262,7 @@ of true nerds would continue making bread with sourdough.
Suddenly people started to talk more often about celiac disease Suddenly people started to talk more often about celiac disease
and the role of gluten. The disease isn't new; it has first and the role of gluten. The disease isn't new; it has first
been described in 250 AD~\cite{coeliac+disease}. People been described in \num{250}~AD~\cite{coeliac+disease}. People
would note how modern bread has much more gluten compared would note how modern bread has much more gluten compared
to ancient bread. The bread in ancient times probably was much flatter. to ancient bread. The bread in ancient times probably was much flatter.
The grains over time have been bred more and more towards containing a higher The grains over time have been bred more and more towards containing a higher
@@ -218,8 +302,9 @@ During the California Gold Rush, French bakers brought the sourdough
culture to Northern America. A popular bread became the culture to Northern America. A popular bread became the
San Francisco sourdough. It's characterized by its unique San Francisco sourdough. It's characterized by its unique
tang (which was previously common for every bread). It tang (which was previously common for every bread). It
however remained more of a niche food. What really expedited however remained more of a niche food while industrial bread
the comeback of sourdough was the 2020 COVID-19 pandemic. was on the rise. What really expedited
the comeback of sourdough was the \num{2020} COVID-19 pandemic.
Flour and yeast became scarce in the supermarkets. While Flour and yeast became scarce in the supermarkets. While
flour returned yeast couldn't be found. People started flour returned yeast couldn't be found. People started
to look for alternatives and rediscovered the ancient to look for alternatives and rediscovered the ancient

View File

@@ -1,7 +1,7 @@
# Macros for commands # Macros for commands
LATEX := latexmk -cd -pdflua -lualatex="lualatex -interaction=nonstopmode" -synctex=1 -use-make LATEX := latexmk -cd -pdflua -lualatex="lualatex -interaction=nonstopmode" -synctex=1 -use-make
EBOOK := tex4ebook --lua -d epub -f epub -c tex4ebook.cfg EBOOK := tex4ebook --lua -d epub -f epub -c tex4ebook.cfg
WEBSITE := make4ht --lua -c website.cfg -a debug -uf html5+tidy+common_domfilters+dvisvgm_hashes WEBSITE := make4ht --lua -c website.cfg -a debug -uf html5+tidy+common_domfilters
CLEAN := latexmk -cd -lualatex -c -use-make CLEAN := latexmk -cd -lualatex -c -use-make
CHECK_1 := lacheck CHECK_1 := lacheck
CHECK_2 := chktex CHECK_2 := chktex
@@ -302,6 +302,8 @@ show_tools_version: # Show version of tools used on the build machine
@echo "" @echo ""
- tidy -version - tidy -version
@echo "" @echo ""
- dvisvgm --version
@echo ""
- lacheck --version - lacheck --version
@echo "" @echo ""
- chktex --version - chktex --version

View File

@@ -98,6 +98,75 @@
howpublished = {\url{https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6077754/}} howpublished = {\url{https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6077754/}}
} }
@article{fleischmann+history,
author = {Fleischmann History},
title = {History of Fleischmann's},
howpublished = {\url{https://www.fleischmannsyeast.com/our-history/}},
note = {Accessed: 2023-12-04}
}
@article{evans+mill,
author = {Jeremy Norman},
title = {Oliver Evans Builds the First Automated Flour Mill: Origins of the Integrated and Automated Factory},
howpublished = {\url{https://www.historyofinformation.com/detail.php?entryid=3567}},
note = {Accessed: 2023-12-04}
}
@article{first+mixer,
author = {United States Patent office},
title = {Eastman Mixer for cream, eggs and liquors},
howpublished = {\url{https://patents.google.com/patent/US330829}},
note = {Accessed: 2023-12-04}
}
@article{egypt+beer,
author = {Smithsonian Magazine},
title = {Worlds Oldest Industrial-Scale Brewery Found in Egypt},
howpublished = {\url{https://www.smithsonianmag.com/smart-news/worlds-oldest-industrial-scale-brewery-found-egypt-180977026/}},
note = {Accessed: 2023-12-04}
}
@article{kitchenaid+history,
author = {KitchenAid},
title = {KitchenAid Brand History},
howpublished = {\url{https://www.kitchenaid.com/100year/history.html}},
note = {Accessed: 2023-12-04}
}
@article{aboriginal+grinding+stones,
author = {First Peoples - State Relations},
title = {Fact sheet: Aboriginal grinding stones},
howpublished = {\url{https://www.firstpeoplesrelations.vic.gov.au/fact-sheet-aboriginal-grinding-stones}},
note = {Accessed: 2023-12-04}
}
@book{history+mills,
title = {Archaeological Evidence for Early Water-Mills. An Interim Report},
journal = {History of Technology},
number = {10},
author = {Wikander, Örjan},
year = {1985},
pages = {151--179}
}
@book{mills+scandinavia,
title = {Waterwheels and Windmills: Five machines that changed the world},
author = {Mark, Denny},
year = {2007},
pages = {36}
}
@article{green+revolution,
author = {Borlaug, Norman},
title = {Contributions of conventional plant breeding to food production},
journal = {Science},
volume = {219},
number = {4585},
pages = {689-693},
year = {1983},
doi = {10.1126/science.219.4585.689}
}
@article{switzerland+bread, @article{switzerland+bread,
author = {Pasquale Catzeddu}, author = {Pasquale Catzeddu},
title = {Flour and Breads and their Fortification in Health and Disease Prevention}, title = {Flour and Breads and their Fortification in Health and Disease Prevention},
@@ -105,7 +174,7 @@
year = {2011} year = {2011}
} }
@book{Yong_2017, @book{Yong+2017,
place = {London}, place = {London},
title = {I contain multitudes: The microbes within US and a grander view of life}, title = {I contain multitudes: The microbes within US and a grander view of life},
publisher = {Vintage}, publisher = {Vintage},
@@ -114,6 +183,15 @@
pages = {5--9} pages = {5--9}
} }
@book{Yong+2017+Leeuwen,
place = {London},
title = {I contain multitudes: The microbes within US and a grander view of life},
publisher = {Vintage},
author = {Yong, Ed},
year = {2017},
pages = {39}
}
@article{egyptian+bread, @article{egyptian+bread,
title = {Investigation of ancient Egyptian baking and brewing methods by correlative microscopy}, title = {Investigation of ancient Egyptian baking and brewing methods by correlative microscopy},
volume = {273}, volume = {273},

View File

@@ -191,12 +191,12 @@ and I~use \qty{50}{\gram} of starter, then I~would proceed and only use \qty{550
water. water.
This type of starter is also an excellent mold combatant. As you are removing This type of starter is also an excellent mold combatant. As you are removing
oxygen from the equation, aerobic mold can not properly grow. If your starter oxygen from the equation, aerobic mold cannot properly grow. If your starter
has a mold problem then the liquid conversion could be the remedy. Take a has a mold problem then the liquid conversion could be the remedy. Take a
piece of your starter where you suspect mold growth. Apply the conversion piece of your starter where you suspect mold growth. Apply the conversion
as mentioned before. The mold will likely sporulate as it runs out of food. as mentioned before. The mold will likely sporulate as it runs out of food.
With each new feeding you are reducing the mold spores. The spores can no With each new feeding you are reducing the mold spores. The spores can no
longer reactivate as they can not do so in the anaerobic conditions. longer reactivate as they cannot do so in the anaerobic conditions.
The liquid on top of your starter is an excellent resource that you could use The liquid on top of your starter is an excellent resource that you could use
to make sauces. If you feel you would like to add a little bit of acidity, to make sauces. If you feel you would like to add a little bit of acidity,

View File

@@ -62,18 +62,22 @@ main.main-content,main.titlepage,div.footnotes{
padding:1rem; padding:1rem;
} }
.sectionHead a.permalink { .permalink {
opacity: 0.5; opacity: 0.5;
text-decoration: none; text-decoration: none;
font-size: 0.75rem; font-size: 0.75rem;
vertical-align: top;
line-height: 0.8rem; line-height: 0.8rem;
margin-left: 0.25rem; margin-left: 0.25rem;
padding-top: 0.2rem;
color: black; color: black;
display: inline-block; display: inline-block;
} }
.sectionHead, .subsectionHead {
display: flex;
align-items: center;
align-content: center;
}
p.indent, p.noindent{ p.indent, p.noindent{
text-indent: 0; text-indent: 0;
text-align: justify; text-align: justify;

View File

@@ -1,10 +1,10 @@
%TODO: last line is not great %TODO: Alignement is not great
-\begin{tabular}{lll} \begin{tabular}{@{}lll@{}}
\toprule \toprule
& \textbf{Flat breads} & \textbf{Pancakes} \\ \midrule & \textbf{Flat breads} & \textbf{Pancakes} \\ \midrule
\textbf{Flour} & 100g & 100g \\ Flour & \qty{100}{g} & \qty{100}{g} \\
\textbf{Water} & up to 100g (100\%) & 300g (300\%) \\ Water & up to \qty{100}{g} (\qty{100}{\percent}) & \qty{300}{g} (\qty{300}{\percent}) \\
\textbf{Sourdough starter} & 5--20g (5--20\%) & 5--20g (5--20\%) \\ Sourdough starter & 5--\qty{20}{g} (5--\qty{20}{\percent}) & 5--\qty{20}{g} (5--\qty{20}{\percent}) \\
\textbf{Salt} & 2g (2\%) & 2g (2\%) \\ Salt & \qty{2}{g} (\qty{2}{\percent}) & \qty{2}{g} (\qty{2}{\percent}) \\
\textbf{Bake when?} & Dough increased 50 percent in size & Bubbles visible on surface \\ \bottomrule Bake when? & Dough increased \qty{50}{\percent} in size & Bubbles visible on surface \\ \bottomrule
\end{tabular} \end{tabular}

View File

@@ -1,9 +1,10 @@
% TODO \begin{tabular}{@{}llll@{}}
\begin{tabular}{@{}>{\bfseries}p{0.17\textwidth}ccc@{}}
\toprule \toprule
& \thead{Flatbread} & \thead{Loaf pan bread} & \thead{Free standing bread} \\ \midrule & \multicolumn{3}{c}{\textbf{Type of bread}}\\
Cooking method & Fire, pan, barbecue & Oven & Oven \\ \cmidrule(lll){2-4}
Working time (min.) & 3 & 5 & 60 \\ & \textbf{Flat} & \textbf{Loaf pan} & \textbf{Free standing} \\ \midrule
Cooking method & Pan, fire, barbecue & Oven & Oven \\
Working time & 3~min. & 5~min. & 60~min. \\
Flour types & All & All & Gluten flours \\ Flour types & All & All & Gluten flours \\
Difficulty & Very easy & Easy & Difficult \\ Difficulty & Very easy & Easy & Difficult \\
Cost & Low & Medium & High \\ \bottomrule Cost & Low & Medium & High \\ \bottomrule

View File

@@ -1,8 +1,10 @@
\begin{tabular}{@{}crr@{}} \begin{tabular}{@{}c
S[table-format=2.0]
S[table-format=2.1]@{}}
\toprule \toprule
&\multicolumn{2}{c}{\textbf{Amount (\%) of a starter}}\\ &\multicolumn{2}{c}{\textbf{Amount (\%) for a starter}}\\
\cmidrule(rl){2-3} \cmidrule(rl){2-3}
\thead{°C / °F} & \thead{Recently fed} & \thead{Starving}\\ \midrule \textbf{°C / °F} & \textbf{Recently fed} & \textbf{Starving}\\ \midrule
30 / 86 & 5 & 2.5 \\ 30 / 86 & 5 & 2.5 \\
25 / 77 & 10 & 5 \\ 25 / 77 & 10 & 5 \\
20 / 68 & 15 & 10 \\ \bottomrule 20 / 68 & 15 & 10 \\ \bottomrule

View File

@@ -18,14 +18,14 @@ making this type of bread requires a lot more effort, patience,
and technique than other types of bread. You have to perfectly and technique than other types of bread. You have to perfectly
balance the fermentation process. You cannot ferment for too balance the fermentation process. You cannot ferment for too
short and also not for too long. The techniques you need to short and also not for too long. The techniques you need to
learn to require a bit more skill. It took me several attempts learn also require a bit more skill. It took me several attempts
to get this right. One of the challenges I~faced was that to get this right. One of the challenges I~faced was that
I~had the wrong flour. I~didn't properly know how to use my oven. I~had the wrong flour. I~didn't properly know how to use my oven.
When should I~stop the fermentation? There is a lot of information When should I~stop the fermentation? There is a lot of information
out there. I~dug through most of it and have tried almost everything. out there. I~dug through most of it and have tried almost everything.
In many cases the information was wrong; in other cases, I~found another In many cases the information was wrong; in other cases, I~found another
valuable puzzle piece. Aggregating all this valuable puzzle piece. Aggregating all this
information was one of my main motivations to start The Bread Code. information was one of my main motivations to start \texttt{The Bread Code}.
My key learning was that there is no recipe that My key learning was that there is no recipe that
you can blindly follow. You will always have to adapt the recipe you can blindly follow. You will always have to adapt the recipe
to your locally available tools and environment. to your locally available tools and environment.
@@ -209,7 +209,8 @@ Find below an example recipe for 1 loaf including baker's math calculation:
\begin{itemize} \begin{itemize}
\item \qty{400}{\gram} of bread flour \item \qty{400}{\gram} of bread flour
\item \qty{100}{\gram} of whole-wheat flour \item \qty{100}{\gram} of whole-wheat flour
\item \textbf{\qty{500}{\gram} of flour in total} % Manual unit so we can use emphasis
\item \emph{500~g of flour in total}
\item \qtyrange{300}{450}{\gram} of room temperature water (\qty{60}{\percent} up to \qty{90}{\percent}). More on \item \qtyrange{300}{450}{\gram} of room temperature water (\qty{60}{\percent} up to \qty{90}{\percent}). More on
this topic in the next chapter. this topic in the next chapter.
\item \qty{50}{\gram} of stiff sourdough starter (\qty{10}{\percent}) \item \qty{50}{\gram} of stiff sourdough starter (\qty{10}{\percent})
@@ -223,7 +224,8 @@ recipe would look like this:
\begin{itemize} \begin{itemize}
\item \qty{1800}{\gram} of bread flour \item \qty{1800}{\gram} of bread flour
\item \qty{200}{\gram} of whole-wheat flour \item \qty{200}{\gram} of whole-wheat flour
\item \textbf{\qty{2000}{\gram} of flour, equaling 4 loaves} % Manual unit so we can use emphasis again
\item \emph{2000 g of flour}, equaling 4 loaves
\item \qty{1200}{\gram} up to \qty{1800}{\gram} of room temperature water (60 to \qty{90}{\percent}) \item \qty{1200}{\gram} up to \qty{1800}{\gram} of room temperature water (60 to \qty{90}{\percent})
\item \qty{200}{\gram} of stiff sourdough starter (\qty{10}{\percent}) \item \qty{200}{\gram} of stiff sourdough starter (\qty{10}{\percent})
\item \qty{40}{\gram} of salt (\qty{2}{\percent}) \item \qty{40}{\gram} of salt (\qty{2}{\percent})
@@ -231,7 +233,7 @@ recipe would look like this:
This is the beauty of baker's math. Simply recalculate the percentages, and you This is the beauty of baker's math. Simply recalculate the percentages, and you
are good to go. If you are unsure about how this works, please check out the are good to go. If you are unsure about how this works, please check out the
full Chapter~\ref{section:bakers-math} which looks at the topic in detail. full Section~\ref{section:bakers-math} which looks at the topic in detail.
\section{Hydration} \section{Hydration}
@@ -390,8 +392,8 @@ difficulty.
\section{How much starter?} \section{How much starter?}
Most bakers use around \qty{20}{\percent} sourdough starter based on the Most bakers use around \qty{20}{\percent} sourdough starter based on the
flour weight. I~recommend going much lower, flour weight. I~recommend going much lower, to around
to around 5 to \qty{10}{\percent}. \qtyrange{5}{10}{\percent}.
By adjusting the amount of pre-ferment you can influence the time your dough By adjusting the amount of pre-ferment you can influence the time your dough
requires in the bulk fermentation stage. The more starter you use, the faster requires in the bulk fermentation stage. The more starter you use, the faster
@@ -787,7 +789,7 @@ this is not an option for an inexperienced baker. As
you make more and more dough, you will be able to judge you make more and more dough, you will be able to judge
the dough's state by touching it. the dough's state by touching it.
My go-to method for beginners is to use an \textbf{Aliquot jar}. My go-to method for beginners is to use an \emph{Aliquot jar}.
The aliquot is a sample that you extract from your dough. The The aliquot is a sample that you extract from your dough. The
sample is extracted after creating the initial dough strength. sample is extracted after creating the initial dough strength.
You monitor the aliquot's size increase to judge the You monitor the aliquot's size increase to judge the
@@ -1610,8 +1612,8 @@ banneton should now be facing you.
\label{fig:artistic-scoring} \label{fig:artistic-scoring}
\end{figure} \end{figure}
The scoring cut for done at a \qty{45}{\angle} angle relative to the dough's The scoring cut for done at a \ang{45}~angle relative to the dough's
surface slightly off the dough's center. With the \qty{45}{\angle} angle cut surface slightly off the dough's center. With the \ang{45}~angle cut
the overlaying side will rise more in the oven than the other side. the overlaying side will rise more in the oven than the other side.
This way you will achieve a so-called \emph{ear} on the final bread. This way you will achieve a so-called \emph{ear} on the final bread.
The ear is a thin crisp edge that offers intriguing texture The ear is a thin crisp edge that offers intriguing texture
@@ -1621,7 +1623,7 @@ a good loaf into a great loaf.
\begin{figure}[htb!] \begin{figure}[htb!]
\includegraphics[width=\textwidth]{bread-scoring-angle} \includegraphics[width=\textwidth]{bread-scoring-angle}
\caption[Scoring angle]{The \qty{45}{\angle} angle at which you score the \caption[Scoring angle]{The \ang{45}~angle at which you score the
dough is relative to the surface of the dough. When scoring more towards dough is relative to the surface of the dough. When scoring more towards
the side, you have to adjust the angle to achieve the ear on your the side, you have to adjust the angle to achieve the ear on your
bread.}% bread.}%

View File

@@ -1,7 +1,7 @@
.DEFAULT_GOAL := build_pdf .DEFAULT_GOAL := build_pdf
DOCKER_IMAGE := ghcr.io/hendricius/the-sourdough-framework DOCKER_IMAGE := ghcr.io/hendricius/the-sourdough-framework
DOCKER_CMD := docker run -it -v $(PWD):/opt/repo $(DOCKER_IMAGE) /bin/bash -c DOCKER_CMD := docker run -it -v $(PWD):/opt/repo --platform linux/x86_64 $(DOCKER_IMAGE) /bin/bash -c
.PHONY: bake build_pdf build_docker_image push_docker_image validate website .PHONY: bake build_pdf build_docker_image push_docker_image validate website
.PHONY: print_os_version start_shell printvars show_tools_version mrproper .PHONY: print_os_version start_shell printvars show_tools_version mrproper
@@ -14,10 +14,11 @@ push_docker_image: build_docker_image
docker push $(DOCKER_IMAGE):latest docker push $(DOCKER_IMAGE):latest
# Books/website # Books/website
build_serif_pdf:
$(DOCKER_CMD) "cd /opt/repo/book && make build_serif_pdf"
# Quicker run for each commit, shall catch most problems build_ebook:
validate: $(DOCKER_CMD) "cd /opt/repo/book && make build_ebook"
$(DOCKER_CMD) "cd /opt/repo/book && make -j build_serif_pdf build_ebook"
build_pdf: build_pdf:
$(DOCKER_CMD) "cd /opt/repo/book && make" $(DOCKER_CMD) "cd /opt/repo/book && make"

View File

@@ -8,14 +8,4 @@ document.addEventListener('DOMContentLoaded', function() {
}); });
} }
}); });
// Add permalinks to headers
var heads = document.querySelectorAll('.sectionHead');
heads.forEach(function (head) {
let permalink = document.createElement("a");
permalink.href = '#' + head.id;
permalink.classList.add('permalink');
permalink.append('🔗');
head.append(permalink);
});
}); });

View File

@@ -5,6 +5,8 @@ require 'nokogiri'
# several optimisations on the HTML. Nokogiri is used to facilitate the # several optimisations on the HTML. Nokogiri is used to facilitate the
# modifications. # modifications.
class InvalidWebsiteFormat < StandardError; end
class ModifyBuild class ModifyBuild
HOST = "https://www.the-sourdough-framework.com".freeze HOST = "https://www.the-sourdough-framework.com".freeze
@@ -15,6 +17,8 @@ class ModifyBuild
def build def build
build_latex_html build_latex_html
create_sitemap create_sitemap
rescue InvalidWebsiteFormat => e
raise e
end end
private private
@@ -27,7 +31,7 @@ class ModifyBuild
html_file_name = fn.split("/")[-1] html_file_name = fn.split("/")[-1]
content += "#{HOST}/#{html_file_name}\n" content += "#{HOST}/#{html_file_name}\n"
end end
File.open("#{build_dir}/sitemap.txt", 'w') { |file| file.write(content) } File.open("#{build_dir}/sitemap.txt", 'w:UTF-8') { |file| file.write(content) }
end end
def build_latex_html def build_latex_html
@@ -41,7 +45,8 @@ class ModifyBuild
end end
def modify_file(filename) def modify_file(filename)
orig_text = File.read(filename) orig_text = File.read(filename, encoding: "UTF-8")
validate_file(orig_text)
text = fix_double_slashes(orig_text) text = fix_double_slashes(orig_text)
text = fix_navigation_bar(text) text = fix_navigation_bar(text)
text = fix_titles(text) text = fix_titles(text)
@@ -58,9 +63,10 @@ class ModifyBuild
text = add_text_to_coverpage(text, extract_file_from_path(filename)) text = add_text_to_coverpage(text, extract_file_from_path(filename))
text = fix_js_dependency_link(text) text = fix_js_dependency_link(text)
text = fix_list_of_tables_figures_duplicates(text) text = fix_list_of_tables_figures_duplicates(text)
text = add_anchors_to_headers(text)
text = fix_menus_list_figures_tables(text) if is_list_figures_tables?(filename) text = fix_menus_list_figures_tables(text) if is_list_figures_tables?(filename)
text = fix_list_of_figures_tables_display(text) if is_list_figures_tables?(filename) text = fix_list_of_figures_tables_display(text) if is_list_figures_tables?(filename)
File.open(filename, "w") {|file| file.puts text } File.open(filename, "w:UTF-8") {|file| file.puts text }
end end
def is_cover_page?(filename) def is_cover_page?(filename)
@@ -70,7 +76,7 @@ class ModifyBuild
end end
def is_list_figures_tables?(filename) def is_list_figures_tables?(filename)
["listfigurename.html", "listtablename.html", "listoflocname.html"].any? do |name| ["listfigurename.html", "listtablename.html", "listoflocname.html", "bibname.html"].any? do |name|
filename.include?(name) filename.include?(name)
end end
end end
@@ -100,6 +106,18 @@ class ModifyBuild
text.gsub(/\/\//, "/") text.gsub(/\/\//, "/")
end end
# Sometimes for whatever reason the make4ht input produces files that are
# improperly formatted. This validator will go through the files and do a
# couple of basic checks to see if the files are in the format we expect. If
# not an exception is caused.
def validate_file(text)
doc = build_doc(text)
stylesheets = doc.css("link[rel='stylesheet']").map{|attr| attr["href"] }
has_all_styles = %w(book.css style.css).all? { |required_stylesheet| stylesheets.include?(required_stylesheet) }
raise InvalidWebsiteFormat.new("No style tag style.css found in the website") unless has_all_styles
true
end
def fix_navigation_bar(text) def fix_navigation_bar(text)
doc = build_doc(text) doc = build_doc(text)
elements = [doc.search('.chapterToc'), doc.search('.sectionToc'), doc.search('.subsectionToc')].flatten elements = [doc.search('.chapterToc'), doc.search('.sectionToc'), doc.search('.subsectionToc')].flatten
@@ -227,7 +245,9 @@ class ModifyBuild
# Users are lost and can't easily access the root page of the book. This # Users are lost and can't easily access the root page of the book. This
# adds a home menu item. # adds a home menu item.
def add_home_link_to_menu(text) def add_home_link_to_menu(text)
doc = build_doc(text) # Remove duplicate menu entries first before building clean menu
doc = build_doc(remove_duplicate_entries_menu(text))
menu = doc.css(".menu-items")[0] menu = doc.css(".menu-items")[0]
return text if menu.nil? return text if menu.nil?
@@ -242,6 +262,21 @@ class ModifyBuild
<span class="link_text">List of Flowcharts</span> <span class="link_text">List of Flowcharts</span>
</a> </a>
</span> </span>
<span class="chapterToc">
<a href="listtablename.html">
<span class="link_text">List of Tables</span>
</a>
</span>
<span class="chapterToc">
<a href="listfigurename.html">
<span class="link_text">List of Figures</span>
</a>
</span>
<span class="chapterToc">
<a href="bibname.html">
<span class="link_text">Bibliography</span>
</a>
</span>
<span class="chapterToc"> <span class="chapterToc">
<a href="https://breadco.de/kofi"> <a href="https://breadco.de/kofi">
<span class="chapter_number">⭐️</span> <span class="chapter_number">⭐️</span>
@@ -259,6 +294,18 @@ class ModifyBuild
doc.to_html doc.to_html
end end
# Some of the menu links are added in the wrong order. Remove them since we
# later on add them in the structure that we want.
def remove_duplicate_entries_menu(text)
doc = build_doc(text)
remove = ["List of Tables", "List of Figures"]
selected_elements = doc.css(".menu-items .chapterToc > a").select do |el|
remove.include?(el.text)
end
selected_elements.each(&:remove)
doc.to_html
end
# Some of the links in the menu have an anchor. This makes clicking through # Some of the links in the menu have an anchor. This makes clicking through
# the menu frustrating as the browser jumps a lot on each request. Only do # the menu frustrating as the browser jumps a lot on each request. Only do
# this for the top level menu entries though. # this for the top level menu entries though.
@@ -370,15 +417,17 @@ class ModifyBuild
def mark_menu_as_selected_if_on_page(text, filename) def mark_menu_as_selected_if_on_page(text, filename)
doc = build_doc(text) doc = build_doc(text)
return doc.to_html
selected = doc.css(".menu-items .chapterToc > a").find do |el| selected = doc.css(".menu-items .chapterToc > a").find do |el|
el["href"] == "" el["href"] == ""
end end
# Special case for index page # Special case for index page
if ["index.html", "book.html"].include?(filename) #if ["index.html", "book.html"].include?(filename)
doc.css(".menu-items .chapterToc.home-link")[0].add_class("selected") # doc.css(".menu-items .chapterToc.home-link")[0].add_class("selected")
return doc.to_html # return doc.to_html
end #end
# Special case for the flowcharts page which is added by us to the menu. # Special case for the flowcharts page which is added by us to the menu.
# This needs to be done for future manually added pages too # This needs to be done for future manually added pages too
@@ -501,8 +550,10 @@ class ModifyBuild
<p class="noindent"> <p class="noindent">
EPUB: <a href="https://www.the-bread-code.io/book.epub">https://www.the-bread-code.io/book.epub</a><br> EPUB: <a href="https://www.the-bread-code.io/book.epub">https://www.the-bread-code.io/book.epub</a><br>
EPUB in Black & White, size optimized for screen readers : <a href="https://www.the-bread-code.io/bw-book.epub">https://www.the-bread-code.io/bw-book.epub</a><br>
</p> </p>
<p class="noindent"> <p class="noindent">
The full source code of the book can be found here: The full source code of the book can be found here:
<a href="https://www.github.com/hendricius/the-sourdough-framework">https://www.github.com/hendricius/the-sourdough-framework</a> <a href="https://www.github.com/hendricius/the-sourdough-framework">https://www.github.com/hendricius/the-sourdough-framework</a>
@@ -561,6 +612,20 @@ class ModifyBuild
def build_doc(text) def build_doc(text)
Nokogiri::HTML(text) Nokogiri::HTML(text)
end end
def add_anchors_to_headers(text)
doc = build_doc(text)
content = doc.css(".sectionHead, .subsectionHead")
content.each do |el|
anchor = el.attribute("id").value
# No anchor for whatever reason
next unless anchor
copy_link = %Q{<a href="##{anchor}" class="permalink">🔗</a>}
el.inner_html = "#{el.inner_html}#{copy_link}"
end
doc.to_html
end
end end
ModifyBuild.build ModifyBuild.build