Merge remote-tracking branch 'hendiricus/main' into supporters

This commit is contained in:
Cedric
2024-12-26 14:43:49 +00:00
38 changed files with 823 additions and 315 deletions

View File

@@ -1,56 +0,0 @@
name: Create and publish a Docker image
on:
workflow_call:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
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
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Buildx for caching
- uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.determine_tag.outputs.tag }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@@ -4,12 +4,36 @@ on:
push:
branches:
- main
env:
IMAGE: ghcr.io/${{ github.repository }}:latest
LATEST_IMAGE: ghcr.io/${{ github.repository }}:latest
jobs:
build-and-push-image:
uses: ./.github/workflows/docker-build-push.yml
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Buildx for caching
- uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
release-book-website:
needs: build-and-push-image
@@ -20,7 +44,7 @@ jobs:
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
image: ${{ env.LATEST_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
@@ -28,7 +52,7 @@ jobs:
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
image: ${{ env.LATEST_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
@@ -36,11 +60,11 @@ jobs:
- name: Bake the book
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
image: ${{ env.LATEST_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
make -j bake
make bake
- name: Release baked book to S3
uses: shallwefootball/s3-upload-action@master
with:
@@ -60,7 +84,7 @@ jobs:
- name: Bake the website
uses: addnab/docker-run-action@v3
with:
image: ${{ env.IMAGE }}
image: ${{ env.LATEST_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book

View File

@@ -1,14 +0,0 @@
name: Test building book and website with custom image
on:
pull_request:
jobs:
build-and-push-image:
uses: ./.github/workflows/docker-build-push.yml
test-building-book-website:
needs: build-and-push-image
uses: ./.github/workflows/test-book-website.yml
with:
docker-image: ghcr.io/${{ github.repository }}:${{ github.event.pull_request.head.ref }}

View File

@@ -1,14 +0,0 @@
name: Test building book and website with default image
on:
push:
jobs:
build-and-push-image:
uses: ./.github/workflows/docker-build-push.yml
test-building-book-website:
needs: build-and-push-image
uses: ./.github/workflows/test-book-website.yml
with:
docker-image: ghcr.io/${{ github.repository }}:latest

View File

@@ -1,11 +1,9 @@
name: Test book and website for given image
on:
workflow_call:
inputs:
docker-image:
required: true
type: string
on: [push, pull_request]
env:
DOCKER_IMAGE: ghcr.io/${{ github.repository }}:latest
jobs:
test-book-website:
@@ -16,7 +14,7 @@ jobs:
- name: Print dependency versions
uses: addnab/docker-run-action@v3
with:
image: ${{ inputs.docker-image }}
image: ${{ env.DOCKER_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
@@ -24,7 +22,7 @@ jobs:
- name: Print build variables
uses: addnab/docker-run-action@v3
with:
image: ${{ inputs.docker-image }}
image: ${{ env.DOCKER_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
@@ -32,7 +30,7 @@ jobs:
- name: Test baking the release versions
uses: addnab/docker-run-action@v3
with:
image: ${{ inputs.docker-image }}
image: ${{ env.DOCKER_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book
@@ -48,7 +46,7 @@ jobs:
- name: Test building website
uses: addnab/docker-run-action@v3
with:
image: ${{ inputs.docker-image }}
image: ${{ env.DOCKER_IMAGE }}
options: -v ${{ github.workspace }}:/app
run: |
cd /app/book

View File

@@ -8,7 +8,7 @@ LABEL org.opencontainers.image.source="https://github.com/hendricius/the-sourdou
# Print release information if needed
RUN cat /etc/*release*
# Install base depdendencies
# Install base dependencies
RUN apt-get update && \
apt-get install --yes -y --no-install-recommends \
sudo \
@@ -55,6 +55,11 @@ RUN wget https://github.com/mgieseki/dvisvgm/releases/download/3.1.2/dvisvgm-3.1
make && \
make install
RUN git clone https://github.com/michal-h21/make4ht.git && \
cd make4ht && \
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

View File

@@ -84,6 +84,13 @@ size. This shrinks the book from more than 50MB down to ~5MB:
* [Download compiled B&W .epub version](https://www.the-bread-code.io/bw-book.epub)
If you prefer a very short version (about 10 pages) with main flowcharts and
crucial information needed while you are in the kitchen, we also provide a
"too long;didn't read" version you could print. Having read the full book is
highly recommended to understand this leaflet:
* [Download a condensed version](https://www.the-bread-code.io/booklet.pdf)
## Online HTML version
Head over to [https://www.the-sourdough-framework.com](https://www.the-sourdough-framework.com)

View File

@@ -18,12 +18,11 @@ 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{center}
\centering
\input{tables/table-baking-process-stages.tex}
\caption[Stages of dough during baking]{The different stages that
your dough undergoes during the baking process.}%
\label{tab:baking-stages}
\end{center}
\end{table}
At around \qty{60}{\degreeCelsius} (\qty{140}{\degF}) the microbes in your dough start to die.
@@ -171,12 +170,11 @@ way.
\section{Building up steam}
\begin{flowchart}[!htb]
\begin{center}
\centering
\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]
@@ -206,7 +204,7 @@ way.
\end{figure}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-dutch-oven-process.tex}
\caption[Baking process with a dutch oven]{A visualization of the baking
process using a dutch oven (DO). The dough is steamed for the first half
@@ -215,7 +213,6 @@ way.
personal preference. Some bakers prefer a lighter crust and others a
darker.}%
\label{fig:dutch-oven-process}
\end{center}
\end{flowchart}
Dutch ovens are an ideal way to bake with a lot of
@@ -277,12 +274,11 @@ created from the dough and water source stays
around your dough.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-inverted-tray-method.tex}
\caption[Inverted tray baking process]{A schematic visualization the
inverted tray baking method that works great for home ovens.}%
\label{fig:inverted-tray-process}
\end{center}
\end{flowchart}
@@ -335,11 +331,10 @@ crust color. In my case this is another 15--25~minutes typically.
\section{Conclusions}
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-oven-baking-overview.tex}
\caption[Different oven types]{An overview of different oven types and their
different baking methods.}
\end{center}
\end{table}
Depending on your home oven, a different method

View File

@@ -19,7 +19,7 @@ learn more about the yeast and bacterial microorganisms involved.
To understand the many enzymatic reactions that take place when flour
and water are mixed, we must first understand seeds and their role in
the lifecycle of wheat and other grains.
the life cycle of wheat and other grains.
Seeds are the primary means by which many plants, including wheat,
reproduce. Each seed contains the embryo of another plant, and must
@@ -223,12 +223,11 @@ exception, skip ahead to the end of this section on
page~\pageref{aggressive-yeast}.}
\begin{figure}[!htb]
\begin{center}
\centering
\includegraphics[width=0.8\textwidth]{saccharomyces-cerevisiae-microscope}
\caption[Brewer's yeast]{Saccharomyces cerevisiae: Brewer's yeast under the
microscope.}%
\label{saccharomyces-cerevisiae-microscope}
\end{center}
\end{figure}
Yeasts are saprotrophic fungi. This means that they do not produce their own

174
book/booklet.tex Normal file
View File

@@ -0,0 +1,174 @@
\documentclass[paper=a4, twoside=false, fontsize=12pt]{scrbook}
% General packages
\usepackage{sourdough}
\usepackage[
paperwidth=210mm,
paperheight=260mm,
top=10mm,
bottom=80mm,
inner=10mm,
outer=10mm,
marginparsep=7mm,
marginparwidth=48mm,
]{geometry}
\usepackage{subcaption}
\pagenumbering{gobble}
% Basic attributes
\author{Hendrik Kleinwächter}
\title{The Sourdough Framework\\\texttt{tl;dr Booklet Version}}
\begin{document}
\maketitle
\section*{Sourdough starter}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-starter-process.tex}
\caption*{How to setup a sourdough starter}
\end{flowchart}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-starter-readiness.tex}
\caption*{Preparing your starter for baking}
\end{flowchart}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-starter-maintenance.tex}
\caption*{Maintaining your starter, change ratio as per starter hydration
type}
\end{flowchart}
\clearpage{}
\section*{Baker's math}
\begin{table}[!htb]
\centering
\input{tables/table-bakers-math-example.tex}
\caption*{An example table demonstrating how to properly calculate using
baker's math. All the ingredients are calculated as a percentage of the
flour quantity.}
\end{table}
\section*{Basic recipes}
\subsection*{Flat bread}
\input{recipes/flat-bread.tex}
\clearpage{}
\subsection*{Freestanding \& sandwich wheat-based breads}
\begin{table}[!htb]
\centering
\begin{tabular}{@{}lrrrp{0.4\linewidth}@{}}
\toprule
\thead{Ingredient}& & \thead{Percentage} & \thead{Calculation} & \thead{Comments} \\ \midrule
Flour & \qty{400}{g} & & & \\
Whole-wheat flour & \qty{100}{g} & & & \\
Total flour & & \qty{100}{\percent} & \qty{500}{g} & \\
Water & & \qty{60}{\percent} & \qty{300}{g} & \\
Sourdough starter & & \qty{10}{\percent} & \qty{50}{g} & \\
Salt & & \qty{2}{\percent} & \qty{10}{g} & \\ \midrule
Flour & & \qty{100}{\percent} & & \\
Water & & & & \\
Sourdough starter & & & & \\
Salt & & & & \\ \midrule
Flour & & & & \\
& & & & \\
& & & & \\
& & & & \\
& & & & \\ \bottomrule
\end{tabular}
\caption*{Table for your own calculation using baker's math}
\end{table}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-wheat-sourdough-process.tex}
\caption*{The whole process of making wheat based sourdough breads}
\end{flowchart}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-kneading-process.tex}
\caption*{The kneading process to create dough strength}
\end{flowchart}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-bulk-fermentation.tex}
\caption*{How to properly manage bulk fermentation}
\end{flowchart}
\begin{figure*}[!htb]
\centering
\includegraphics[width=\textwidth]{stretch-and-fold-steps}
\caption*{An overview of the steps involved to perform stretch and folds for
wheat-based doughs. They are optional and should only be done when the dough
flattened out a lot.}%
\end{figure*}
\clearpage{}
\section*{Shaping}
\begin{figure*}[!htb]
\centering
\begin{subfigure}{.475\linewidth}
\includegraphics[width=\linewidth]{preshape-direction}
\caption*{Preshaping: Drag the dough in the direction of the rough
surface area.}%
\end{subfigure}
\begin{subfigure}{.475\linewidth}
\includegraphics[width=\linewidth]{step-1-flour-applied}
\caption*{Step 1: Apply flour to the dough's surface.}%
\end{subfigure}\hfill % <-- "\hfill"
\medskip % create some *vertical* separation between the graphs
\begin{subfigure}{.475\linewidth}
\includegraphics[width=\linewidth]{step-2-flipped-over}
\caption*{Step 2: Flipp-over dough. Note how the sticky side is facing
you while the floured side is facing the countertop.}
\end{subfigure}\hfill % <-- "\hfill"
\begin{subfigure}{.475\linewidth}
\includegraphics[width=\linewidth]{step-3-rectangular}
\caption*{Step 3: Make the dough rectangular, keep the sticky side
facing you while the floured side is facing the countertop.}%
\end{subfigure}
\caption*{First steps of shaping process}
\end{figure*}
\begin{figure*}[htb!]
\centering
\includegraphics[width=\textwidth]{step-4-folding}
\caption*{Step 4: The process of folding a batard. Note how the rectangle
is first glued together and then rolled inwards to create a dough roll.
Ultimately the edges are sealed to create a more uniform dough.}%
\end{figure*}
\clearpage{}
\section*{Proofing}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-proofing-process.tex}
\end{flowchart}
\clearpage{}
\section*{Baking}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-baking-process.tex}
\caption*{Summary of different bread baking processes}
\end{flowchart}
\begin{flowchart}[!htb]
\centering
\input{figures/fig-inverted-tray-method.tex}
\caption*{Baking with the inverted tray method}
\end{flowchart}
\begin{flowchart*}[!htb]
\centering
\input{figures/fig-dutch-oven-process.tex}
\caption*{Baking with a Dutch Oven}
\end{flowchart*}
\clearpage{}
\end{document}

View File

@@ -19,12 +19,11 @@ 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{center}
\centering
\input{tables/table-overview-bread-types.tex}
\caption[Different bread types]{An overview of different bread types
and their respective complexity.}%
\label{tab:bread-types-comparison}
\end{center}
\end{table}
\section{Flatbread}%
@@ -57,7 +56,7 @@ pancake-like consistency, as you can see in
Table~\ref{tab:flat-bread-ingredients}
\begin{table}[!htb]
\begin{center}
\centering
\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
@@ -65,7 +64,6 @@ Table~\ref{tab:flat-bread-ingredients}
``\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
@@ -80,13 +78,12 @@ few steps, you can stop buying bread forever. This works with
any flour, including gluten-free options.
\begin{flowchart}[!htb]
\begin{center}
\centering
\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
@@ -106,13 +103,12 @@ 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}
\centering
\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
@@ -135,12 +131,11 @@ when getting started. You can observe the dough more easily and see when
it is ready.
\begin{figure}[htb]
\begin{center}
\centering
\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
@@ -170,12 +165,11 @@ going to taste relatively sour. I~do this frequently to better evaluate the
state of my doughs.
\begin{figure}[!htb]
\begin{center}
\centering
\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
@@ -208,13 +202,12 @@ pancake option, opt for around \qtyrange{0.1}{0.5}{\cm} depending on what you
like.
\begin{figure}[htb]
\begin{center}
\centering
\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
@@ -249,57 +242,10 @@ 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}
\input{recipes/flat-bread.tex}
\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}%
\label{sec:loaf-pan-bread}
Loaf pan bread is made using the help of a special loaf pan
or loaf tin. The edges of the pan provide additional support
@@ -377,12 +323,11 @@ baking vessels in your oven. To make a freestanding loaf more steps
and tools are required.
\begin{figure}[!htb]
\begin{center}
\centering
\includegraphics[width=1.0\textwidth]{free-standing-loaf.jpg}
\caption[Freestanding sourdough bread]{A freestanding sourdough bread. Note
the incision known as an \emph{ear} and the oven spring clearly
distinguish this type of bread from flatbread and loaf pan bread.}
\end{center}
\end{figure}
When using wheat, make sure to mix your dough enough to develop a gluten network.

View File

@@ -29,11 +29,11 @@
% 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 together
\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,3.0); % Branch to Jordan
% Move pasteur down a bit so the lines look like they cross
% 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

View File

@@ -1,5 +1,5 @@
\begin{tikzpicture}[node distance = 3cm, auto]
\node [start] (init) {Make a starter};
\node [start] (init) {Create a starter};
\node [decision, right of=init, node distance=3.5cm] (decision_start) {Starter last fed within 3~days?};
\node [block, right of=decision_start, text width=7em, node distance=4cm] (feed_no_branch)
{Feed starter twice:\par \qty{48}{\hour} before\par \qtyrange{6}{12}{\hour} before};

View File

@@ -17,12 +17,11 @@ Depending on which layers are still present, different names are used to describ
type of flour.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-flour-types.tex}
\caption[Labelling of wheat flour]{A comparison of how different types
of wheat flour are labelled in different countries.}%
\label{tab:flour-types-comparison}
\end{center}
\end{table}
In Germany, the ash content is used to describe the flours. The lab will burn
@@ -60,11 +59,10 @@ want the final bread to be too sour. Conversely you do not have to worry about
the gluten degradation, removing a huge headache from the equation.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-grains-bread-making-process.tex}
\caption[Different types of grain]{An overview of different grain
types and the steps involved in the respective bread making process.}
\end{center}
\end{table}
Because gluten has a special role, the rest of this chapter is dedicated to having a
@@ -115,13 +113,12 @@ The long fermentation period also means that your microbes will enrich
your dough with more flavor.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-overview-w-values.tex}
\caption[Fermentation time versus W-value]{An overview of different
levels of W-values and the respective hydrations and fermentation
times.}%
\label{tab:w-value}
\end{center}
\end{table}
Generally, when aiming to

View File

@@ -157,7 +157,7 @@ and pastries.
\item[Coil fold] A special stretch and folding technique. The coil fold is
very gentle on the dough and is thus excellent throughout the bulk fermentation.
By applying the coil fold the dough strength is improved by minimising damage
By applying the coil fold the dough strength is improved by minimizing damage
to the dough structure.
\item[Crumb] The inner texture of the bread, which is characterized by the size,
@@ -285,7 +285,7 @@ depending on the initial reactants and cooking conditions can produce a wide var
of end products with different tastes and aromas. Maillard reactions occur readily
above \SI{150}{\celsius}, although will still occur much more slowly below that
temperature. Optimal reaction rate occurs between \pHvalue{6.0} to \pHvalue{8.0},
although it favours alkaline conditions.
although it favors alkaline conditions.
\item[Maltose] A sugar produced from the enzymatic breakdown of starch by amylases.
It's a primary food source for yeast during fermentation.
@@ -404,7 +404,7 @@ unpredictable ways. It also provides a controlled aesthetic to the finished loaf
\item[Soaker] A mixture of grains or seeds with water that is left to soak overnight (or for a
specified amount of time) before being incorporated into bread dough. This helps to
soften and hydrate the grains or seeds (sesame, pumpkin, etc.), making them
soften and hydrate the grains or seeds (sesame, pumpkin, \etc{}), making them
easier to integrate into the dough and
providing a moister crumb in the finished bread.

View File

@@ -26,7 +26,7 @@ waters, another single-celled life form, \emph{archaea}, also thrived. These
organisms inhabit extreme environments, from boiling vents to icy waters.
\begin{figure}[!htb]
\begin{center}
\centering
\input{figures/fig-life-planet-sourdough-timeline.tex}
\caption[Sourdough microbiology timeline]{Timeline of significant events
starting from the first day of Earth's existence,
@@ -34,12 +34,11 @@ organisms inhabit extreme environments, from boiling vents to icy waters.
marked at midnight. This visualization shows the pivotal steps
of life and sourdough on earth.}%
\label{fig:planet-timeline}
\end{center}
\end{figure}
Whoever comes first, bacteria or archaea, remains debated. For three
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 a highly unlikely event, an archaeon consumed a bacterium.
Instead of digesting it, they formed a symbiotic relationship. This led to the
first nucleated organisms, marking an evolutionary milestone. This event lead
to the development of plants, fungi and also ultimately humans.
@@ -70,12 +69,11 @@ Ancient Jordan~\cite{jordan+bread}. Looking at the earth's timeline sourdough
bread can be considered a very recent invention.
\begin{figure}[!htb]
\begin{center}
\centering
\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

View File

@@ -81,7 +81,7 @@ sometimes you are faced with issues you don't understand. In \qty{99.95}{\percen
of all software bugs, the developer is the issue. Sometimes, however, the framework has a
bug. That is when the developer must dig deeper to see the \emph{what} and the
\emph{why} behind what
the framework is doing. You will need to read other engineer's source code, and you will be forced
the framework is doing. You will need to read other engineers' source code, and you will be forced
to understand \emph{why} things are happening.
Being unhappy with what I~was baking, my engineering mindset took over, and I~had

View File

@@ -31,10 +31,12 @@ chapters = baking basics bread-types cover flour-types history intro mix-ins\
src_tables := $(wildcard tables/table-*.tex)
src_figures := $(wildcard figures/fig-*.tex) figures/flowcharts_tikz.tex
src_recipes := $(wildcard recipes/*.tex)
src_tex := $(foreach directory, $(chapters), $(wildcard $(directory)/*.tex))
src_tex += book.tex book_sans_serif.tex references.bib figures/vars.tex
src_tex += supporters.csv sourdough.sty colors.tex
src_tex += $(src_recipes)
images := $(wildcard images/*/*.jpg)
images += $(wildcard images/*.jpg)
@@ -55,6 +57,11 @@ ebook_src := $(src_all) tex4ebook.cfg book.mk4 book-ebook.css
website_src := $(src_all) website.cfg style.css
# This is more than what is actually needed but keeps the makefile simple
# and latexmk will handle the rest
booklet_src := $(src_figures) $(src_tables) $(src_recipes) $(images)
booklet_src += booklet.tex
website_assets := $(wildcard ../website/assets/*)
ruby_src := ../website/modify_build.rb $(website_assets)
ruby_pkg := ../website/Gemfile ../website/Gemfile.lock
@@ -83,6 +90,9 @@ tgt_figures := $(patsubst %.tex, %.png,$(src_figures))
%.xbb: %.jpg
ebb -x $<
booklet/booklet.pdf: $(booklet_src)
$(LATEX) -output-directory=booklet booklet.tex
book_serif/book.pdf: $(src_all)
$(LATEX) -output-directory=book_serif book.tex
@@ -97,7 +107,7 @@ epub/%.epub: %.tex $(ebook_src) cover/cover-page.xbb
copy_ebook_files: build_ebook
$(RSYNC) book-epub/ bw-book-epub/
# We not convert SVG to B&W or lower res for now as they are super small
# We do not convert SVG to B&W or lower res for now as they are super small
# anyway
bw-book-epub/OEBPS/%.jpg: %.jpg
mkdir -p $(dir $@)
@@ -140,6 +150,8 @@ help:
@echo ""
@echo "build_ebook: builds only the colour ebook"
@echo ""
@echo "build_booklet: builds only the short booklet"
@echo ""
@echo "build_bw_ebook: builds the low res black & white ebook"
@echo ""
@echo "build_sans_serif_pdf: build accessible pdf only"
@@ -160,6 +172,8 @@ help:
@echo ""
@echo "quick_ebook: compiles ebook but runs lulatex only once"
@echo ""
@echo "quick_booklet: compiles booklet but runs lulatex only once"
@echo ""
@echo "show_tools_version: Show version of tools used on the build machine"
@echo ""
@echo "print-X: print makefile variable X"
@@ -170,10 +184,12 @@ help:
# Finally actual project targets (i.e. build pdf and ebooks)
.PHONY: build_pdf build_serif_pdf build_sans_serif_pdf build_ebook
.PHONY: build_pdf build_booklet build_serif_pdf build_sans_serif_pdf build_ebook
build_pdf: build_serif_pdf build_sans_serif_pdf
build_booklet: booklet/booklet.pdf
build_serif_pdf: book_serif/book.pdf
build_sans_serif_pdf: book_sans_serif/book_sans_serif.pdf
@@ -221,15 +237,17 @@ clean_website_build: clean_ebook_build
clean: clean_ebook_build clean_figures clean_website_build
$(CLEAN) -output-directory=book_serif book.tex
$(CLEAN) -output-directory=book_sans_serif book_sans_serif.tex
$(CLEAN) -output-directory=booklet booklet.tex
-rm book*/*.{bbl,loc,.run.xml}
-rm -rf book*-epub/META-INF
-rm -rf book*-epub/OEBPS
-rm book*-epub/mimetype
-rm -rf *book-epub/META-INF
-rm -rf *book-epub/OEBPS
-rm *book-epub/mimetype
mrproper: clean
$(CLEAN) -C $(src_figures)
$(CLEAN) -C -output-directory=book_serif book.tex
$(CLEAN) -C -output-directory=book_sans_serif book_sans_serif.tex
$(CLEAN) -C -output-directory=booklet booklet.tex
-rm figures/*.png
-rm *.html
-rm *.svg
@@ -237,13 +255,14 @@ mrproper: clean
-rm -rf release/
-rm -rf book_serif/
-rm -rf book_sans_serif/
-rm -rf book-epub/
-rm -rf booklet/
-rm -rf *book-epub/
-rm -rf $(website_dir)
# top level releases rules
.PHONY: bake release_serif release_sans_serif
bake: release_serif release_sans_serif
bake: release_serif release_sans_serif release_booklet
release:
mkdir -p release
@@ -256,6 +275,9 @@ release_serif: build_serif_pdf build_ebook build_bw_ebook | release
release_sans_serif: build_sans_serif_pdf | release
cp book_sans_serif/book_sans_serif.pdf release/TheBreadCode-The-Sourdough-Framework-sans-serif.pdf
release_booklet: build_booklet | release
cp booklet/booklet.pdf release/TheBreadCode-The-Sourdough-Framework-booklet.pdf
# Website stuff
.PHONY: html website
$(website_dir)/book.html: $(website_src) cover/cover-page.xbb
@@ -283,6 +305,9 @@ website: html ../website/_bundle_install_done $(ruby_src)
quick: # run latex only once no biber, no references etc...
$(LATEX) -e '$$max_repeat=1' -halt-on-error -output-directory=book_serif book.tex
quick_booklet:
$(LATEX) -e '$$max_repeat=1' -halt-on-error -output-directory=booklet booklet.tex
quick_ebook: cover/cover-page.xbb # run latex only once no biber, ref etc...
$(EBOOK) --mode draft book.tex
@@ -293,6 +318,9 @@ show_tools_version: # Show version of tools used on the build machine
@echo ""
- $(SHELL) --version
@echo ""
- @echo "PATH:"
- @echo $(PATH) | tr ':' '\n'
@echo ""
- latexmk --version
@echo ""
- lualatex --version

View File

@@ -111,7 +111,7 @@ usually moderately affect the color.
\item Semolina (supports Mediterranean flavors)
\item Cocoa (replace \qty{10}{\percent} of the flour for a black loaf, goes
great with sweet toppings)
\item Other non-wheat flours such as: Chickpea, corn, hemp, potato etc.
\item Other non-wheat flours such as: Chickpea, corn, hemp, potato\dots{}
\end{itemize}
\subsection{Liquids}
@@ -134,15 +134,15 @@ affecting taste and texture.
\item Eggs
\item Fruit/vegetable juices (also see Section~\ref{section:colors})
\item Milk (for sweet, soft breads)
\item Milk alternatives such as: Almond, oat, soy etc.
\item Milk alternatives such as: Almond, oat, soy\dots{}
\item Mashed potatoes
\item Mashed sweet potatoes. Bolo do caco is a typical bread from Madeira,
made from \qty{50}{\percent} wheat flour and \qty{50}{\percent} mashed potatoes.
\item Olive oil (Mediterranean)
\item Other mashed vegetables such as: Beets, pumpkin, etc.
\item Other mashed vegetables such as: Beets, pumpkin\dots{}
\end{itemize}
\subsection{Colors}
\subsection{Colors}%
\label{section:colors}
Some mix-ins will change the color and flavor of your bread. Common colorings
include:
@@ -201,17 +201,18 @@ dough.
These are mostly powders or small bits.
\begin{itemize}
\item Blueberry skins (press through a sieve to remove juice, raw blueberries
\item Blueberry skins (press through a sieve to remove juice), raw
blueberries
\item Browned onions
\item Candied fruits such as: Lemon, orange, pineapple, etc.
\item Candied fruits such as: Lemon, orange, pineapple\dots{}
\item Cinnamon
\item Grated hard cheese such as: Gruyère, parmesan, etc.
\item Mediterranean herbs such as: Marjoram, oregano, rosemary, thyme, etc.
\item Grated hard cheese such as: Gruyère, parmesan\dots{}
\item Mediterranean herbs such as: Marjoram, oregano, rosemary, thyme\dots{}
\item Miso
\item Molasses
\item Sugar
\item Spices such as: Anise, fennel, cinnamon, coriander, cumin, etc.
\item Zests such as: Lime, Lemon, orange, etc.
\item Spices such as: Anise, fennel, cinnamon, coriander, cumin\dots{}
\item Zests such as: Lime, Lemon, orange\dots{}
\end{itemize}
\subsection{Highlights}
@@ -222,12 +223,12 @@ can often be complemented by some flavor or flour mix-in.
\begin{itemize}
\item Chocolate chunks or drops
\item Chunks of black garlic
\item Chunks of cheese such as: Cheddar, feta, etc.
\item Chunks of cheese such as: Cheddar, feta\dots{}
\item Cornflakes
\item Dried fruits such as: Cranberries, dates, raisins, etc.
\item Dried fruits such as: Cranberries, dates, raisins\dots{}
\item Olives
\item Pickled pepperoni
\item Sundried tomatoes (squeeze out the oil if using pickled ones, or soak
\item Sun-dried tomatoes (squeeze out the oil if using pickled ones, or soak
dried ones in water)
\end{itemize}
@@ -240,7 +241,7 @@ A few combinations where multiple mix-ins complement each other:
\item Cheddar and jalapeño
\item Cocoa, cacao nibs, whole hazelnuts
\item Cranberry and walnuts
\item Semolina, Mediterranean herbs, olives, sundried tomatoes
\item Semolina, Mediterranean herbs, olives, sun-dried tomatoes
\item Tomato juice instead of water with \qty{20}{\percent} rye flour
\end{itemize}
@@ -310,6 +311,6 @@ ferment the dough in separate containers. Then Combine the two (or
more) differently colored doughs by laminating and stacking the colored sheets
of dough before the last folding, just before shaping. This way the colored
layers won't mix and the resulting dough will have differently colored and
tasting layers. \footnote{I once made an experimental dough by merging a wheat,
tasting layers\footnote{I once made an experimental dough by merging a wheat,
rye, spelt and einkorn dough into a single dough. The resulting dough was
layered featuring different colors, textures, and flavors.}
layered featuring different colors, textures, and flavors.}.

View File

@@ -17,14 +17,13 @@ a denser crumb compared to wheat, as you can see in
Picture~\ref{fig:rye-crumb}.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-non-wheat-process.tex}
\caption[Process for non-wheat sourdough bread]{A visualization of the
process to make non-wheat sourdough bread. The process is much simpler
than making wheat sourdough bread. There is no gluten development. The
ingredients are simply mixed together.}%
\label{flc:non-wheat-sourdough}
\end{center}
\end{flowchart}
For non-wheat flours---including rye, emmer, and einkorn---no gluten

View File

@@ -0,0 +1,53 @@
\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}

View File

@@ -27,14 +27,13 @@ starter has half as much water as flour, as summarized in
Table~\ref{tab:starter-types-comparison}.
\begin{table}[htp!]
\begin{center}
\centering
\input{tables/table-starter-types.tex}
\caption[Different types of sourdough]{A comparison of different
sourdough starter types and their respective properties. The only
difference is the amount of water (hydration) that is used when
feeding the starter.}%
\label{tab:starter-types-comparison}
\end{center}
\end{table}
You can change your starter type by just adjusting the feeding ratio of how
@@ -123,19 +122,18 @@ starter's flavor by changing the type to a liquid starter.
\label{section:liquid-starter}
\begin{figure}[!htb]
\begin{center}
\centering
\includegraphics[width=0.5\textwidth]{sourdough-starter-liquid.jpg}
\caption[Liquid starter]{A liquid sourdough starter features a high level of
water. The high water amount boosts lactic acid producing bacteria.
After a while the liquid and flour start to separate. Bubbles on the
side of the flour indicate that the starter is ready to be used.}%
\label{fig:liquid-sourdough-starter}
\end{center}
\end{figure}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-liquid-starter-conversion.tex}
\caption[Converting to a liquid starter]{The process to convert your regular
or stiff starter into a liquid starter. The whole process takes around
@@ -149,7 +147,6 @@ starter's flavor by changing the type to a liquid starter.
starter your created stiff starter will feature both dairy
and vinegary notes.}%
\label{flc:liquid-starter-conversion}
\end{center}
\end{flowchart}
The liquid starter is made at a hydration of around \qty{500}{\percent}. This means
@@ -242,7 +239,7 @@ for a visual example of the starter's required hydration level.
\end{figure}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-stiff-starter-conversion.tex}
\caption[Converting to a stiff starter]{The process to convert your regular
starter into a stiff starter. The whole process takes around 3 days. The
@@ -252,7 +249,6 @@ for a visual example of the starter's required hydration level.
\qty{50}{\percent} hydration level for the starter. If the dough is too
stiff consider increasing this to \qty{60}{\percent}.}%
\label{fig:stiff-starter-conversion}
\end{center}
\end{flowchart}
In the stiffer environment the yeast thrives more. This means you will have
@@ -302,13 +298,16 @@ pockets of air on the sides of your container. Use your nose to smell the
starter. It should have a mild smell. It also tends to smell much more
alcoholic than the other starters.
When using a stiff starter, use around \qtyrange{1}{20}{\percent} starter for your
When using a stiff starter, use around \qtyrange{1}{20}{\percent} starter in terms of
baker's math for your
dough. This depends on the ripeness of your starter.
In summer I~typically use around
\qty{10}{\percent} and in winter around \qty{20}{\percent}. This way you can
also control the fermentation speed.
Mixing the starter can be a little bit annoying as it hardly homogenizes with
the rest of the dough. In this case you can try to dissolve the starter in the
\qtyrange{1}{10}{\percent} and in winter around \qty{20}{\percent}. This way you can
also control the fermentation speed. If it is very hot where you live, consider
lowering the starter amount to \qtyrange{1}{5}{\percent}. If it is very cold in your
area consider increasing the starter amount up to \qty{30}{\percent}.
Mixing the stiff starter can be a little bit annoying as it hardly homogenizes with
the rest of the dough. In this case, you can try to dissolve the starter in the
water you are about to use for your dough. This will make mixing a lot easier.

View File

@@ -38,11 +38,10 @@ comes in handy. Let's look at the default recipe with baker's
math and then adjust it for the \qty{1.4}{\kg} flour quantity.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-bakers-math-example.tex}
\caption[Baker's math example]{An example table demonstrating how to
properly calculate using baker's math}
\end{center}
\end{table}
Note how each of the ingredients is calculated as a percentage
@@ -55,12 +54,11 @@ more flour available the next day. As mentioned the next day
we have \qty{1.4}{\kg} at hand (\qty{1400}{\gram}).
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-recipe-bakers-math.tex}
\caption[Another baker's math example]{An example recipe that uses
\qty{1400}{\gram} as its baseline and is then calculated using
baker's math.}
\end{center}
\end{table}
For each ingredient we calculate the percentage
@@ -133,12 +131,11 @@ I~like to use a glass and place another
inverted one on top.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-starter-process.tex}
\caption[The full sourdough starter process]{The process of making a sourdough
starter from scratch.}%
\label{fig:sourdough-starter-process}
\end{center}
\end{flowchart}
Now an epic battle begins. In one study~\cite{yeasts+biocontrol+agent}
@@ -272,14 +269,13 @@ yeast has been isolated like this from century old sourdough
starters.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-starter-readiness.tex}
\caption[Determining sourdough starter readiness]{A flow chart showing you how to
determine if your sourdough starter is ready to be used. For checking
readiness look at a size increase and take note of your starter's smell.
Both are important indicators to check for readiness.}%
\label{fig:sourdough-starter-readiness}
\end{center}
\end{flowchart}
The key sign to look at is bubbles that you see in your starter
@@ -346,7 +342,7 @@ yeast part of your sourdough and balance the fermentation.
\section{Maintenance}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-starter-maintenance.tex}
\caption[Sourdough starter maintenance flowchart]{A full flowchart showing
you how to conduct proper sourdough starter maintenance. You can use a
@@ -356,7 +352,6 @@ yeast part of your sourdough and balance the fermentation.
\qty{100}{\percent} hydration level. Adjust the water content
accordingly when you use a stiff starter.}%
\label{fig:sourdough-maintenance-process}
\end{center}
\end{flowchart}
You have made your sourdough starter and your first bread. How do you perform
@@ -432,7 +427,7 @@ of water. This extra layer of water provides good protection from the top
part drying out. As mold is aerobic it can not grow efficiently under
water~\cite{mold+anaerobic}. Before using the starter again simply either stir
the liquid into the dough or drain it. If you drain the liquid you can use it
to make a lacto fermented hot sauce for instance.
to make a lacto-fermented hot sauce for instance.
The colder it is the longer you preserve a good balance of yeast and
bacteria. Generally, the warmer it is the faster the fermentation process is,

View File

@@ -33,6 +33,7 @@
% Common abbreviations
\newcommand{\ie}{\emph{i.e.}\@ifnextchar.{\!\@gobble}{}}
\newcommand{\eg}{\emph{e.g.}\@ifnextchar.{\!\@gobble}{}}
\newcommand{\etc}{etc\@ifnextchar.{}{.\@}}
% Consistent pH values
\newcommand{\pHvalue}[1]{pH~\SI{#1}{}}

View File

@@ -9,12 +9,11 @@ later time.
A summary can be found in Table~\ref{table:bread-storage}, with details and
explanation in th rest of this chapter.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-storing-bread-overview.tex}
\caption[Options to store bread]{A table visualizing the advantages
and disadvantages of different bread storing options.}%
\label{table:bread-storage}
\end{center}
\end{table}
\section{Room temperature}

View File

@@ -6,12 +6,15 @@
--fw-bold: 800;
--f-lh: 28px;
--c-black: #282828;
--c-black-background: #1c1819;
--fs-xxxl: 32px;
--fs-xxl: 26px;
--fs-xl: 24px;
--fs-l: 22px;
--fs-m: 16px;
--padding-hamburger: 5px;
--c-beige: #F3EDE6;
--border-radius: 7px;
}
@media (min-width: 1200px){
@@ -38,6 +41,7 @@ body{
font-family: var(--ff-sans);
font-weight: var(--fw-regular);
font-size: var(--fs-m);
color: var(--c-black);
}
@media screen and (min-width: 57rem) {
@@ -60,7 +64,6 @@ body{
/* ****************** */
main.main-content,main.titlepage,div.footnotes{
padding:1rem;
}
.permalink {
@@ -144,7 +147,7 @@ nav.TOC a, nav.TOC a:visited{
body{
background-color: var(--c-black);
background-color: var(--c-beige);
}
a {
@@ -174,6 +177,7 @@ figure.texsource, figure.shellcommand, figure.htmlsource, figure.luasource, figu
.main-content {
line-height: var(--f-lh);
margin-left: 30px;
}
div.footnotes {
@@ -229,6 +233,7 @@ figcaption.caption {
list-style: none;
margin: 0;
padding: 0;
width: 300px;
}
.menu-items .chapterToc, .menu-items .likechapterToc {
@@ -331,7 +336,7 @@ div.center {
margin-right: 0 !important;
}
main.titlepage h2.chapterHead {
main.main-content h2.chapterHead, main.main-content h2.likechapterHead {
margin-top: 0px;
}
@@ -379,3 +384,213 @@ h4 {
max-width: 100%;
margin-top: 1em;
}
img[alt~="PIC"], iframe, a img {
border-radius: var(--border-radius);
border: 2px solid var(--c-black);
}
main.main-content, div.footnotes, main.titlepage {
background-color: var(--c-beige);
}
.main-content {
flex: 1;
}
.wrapper {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.header {
background-color: var(--c-black-background);
width: 100%;
height: 340px;
display: flex;
align-content: center;
justify-content: center;
align-items: center;
margin-bottom: 40px;
}
.header img {
border-radius: 0px;
border: none;
width: 710px;
}
body {
display: block;
}
.book-content {
display: flex;
padding: 0px 40px;
max-width: 1200px;
}
.TOC.menu {
width: 330px;
}
.main-content {
width: 100%;
margin-bottom: 40px;
}
nav.TOC, nav.TOC a, nav.TOC a:visited {
background-color: transparent;
color: var(--c-black);
}
.menu-group {
display: flex;
flex-direction: column;
align-items: center;
}
.menu-inner {
border: 2px solid var(--c-black);
border-radius: var(--border-radius);
width: 100%;
}
.menu-entry {
padding: 1px;
border-radius: var(--border-radius);
}
.menu-arrow {
width: 14px;
border: none;
border-radius: 0px;
}
nav.TOC span:hover, nav.TOC span:hover *, nav.TOC span.chapterToc.selected, nav.TOC span.chapterToc.selected a {
background-color: transparent;
}
.menu-entry:hover {
background-color: #c8c8c8;
}
p.flowchart-image-wrapper {
background: white;
padding: 20px;
border-radius: var(--border-radius);
border: 2px solid var(--c-black);
display: flex;
justify-content: center;
}
.menu-items .menu-group:last-of-type .menu-arrow {
display: none;
}
blockquote {
margin-left: 0px;
margin-right: 0px;
}
.crosslinks-bottom {
margin-top: 1em;
}
.crosslinks-bottom a {
display: inline-block;
border-radius: var(--border-radius);
border: 2px solid var(--c-black);
color: var(--c-black);
padding: 4px;
font-weight: bold;
text-decoration: none;
}
.crosslinks-bottom a.prev {
margin-right: 7px;
}
.crosslinks-bottom a:hover {
color: #444;
}
.menu-group.selected .menu-inner {
background-color: #c8c8c8;
}
.TOC.menu {
margin-bottom: 40px;
}
.mobile-banner {
display: none;
}
@media (max-width: 768px) {
.header {
display: none;
}
.book-content {
padding: 0px;
display: flex;
width: 100%;
flex-direction: column;
}
.main-content {
width: 100%;
margin-left: 0px;
box-sizing: border-box;
padding: 0px 14px;
margin-top: 20px;
max-width: 100%;
}
.TOC.menu {
width: 100%;
max-width: 100%;
background: var(--c-black-background);
box-sizing: border-box;
}
nav.TOC, nav.TOC a, nav.TOC a:visited {
color: #fff;
}
.menu-arrow {
display: none;
}
.menu-inner {
border: none;
border-radius: 0px;
}
.menu-group.selected .menu-inner {
background: var(--c-black-background);
}
p.flowchart-image-wrapper {
padding: 5px;
}
.menu-entry:hover {
background-color: transparent;
}
.TOC.menu {
margin-bottom: 0px;
}
.mobile-banner {
display: block;
background-color: var(--c-black-background);
padding: 5px;
}
.mobile-banner a img {
border: none;
border-radius: 0px;
}
}

View File

@@ -11,7 +11,7 @@ Andail,
Andreas Schmid,
Andrzej Mitelski,
Anna G.,
anonnn,
Anonnn,
Anthony Atkinson,
Aurore,
Beatriz,
@@ -26,6 +26,7 @@ BTSkete,
C Fazio,
Cal Kotz,
Case,
Cédric Andrieu,
Charlene Adkins,
Chin Pui Ling,
Chris DuBosq,
@@ -35,7 +36,6 @@ Christiane B,
Christine,
Chrysanna,
Colleen Guidone,
Cédric Andrieu,
Danieel,
Daniel,
David,
@@ -48,7 +48,7 @@ Duivelsjong,
Elaine Leung,
Ellie,
Ethan,
Francois le Danois,
François le Danois,
Fredrik,
Geoff,
Guillermo,
@@ -59,7 +59,6 @@ Ilsefa,
Inma Mcleish,
Jackie,
Jacques Lucke,
Jacques Lucke,
Jan Chrillesen,
Jan-Pieter Van Den Wittenboer,
Jane,
@@ -135,7 +134,6 @@ Smirnov,
Spencer,
Strambinha,
Sue,
Sue,
Sune,
Susan,
Sven,
@@ -145,7 +143,7 @@ Therealbruce,
Tracy \& Paul Will,
Usliv,
Vassil Dichev,
Vladimir
Vladimir Smirnov,
Voicu,
Zika,
Zoltan.
Can't render this file because it has a wrong number of fields in line 148.

View File

@@ -7,7 +7,7 @@
100 / 212 & Water evaporation & Water begins to evaporate and inflates your dough's alveoli.\\
118 / 244 & Acetic acid evaporation & The vinegary tasting acid starts to evaporate, sourness decreases.\\
122 / 252 & Lactic acid evaporation & The dairy tasting lactic acid begins to evaporate, sourness further decreases.\\
140 / 284 & Maillard reaction & The maillard reaction starts to deform starches and proteins.
140 / 284 & Maillard reaction & The Maillard reaction starts to deform starches and proteins.
The dough starts browning.\\
170 / 338 & Caramelization & Remaining sugars begin to caramelise giving your bread a distinct flavor.\\ \bottomrule
\end{tabular}

View File

@@ -1,4 +1,4 @@
%TODO: Alignement is not great
%TODO: Alignment is not great
\begin{tabular}{@{}lll@{}}
\toprule
& \textbf{Flat breads} & \textbf{Pancakes} \\ \midrule

View File

@@ -141,7 +141,7 @@ should dissipate within 12--24~hours, and you have
the added advantage of automatically having
room-temperature water.
Make sure to use whole grain flour (whole-wheat, whole-rye, etc.).
Make sure to use whole grain flour (whole-wheat, whole-rye, \etc{}).
These flours have more natural wild yeast and
bacterial contamination. Making a starter
from just white flour sometimes doesn't work.
@@ -188,12 +188,11 @@ protecting your sourdough starter from aerobic mold entering through
the top.
\begin{figure}[!htb]
\begin{center}
\centering
\includegraphics[width=0.5\textwidth]{sourdough-starter-hooch}
\caption[Hooch] {Hooch building on top of a sourdough
starter~\cite{liquid+on+starter}.}%
\label{fig:hooch}
\end{center}
\end{figure}
Simply stir your sourdough starter to homogenize the hooch back
@@ -321,12 +320,11 @@ When tasting acetic acid, the flavor of your bread is often perceived
as quite strong.
\begin{figure}[!htb]
\begin{center}
\centering
\input{figures/fig-ethanol-oxidation.tex}
\caption[Acetic acid creation]{Oxygen is required to create acetic
acid~\cite{acetic+acid+production}.}%
\label{fig:ethanol-oxidation}
\end{center}
\end{figure}
This is nothing bad. But if you would like to change

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 626 KiB

View File

@@ -45,11 +45,10 @@ that tastes much better than any store-bought bread.
\section{The process}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-wheat-sourdough-process.tex}
\caption{The typical process of making a wheat-based sourdough bread.}%
\label{fig:wheat-sourdough-process}
\end{center}
\end{flowchart}
The whole process of making great sourdough bread starts with
@@ -99,7 +98,7 @@ doesn't have a good balance of yeast to bacteria, so will your
main dough.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-starter-readiness.tex}
\caption[Process to prepare your starter before baking]{The process to check
your sourdough starter when making wheat-based doughs. In practice
@@ -110,7 +109,6 @@ main dough.
shown water quantities, i.e., if the chart shows \qty{100}{\gram} of
water, use \qtyrange{50}{60}{\gram} of water for your stiff starter.}%
\label{fig:process-starter-wheat-sourdough}
\end{center}
\end{flowchart}
Generally, think of the dough you are mixing as a big starter with salt.
@@ -137,7 +135,7 @@ the microorganisms.
Some people use a 1:1:1 ratio to refresh the starter. This would
be one part of the old starter (\qty{10}{\gram} for instance), 1 part of flour,
and one part of water. I~think this is utter rubbish. As mentioned
your starter is a gigantic dough. You would never opt for a 1:1:1 ratio to
your starter is a miniature dough. You would never opt for a 1:1:1 ratio to
make dough. You might use a maximum of \qty{20}{\percent} starter to
make dough. That's why I~advocate using a 1:5:5 ratio or a
1:10:10 ratio depending on how ripe your starter is. As I~almost
@@ -520,12 +518,11 @@ value to \qtyrange{5}{10}{\percent}. The other option could be to place the doug
environment and thus reduce the speed at which your microorganisms replicate.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-starter-usage-activity.tex}
\caption[Quantity of sourdough]{A table visualizing how much sourdough
starter to use depending on temperature and the starter's activity
level.}
\end{center}
\end{table}
Based on my experience and my sourdough, my ideal bread always takes around 8
@@ -561,11 +558,10 @@ all the gases during the fermentation process. Without the gluten network,
the gases would just diffuse out of your dough.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-kneading-process.tex}
\caption{The gluten development process for a wheat-based dough.}%
\label{fig:wheat-sourdough-kneading-process}
\end{center}
\end{flowchart}
It might sound odd, but the most important part of kneading is waiting. By
@@ -751,12 +747,11 @@ flavor of the resulting bread is better compared to a pale
underfermented dough.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-fermentation-effects.tex}
\caption[Stages of sourdough fermentation]{The different stages of
sourdough fermentation and the effects on crumb, alveoli, texture,
and overall taste.}
\end{center}
\end{table}
The worst thing you can do when fermenting sourdough
@@ -777,7 +772,7 @@ is much larger. The doughs are perfect to be made in a
machine.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-bulk-fermentation.tex}
\caption[Process to check the bulk fermentation]{During the bulk
fermentation, multiple doughs are fermented together in bulk. A
@@ -785,7 +780,6 @@ machine.
stage of fermentation is completed. This chart shows multiple available
options to check on the bulk fermentation progress.}%
\label{fig:bulk-fermentation}
\end{center}
\end{flowchart}
Experienced bakers will tell you to go by the look and feel of
@@ -798,8 +792,7 @@ 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
sample is extracted after creating the initial dough strength.
You monitor the aliquot's size increase to judge the
level of fermentation of your main dough. The aliquot
sample is extracted after creating dough strength. As your
level of fermentation of your main dough. As your
dough ferments, so does the content of your aliquot jar. The moment your
sample reached a certain size, your main dough is ready
to be shaped and proofed. The size increase you should
@@ -814,12 +807,11 @@ up to \qty{100}{\percent} with subsequent bakes. Then identify a value
that you are happy with.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-dough-size-increase.tex}
\caption[Increase of size versus protein content]{Reference values for
how much size increase to aim for with an aliquot jar depending on
the dough's protein content.}
\end{center}
\end{table}
The beauty of the aliquot is that no matter the surrounding
@@ -896,12 +888,11 @@ bread didn't turn out the way you like, either shorten
the fermentation or extend it a little bit.
\begin{table}[!htb]
\begin{center}
\centering
\input{tables/table-ph-values-dough.tex}%
\caption[Dough's pH during bread preparation]{Example pH values for
the different breakpoints of my own sourdough process.}%
\label{table:sample-ph-values}
\end{center}
\end{table}
The beauty of this method is its reliability. Once you have found
@@ -921,7 +912,12 @@ as rough ballpark figures. Regardless, you need to find values
that work for your setup.
Another limitation is the price. You will need to purchase
a high-tech pH meter, ideally, a meter featuring a spearhead.
a high-tech pH meter, ideally, a meter featuring a spearhead
\footnote{Not every pH meter is suitable for measuring dough.
Please refer to the manual to make sure it is certified for
measuring the pH of liquid and semi-solid media. To receive
accurate pH readings further ensure that your pH meter
is properly calibrated.}.
This way you can directly poke the meter deep into the dough.
At the same time, automated temperature adjustments are a
feature to look out for. Depending on the temperature,
@@ -1120,12 +1116,11 @@ The step is required if you are making multiple loaves in one
batch. It is optional if you are making a single loaf.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-dividing-preshaping.tex}
\caption[Is dividing your dough required check]{Dividing is only required when you are
making multiple loaves in a single dough batch.}%
\label{fig:dividing-decision-tree}
\end{center}
\end{flowchart}
The goal of dividing your dough into smaller pieces is to portion
@@ -1235,12 +1230,11 @@ your environment.
\section{Shaping}
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-shaping-process.tex}
\caption[Sourdough shaping process]{A schematic visualization of the shaping process
including checks for an overfermented dough.}%
\label{fig:shaping-decision-tree}
\end{center}
\end{flowchart}
Shaping will give your dough the final shape before baking. After
@@ -1460,13 +1454,12 @@ their biochemical processes. More research is needed on the topic
of retarding and flavor development.
\begin{flowchart}[!htb]
\begin{center}
\centering
\input{figures/fig-proofing-process.tex}
\caption[Sourdough proofing process]{A schematic overview of the different steps of
the sourdough proofing process. The proofing technique to choose depends
on your availability and schedule.}%
\label{fig:proofing-process}
\end{center}
\end{flowchart}
To me, the sole purpose of cold-proofing is its ability to allow you
@@ -1676,7 +1669,7 @@ An additional trick that can help you to combine the benefits
of room temperature-proofing and easy cold-proofing scoring
is to place your dough in the freezer for 30~minutes before baking.
Once you notice your dough is almost done proofing, move it to the
freezer. The freezer will dry out the doughs's surface even further
freezer. The freezer will dry out the dough's surface even further
while also lowering its viscosity, making scoring easier.
Another interesting trick is to bake your dough for 30 seconds without steam.

View File

@@ -5,6 +5,7 @@ DOCKER_CMD := docker run --rm -it -v $(PWD):/opt/repo --platform linux/x86_64 $(
.PHONY: bake build_pdf build_docker_image push_docker_image validate website
.PHONY: print_os_version start_shell printvars show_tools_version mrproper
.PHONY: build_serif_pdf build_ebook booklet
# Dockers targets
build_docker_image:
@@ -24,11 +25,14 @@ build_pdf:
$(DOCKER_CMD) "cd /opt/repo/book && make"
bake:
$(DOCKER_CMD) "cd /opt/repo/book && make -j bake"
$(DOCKER_CMD) "cd /opt/repo/book && make bake"
website:
$(DOCKER_CMD) "cd /opt/repo/book && make website"
booklet:
$(DOCKER_CMD) "cd /opt/repo/book && make build_booklet"
mrproper:
$(DOCKER_CMD) "cd /opt/repo/book && make mrproper"

View File

@@ -5,6 +5,8 @@ GEM
method_source (1.0.0)
nokogiri (1.15.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.3-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.15.3-x86_64-linux)
racc (~> 1.4)
pry (0.14.2)
@@ -14,6 +16,7 @@ GEM
PLATFORMS
arm64-darwin-22
x86_64-darwin-22
x86_64-linux
DEPENDENCIES

BIN
website/assets/arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

BIN
website/assets/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

View File

@@ -52,19 +52,27 @@ class ModifyBuild
text = fix_titles(text)
text = fix_menu(text)
text = fix_cover_page(text) if is_cover_page?(filename)
text = add_header_banner(text)
text = add_home_link_to_menu(text)
text = fix_anchor_hyperlinks_menu(text)
text = add_favicon(text)
text = add_meta_tags(text, filename)
text = remove_section_table_of_contents(text)
text = mark_menu_as_selected_if_on_page(text, extract_file_from_path(filename))
text = add_canonical_for_duplicates(text, extract_file_from_path(filename))
text = include_javascript(text)
text = add_text_to_coverpage(text, extract_file_from_path(filename))
text = fix_js_dependency_link(text)
text = fix_list_of_tables_figures_duplicates(text)
text = add_anchors_to_headers(text)
text = create_menu_groups(text)
text = fix_top_links(text)
text = fix_flowchart_background(text)
text = remove_empty_menu_links(text)
text = fix_bottom_cross_links(text)
text = insert_mobile_header_graphic(text)
text = fix_https_links(text)
text = add_anchors_to_glossary_items(text) if is_glossary_page?(filename)
text = mark_menu_as_selected_if_on_page(text, extract_file_from_path(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)
File.open(filename, "w:UTF-8") {|file| file.puts text }
@@ -76,6 +84,10 @@ class ModifyBuild
end
end
def is_glossary_page?(filename)
filename.include?("Glossary.html")
end
def is_list_figures_tables?(filename)
["listfigurename.html", "listtablename.html", "listoflocname.html", "bibname.html"].any? do |name|
filename.include?(name)
@@ -147,6 +159,45 @@ class ModifyBuild
doc.to_html
end
def create_menu_groups(text)
doc = build_doc(text)
groups = build_groups(doc.css(".menu-items > span"))
menu_el = doc.css(".menu-items")[0]
html = ""
groups.each do |group|
out = ""
group.each do |g|
if g.to_html.length > 0
out += %Q{<div class="menu-entry">#{g.to_html}</div>}
end
end
html += %Q{<div class="menu-group">
<div class="menu-inner">
#{out}
</div>
<img class="menu-arrow" src="arrow.png" />
</div>}
end
menu_el.inner_html = html
doc.to_html
end
def build_groups(menu_items)
final_groups = []
tmp_groups = []
menu_items.each_with_index do |el, index|
# Get next item and check if it is a lower entry level in the menu.
next_item = menu_items[index + 1]
if next_item && next_item["class"].include?("chapterToc") || next_item.nil?
final_groups.push(tmp_groups.push(el))
tmp_groups = []
else
tmp_groups.push(el)
end
end
final_groups
end
# By default the titles look boring. This changes the titles of all the
# pages and adds the book name as appendix
def fix_titles(text)
@@ -232,7 +283,7 @@ class ModifyBuild
content = doc.css("body > .main-content")[0]
menu = doc.css("body > nav")[0]
content = %Q{
<main class="titlepage">
<main class="titlepage main-content">
<a href="Thehistoryofsourdough.html">
<img src="cover-page.jpg" />
<div class="version"><p>#{version}</p></div>
@@ -252,7 +303,7 @@ class ModifyBuild
menu = doc.css(".menu-items")[0]
return text if menu.nil?
home_html = %Q{<span class="chapterToc home-link"><a href="/">The Sourdough Framework</a></span>}
home_html = %Q{<span class="chapterToc home-link"><a href="/">🍞 The Sourdough Framework</a></span>}
# Normally the flowcharts link should be automatically added, but there
# seems to be a problem in the generation. See:
# https://github.com/hendricius/the-sourdough-framework/pull/188 for more
@@ -263,12 +314,12 @@ class ModifyBuild
<span class="link_text">List of Flowcharts</span>
</a>
</span>
<span class="chapterToc">
<span class="chapterToc listtables-menu">
<a href="listtablename.html">
<span class="link_text">List of Tables</span>
</a>
</span>
<span class="chapterToc">
<span class="chapterToc listfigures-menu">
<a href="listfigurename.html">
<span class="link_text">List of Figures</span>
</a>
@@ -305,7 +356,7 @@ class ModifyBuild
<span class="chapterToc">
<a href="https://breadco.de/kofi">
<span class="chapter_number">⭐️</span>
<span class="link_text">Donate</span>
<span class="link_text">Support me</span>
</a>
</span>
}
@@ -313,6 +364,38 @@ class ModifyBuild
doc.to_html
end
# Adds a header banner to each page
def add_header_banner(text)
doc = build_doc(text)
body = doc.css("body")[0]
footnotes = doc.css(".footnotes")[0]
main = doc.css(".main-content")[0]
menu = doc.css(".menu")[0]
if main.nil? || menu.nil?
#raise ArgumentError.new("Don't know how to handle")
return doc.to_html
end
body.inner_html = %Q{
<div class='wrapper'>
#{build_header_html}
<div class='book-content'>
#{menu.to_html}
<main class='main-content'>
#{main.inner_html}
#{footnotes ? footnotes.to_html : ''}
</main>
</div>
</div>
}
return doc.to_html
end
def build_header_html
%Q{
<div class="header"><a href="/"><img src="banner.png"></a></div>
}
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)
@@ -430,13 +513,14 @@ class ModifyBuild
"Sourdoughstartertypes.html" => "og_image_sourdough_starter_types.png",
"Storingbread.html" => "og_image_storing_bread.png",
"Thehistoryofsourdough.html" => "og_image_the_history_of_sourdough.png",
"Wheatsourdough.html" => "og_image_troubleshooting.png",
"Wheatsourdough.html" => "og_image_wheat_sourdough.png",
"Troubleshooting.html" => "og_image_troubleshooting.png",
"Mixins.html" => "og_image_mixins.png",
}
end
def mark_menu_as_selected_if_on_page(text, filename)
doc = build_doc(text)
return doc.to_html
selected = doc.css(".menu-items .chapterToc > a").find do |el|
el["href"] == ""
@@ -451,7 +535,17 @@ class ModifyBuild
# 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
if "listoflocname.html" == filename
doc.css(".menu-items .chapterToc.flowcharts-menu")[0].add_class("selected")
doc.css(".menu-items .chapterToc.flowcharts-menu")[0].ancestors(".menu-group")[0].add_class("selected")
return doc.to_html
end
if "listtablename.html" == filename
doc.css(".menu-items .chapterToc.listtables-menu")[0].ancestors(".menu-group")[0].add_class("selected")
return doc.to_html
end
if "listfigurename.html" == filename
doc.css(".menu-items .chapterToc.listfigures-menu")[0].ancestors(".menu-group")[0].add_class("selected")
return doc.to_html
end
@@ -460,7 +554,7 @@ class ModifyBuild
# Fix that when the menu is selected the href is empty. This way users can
# click the menu and the page will reload.
selected["href"] = filename
selected.parent.add_class("selected")
selected.ancestors(".menu-group")[0].add_class("selected")
doc.to_html
end
@@ -491,14 +585,28 @@ class ModifyBuild
def add_text_to_coverpage(text, filename)
return text unless is_cover_page?(filename)
doc = build_doc(text)
content = doc.css(".titlepage")[0]
raise ArgumentError.new(".titlepage not found in HTML") if content.nil?
content.add_class("main-content")
content = doc.css(".main-content")[0]
content.inner_html = "#{build_cover_page_content} #{content.inner_html}"
doc.to_html
end
def add_anchors_to_glossary_items(text)
doc = build_doc(text)
content = doc.css("dt.description")
content.each do |el|
term = el.css("span")[0]
item_name = term&.text
# No anchor for whatever reason
next unless item_name
anchor = item_name.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
copy_link = %Q{<a href="#term-#{anchor}" class="permalink">🔗</a>}
el.set_attribute("id", "term-#{anchor}")
term.inner_html = "#{term.inner_html}#{copy_link}"
end
doc.to_html
end
def build_cover_page_content
%Q{
<h2 class="chapterHead home-title">
@@ -521,7 +629,9 @@ class ModifyBuild
to everyone, I have decided to make it available as a free digital download.
</p>
<img alt="One of my best Sourdough Breads" class="home-bread" src="bread.jpg" />
<a href="bread.jpg">
<img alt="One of my best Sourdough Breads" class="home-bread" src="bread.jpg" />
</a>
<p class="noindent">
However, producing and maintaining resources like this requires
@@ -605,13 +715,10 @@ class ModifyBuild
# this.
def fix_menus_list_figures_tables(text)
doc = build_doc(text)
content = doc.css(".menu-items > .subsectionToc, .menu-items > .sectionToc")
content = doc.css(".menu-group .subsectionToc, .menu-group .sectionToc")
content.each do |node|
node.remove
node.ancestors(".menu-entry")[0].remove
end
doc.css(".menu-items > .lotToc").each(&:remove)
doc.css(".menu-items > .lofToc").each(&:remove)
doc.css(".menu-items > br").each(&:remove)
doc.to_html
end
@@ -623,7 +730,7 @@ class ModifyBuild
doc.to_html
end
# For some reason the depdency is missing a // in the url.
# For some reason the dependency is missing a // in the url.
def fix_js_dependency_link(text)
text.gsub("https:/cdn.jsdelivr.net", "https://cdn.jsdelivr.net")
end
@@ -651,6 +758,63 @@ class ModifyBuild
def fix_https_links(text)
text.gsub(/https:\/(?!\/)/, 'https://')
end
def fix_top_links(text)
doc = build_doc(text)
el = doc.css(".crosslinks-top")[0]
el.remove if el
doc.to_html
end
def remove_empty_menu_links(text)
doc = build_doc(text)
menus = doc.css(".menu-group")
menus.each do |m|
element = m.css("span.chapterToc")[0]
next unless element
if element.inner_html == "" || element.inner_html == " "
m.remove
end
end
doc.to_html
end
def insert_mobile_header_graphic(text)
doc = build_doc(text)
content = doc.css(".TOC.menu")[0]
content.after('<div class="mobile-banner"><a href="/"><img src="banner.png" /></a></div>')
doc.to_html
end
def fix_flowchart_background(text)
doc = build_doc(text)
images = doc.css("img")
images.each do |img|
src = img.attr("src")
is_flowchart = src.include?(".svg")
next unless is_flowchart
img.parent.add_class("flowchart-image-wrapper")
end
doc.to_html
end
def fix_bottom_cross_links(text)
doc = build_doc(text)
link_cont = doc.css(".crosslinks-bottom")[0]
return doc.to_html unless link_cont
links = doc.css(".crosslinks-bottom a")
prev_link = links.find {|l| l.inner_html == "prev" }
next_link = links.find {|l| l.inner_html == "next" }
prev_html = prev_link ? "<a class='prev' href='#{prev_link.attr('href')}'>Previous page</a>" : ''
next_html = next_link ? "<a class='next' href='#{next_link.attr('href')}'>Next page</a>" : ''
link_cont.inner_html = %Q{
#{prev_html}
#{next_html}
}
doc.to_html
end
end
ModifyBuild.build