Merge branch 'release' into external-content-teachbooks-v0.2.0

This commit is contained in:
Robert Lanzafame 2025-04-02 05:52:17 +02:00
commit 89fe14cc34
75 changed files with 796 additions and 231 deletions

8
.gitmodules vendored
View file

@ -18,10 +18,6 @@
path = book/external/Sphinx-Image-Inverter
url = https://github.com/TeachBooks/Sphinx-Image-Inverter.git
branch = Manual
[submodule "book/external/JupyterBook-Patches"]
path = book/external/JupyterBook-Patches
url = https://github.com/TeachBooks/JupyterBook-Patches.git
branch = manual_docs
[submodule "book/external/Download-Link-Replacer"]
path = book/external/Download-Link-Replacer
url = https://github.com/TeachBooks/Download-Link-Replacer.git
@ -58,3 +54,7 @@
path = book/external/Sphinx-PRIME-applets
url = https://github.com/TeachBooks/Sphinx-PRIME-applets.git
branch = manual
[submodule "book/external/JupyterBook-Patches"]
path = book/external/JupyterBook-Patches
url = https://github.com/TeachBooks/JupyterBook-Patches.git
branch = manual_docs

51
CITATION.cff Normal file
View file

@ -0,0 +1,51 @@
# This CITATION.cff file was generated with cffinit.
# Visit https://bit.ly/cffinit to generate yours today!
cff-version: 1.2.0
message: 'If you use this Book, please cite it using these metadata.'
authors:
- email: info@teachbooks.io
name: 'TeachBooks Development Team'
website: 'https://teachbooks.io/'
title: 'TeachBooks Manual source code'
preferred-citation:
type: book
authors:
- email: info@teachbooks.io
name: 'TeachBooks Development Team'
website: 'https://teachbooks.io/'
url: 'https://doi.org/10.5281/zenodo.15100847'
identifiers:
- type: doi
value: 10.5281/zenodo.15100848
description: Zenodo record
- type: url
value: 'https://teachbooks.io/manual/'
description: 'Published book on GitHub Pages'
- type: url
value: 'https://github.com/TeachBooks/manual'
description: 'GitHub repository'
abstract: >-
his manual assists you in creating and collaborating on JupyterBooks
for educational purposes. Some parts are specifically aimed for
teachers at Delft University of Technology, although all material and
tools are openly available. This manual aims at providing an easy start
and advanced usages for new and existing users with or without skills
on this topic.
keywords:
- TeachBooks
- Manual
- 'Jupyter Book'
title: 'TeachBooks Manual'
institution:
name: 'TeachBooks'
license: CC-BY-4.0
license-url: 'https://creativecommons.org/licenses/by/4.0/'
copyright: '© 2025 TeachBooks'
version: v1.2.1
date-released: '2025-03-28'
languages:
- en
contact:
- email: info@teachbooks.io
name: 'TeachBooks Development Team'

View file

@ -1,5 +1,6 @@
# TeachBooks Manual
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15100848.svg)](https://doi.org/10.5281/zenodo.15100848)
[![call-deploy-book](https://github.com/TeachBooks/manual/actions/workflows/call-deploy-book.yml/badge.svg)](https://github.com/TeachBooks/manual/actions/workflows/call-deploy-book.yml)
This manual assists you in creating and collaborating on [JupyterBooks](https://jupyterbook.org/) for educational purposes. Some parts are specifically aimed for teachers at Delft University of Technology, although all material and tools are openly available. This manual aims at providing an easy start and advanced usages for new and existing users with or without skills on this topic. it is part of TeachBooks, for more information visit [https://teachbooks.io/](https://teachbooks.io/).

4
WAIVER Normal file
View file

@ -0,0 +1,4 @@
Technische Universiteit Delft hereby disclaims all copyright interest in the
program “TeachBooks Manual” (a book serving as documentation for various tooling
surrounding TeachBooks) written by the Author(s).
Stefan Aarninkhof, Dean of Civil Engineering & Geosciences

View file

@ -51,7 +51,7 @@ sphinx:
tex:
macros:
"newcolor": ['\definecolor{newcolor}{RGB}{111, 29, 119}{\color{newcolor}#1}',1]
named_colors_custom_colors: {'onlylight':[165,21,160],'lightanddark':[45,180,117,204,158,110],'hyphen-color':[45,180,117,165,21,160]}
named_colors_custom_colors: {'onlylight':[165,21,160],'lightanddark':[45,180,117,204,158,110],'hyphen-color':[45,180,117,165,21,160],'attributiongrey':[150,150,150]}
local_extensions:
apastyle: _ext/
bracket_citation_style: _ext/

View file

@ -0,0 +1,4 @@
/* Attribution */
div.attribution > .admonition-title::after {
content: "\f10d";
}

178
book/_static/power.html Normal file
View file

@ -0,0 +1,178 @@
<!DOCTYPE html>
<html>
<head>
<title>CO2 vs Power</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<style>
.slider {
display: block;
margin-bottom: 10px;
width: 100%;
}
.slider-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
width: 100%;
}
.output {
margin-top: 20px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}
.output p {
margin: 5px 0;
}
.output .emoji {
font-size: 20px;
margin-right: 5px;
}
</style>
</head>
<body>
<div id="sliderContainer" class="slider-container"></div>
<div id="outputContainer" class="output"></div>
<script>
var RPM = [800, 1000, 1200, 1400, 1700, 1800];
var CO2 = [708, 696.889, 688.247, 682.897, 684.955, 697.3];
var POW = [161.141, 263.243, 330.51, 381.561, 391.17, 370];
function weighted_obj(s) {
var delta_p = 1 / 3;
var delta_c = 1 - delta_p;
return -delta_p * POWfunc(s) + delta_c * CO2func(s);
}
var Pt = 460;
var Ct = 640;
function goal_attainment(s) {
return Math.max(Pt - POWfunc(s), CO2func(s) - Ct);
}
function CO2func(s) {
return interpolate(RPM, CO2, s);
}
function POWfunc(s) {
return interpolate(RPM, POW, s);
}
function interpolate(x, y, s) {
var i = 1;
while (x[i] < s) {
i++;
}
var x0 = x[i - 1];
var x1 = x[i];
var y0 = y[i - 1];
var y1 = y[i];
var t = (s - x0) / (x1 - x0);
// Calculate the coefficients for the cubic spline interpolation
var h = x1 - x0;
var a = (1 - t) * (1 - t) * (1 - t);
var b = 3 * t * (1 - t) * (1 - t);
var c = 3 * t * t * (1 - t);
var d = t * t * t;
// Perform cubic spline interpolation
var interpolatedValue = a * y0 + b * y[i - 1] + c * y[i] + d * y1;
return interpolatedValue;
}
function func(x) {
var weighted_obj_val = weighted_obj(x).toFixed(2);
var goal_attainment_val = goal_attainment(x).toFixed(2);
var outputContainer = document.getElementById("outputContainer");
var weighted_obj_val = weighted_obj(x).toFixed(2);
var goal_attainment_val = goal_attainment(x).toFixed(2);
var POWfunc_val = POWfunc(x).toFixed(2);
var CO2func_val = CO2func(x).toFixed(2);
outputContainer.innerHTML = "<p>Weighted 🏋️ Objective: " + " = - 1/3 * POWfunc(" + x + ") + 2/3 * CO2func(" + x + ") = - 1/3 * " + POWfunc_val + " + 2/3 * " + CO2func_val + " = " + weighted_obj_val + "</p>" +
"<p>Goal 🥅 Attainment: max(460 - POWfunc(" + x + "), CO2func(" + x + ") - 640) = max(460 - " + POWfunc_val + ", " + CO2func_val + " - 640) = " + goal_attainment_val ;
var plotContainer = document.createElement("div");
plotContainer.id = "plotContainer";
plotContainer.style.height = "400px";
outputContainer.appendChild(plotContainer);
var plotData = [
{
x: [CO2func(parseFloat(document.getElementById("x").value))],
y: [POWfunc(parseFloat(document.getElementById("x").value))],
type: 'scatter',
mode: 'markers',
name: 'Selected RPM'
}
];
var plotLayout = {
xaxis: {
title: 'CO2 (g/kWh)',
range: [680, 710]
},
yaxis: {
title: 'Power functions (kW)',
range: [400, 150], // Flipped y-axis range
},
title: {
text: 'CO2 vs Power',
font: {
size: 16
}
}
};
Plotly.newPlot('plotContainer', plotData, plotLayout);
}
var sliderContainer = document.getElementById("sliderContainer");
var xSlider = document.createElement("input");
xSlider.type = "range";
xSlider.min = 800;
xSlider.max = 1800;
xSlider.value = 1000;
xSlider.step = 1;
xSlider.id = "x";
xSlider.oninput = function() {
func(parseFloat(document.getElementById("x").value));
};
xSlider.classList.add("slider");
var xLabel = document.createElement("label");
xLabel.innerHTML = "RPM";
xLabel.setAttribute("for", "x");
xLabel.style.textAlign = "right";
var valueDisplay = document.createElement("span");
valueDisplay.innerHTML = xSlider.value; // Set the initial value of the display element
valueDisplay.style.marginLeft = "10px"; // Add some margin to separate the value from the slider
xSlider.oninput = function() {
valueDisplay.innerHTML = xSlider.value; // Update the value display element when the slider value changes
func(parseFloat(document.getElementById("x").value));
};
sliderContainer.appendChild(xLabel);
sliderContainer.appendChild(xSlider);
sliderContainer.appendChild(valueDisplay); // Append the value display element
var outputContainer = document.getElementById("outputContainer");
outputContainer.style.height = "400px";
// Call func with initial values
func(parseFloat(document.getElementById("x").value));
</script>
</body>
</html>

View file

@ -72,8 +72,9 @@ parts:
- file: external/Download-Link-Replacer/README.md
- file: external/Sphinx-launch-buttons/README.md
- file: basic-features/utterances.md
- file: features/jupyterquiz.ipynb
- file: features/h5p.md
sections:
- file: examples/h5p_examples.md
- file: features/plotly.ipynb
- file: external/Sphinx-Grasple-public/README.md
- file: features/HTML_javascript.md
@ -84,6 +85,7 @@ parts:
sections:
- file: features/widgets.ipynb
- file: features/exercise_checking.ipynb
- file: features/jupyterquiz.ipynb
- file: external/sphinx-iframes/README.md
- file: external/Sphinx-PRIME-applets/README.md
- file: features/visuals.md
@ -103,7 +105,6 @@ parts:
chapters:
- file: examples/overview.md
- file: examples/book_structure.md
- file: examples/h5p_examples.md
- file: examples/live_code.md
- file: examples/example_gumbel.ipynb
- file: examples/theory_questions.md
@ -117,6 +118,7 @@ parts:
- file: helper_code/intro.md
sections:
- file: helper_code/converter.md
- file: helper_code/move_images.md
- file: external/Useful_python_code/snippit.ipynb
- file: external/Useful_python_code/extensionfildownloadreturn.ipynb
- file: external/Useful_python_code/figshrinker.ipynb

View file

@ -49,13 +49,13 @@ The basic code syntax for creating a button is as follows:
:color: primary
```
```
```{button-ref} ../features/overview.md
[](../features/overview.md)
```{button-ref} feature_overview
:color: secondary
```
```
```{button-ref} ../features/overview.md
```{button-ref} feature_overview
:color: secondary
```
```

View file

@ -29,9 +29,11 @@ $$ F = m \cdot a = 10 \cdot 9.81 = 98 \text{N}$$
To number the equations and refer in text, you need to provide a label to the equation. Just put the label between brackets and place it after the last \$\$, like this:
$$
F = m \cdot a
$$ (newtons_second_law)
```md
$$
F = m \cdot a
$$ (newtons_second_law)
```
Resulting in:

View file

@ -1,11 +1,13 @@
# Making comments on the website: Hypothesis
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 1-5.
```
{bdg-warning}`Javascript overlay` {bdg-success}`Chrome Extension`
````
# Making comments on the website: Hypothesis
Hypothesis is a third-party application that allows anyone to make publicly visible comments on a website (once you create a free account). This section explains how to use and install the extension. As this tool requires an account with a third-party, we advise to use our [local-annotator](../external/annotater/README.md) with similar capabilities but which store annotations locally. By default Hypothesis stores annotations publicly, which might confuse other students.

View file

@ -1,8 +1,10 @@
# Original Jupyter Book and Sphinx Features
````{margin}
```{admonition} User types
:class: tip
This section is useful for [user type 3-5](../installation-and-setup/user_types.md).
```
````
# Original Jupyter Book and Sphinx Features
These pages will provide a list of some common, basic book features which are all available in the original <a href="https://jupyterbook.org/"><img style="display:inline-block; height:1.5em; width:auto; transform:translate(0, -0.15em)" src="../images/logo-wide.svg" alt="Jupyter book"></a> package. Additionally, this page includes also best-practices.

View file

@ -1,11 +1,13 @@
# Discussions in your book: Utterances
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 3-5.
```
{bdg-white}`GitHub app and Javascript script`
````
# Discussions in your book: Utterances
[Utterances 🔮](https://utteranc.es/) is a lightweight open-source widget which allows you, your colleages and your students to discuss stuff in a blog post in your book. It is build on GitHub issues, so requires a GitHub repository, although the book can be hosted anywhere (so also on GitLab).

View file

@ -5,11 +5,13 @@ You can refer to this book in its entirety as:
> TeachBooks Development Team (2024), _TeachBooks Manual_. https://github.com/TeachBooks/manual. Retreived [Month, Year]. CC BY 4.0.
This book is already registered on Zenodo: [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15100848.svg)](https://doi.org/10.5281/zenodo.15100848)
The introduction, structure and decisions on content is done under direction of the TeachBooks Development Team. The content is written by many contributors, of which there are many.
We anticipate that the content of this book will change continuously. Therefore, if you'd like to refer to a specific chapter, we recommend using the source code directly with the citation that refers to the GitHub repository and lists the date and name of the file. Although content will be added over time, chapter titles and URL's in this book are expected to remain relatively static after Spring 2025. You can refer to individual chapters or pages within this book as:
We anticipate that the content of this book will change continuously. Therefore, if you'd like to refer to a specific chapter, we recommend using the source code directly with the citation that refers to the GitHub repository and lists the date and name of the file. Although content will be added over time, chapter titles and URL's in this book are expected to remain relatively static. You can refer to individual chapters or pages within this book as:
> `<Primary Author>` (2024), `<Title of Chapter or Page>`. In _TeachBooks Manual_. https://github.com/TeachBooks/manual (chapter `./book/intro/`, retrieved [`<date>`]).
> `<Title of Chapter or Page>`. In _TeachBooks Manual_. https://github.com/TeachBooks/manual (chapter `./book/intro/`, retrieved [`<date>`]).
Better yet, include a link to the specific commit! _If you know what this means, we assume you know how to do it._

View file

@ -6,7 +6,7 @@
"tags": []
},
"source": [
"# Programming assignment\n",
"# Programming assignment with checks\n",
"\n",
"This page shows how you can recreate the classical Jupyter Notebook assignments that are given in many courses to a Jupyter Book format with live coding. A widget has been implemented to check the answers, of which the data is included in a separate python file. The page automatically loads and a custom download page has been added\n",
"\n",

View file

@ -1,14 +1,4 @@
# Types of H5p Quizzes
This page will show some examples of H5p quizzes built into a variety of TeachBooks to allow the students to test their understanding of the content as they read. H5p quizzes can be used to create a set of Multiple Choice, Drag and Drop, Fill in the blanks, True/False and Image choice questions so the applications are quite versitile and your imagination can be used in creating the questions.
## Getting started with H5p
Some best-practices on the use of H5p:
- To startup your H5p-account, first login to H5p via Brightspace. You can follow instructions as under [https://www.tudelft.nl/teaching-support/educational-tools/h5p](https://www.tudelft.nl/teaching-support/educational-tools/h5p).
- After that, direct login is possible via [tudelft.h5p.com](https://tudelft.h5p.com)
- Place your H5p-elements in a shared folder in H5p.
- Disable the display options "Toolbar Below Content" and "Display author's name to public (anonymous users) (only relevant when content's status is set to Public )" for each
# Examples of H5p Quizzes
## Dialog cards
@ -28,27 +18,19 @@ Problem Statement
As can be seen on the right-hand-side menu, the sub-chapter includes the problem statement, the elaboration on the model and solution method and finally an exercise for the student. The code in the page is activated by pressing the live code button which will make the code cells editable and executable. Additionally, interactive figures are included into the text with movable sliders to directly see the effect of the changes made.
```{figure} figures/Live_code2.PNG
---
width: 600
align: center
---
Interactive Graph
```{iframe} ../_static/power.html
:height: 580px
:width: 100%
```
The H5p quizzes can shine in the section on questions, discussions and comments. Next to many multiple choice questions (which are discussed later) there are dialog cards which can ask more conceptual and open ended questions. Pressing on the blue button `Turn` will flip around the card and reveal the model answer. The great thing about the integration of both interactive aspects (coding and questions) helps the student to play around with the code and understand the topic from a less theoretical point-of-view.
```{figure} figures/cards1.PNG
---
width: 700
align: center
---
Dialoge Card
```{h5p} https://tudelft.h5p.com/content/1292260184374358717/embed
```
**Try it out!**
```{h5p} https://tudelft.h5p.com/content/1292260188487459217/embed
```
<iframe src="https://tudelft.h5p.com/content/1292050206829217497/embed" aria-label="PA1 File Contents" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
## Question Set
@ -58,20 +40,10 @@ Question sets consist of a question and one or more possible answers to that que
The following question sets are taken from chapter 3.3. Weighted least-squares estimation of the MUDE 23/24 book. The chapter builds on the previous chapter on simple least-squares estimation and dwelves into the importance and properties of the weight matrix. The student is primarily quizzed using multiple choice questions to check their understanding. The answers can be provided in the shape of text, figures, equations, matrices and probably much more.
```{figure} figures/Question_set_1.PNG
---
width: 600
align: center
---
Text Answers
```{h5p} https://tudelft.h5p.com/content/1292060781042105617/embed
```
```{figure} figures/Question_set_2.PNG
---
width: 600
align: center
---
Equations Answers
```{h5p} https://tudelft.h5p.com/content/1292046737060674407/embed
```
Since these questions are meant to develop the understanding of the students, feedback is vital! Feedback can be built into the questions to explain the reasoning behind a correct answer.
@ -96,7 +68,8 @@ Tips
Have a look at the following 7 questions.
<iframe src="https://tudelft.h5p.com/content/1292062157562749767/embed" aria-label="quiz_uniform_motion" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
```{h5p} https://tudelft.h5p.com/content/1292062157562749767/embed
```
## Complex fill in the blanks
@ -106,12 +79,7 @@ The complex fill in the blanks can be used to evaluate numerical answers.
Chapter 3.7. Non-linear least-squares estimation from the MUDE 23/24 book makes use of the complex fill in the blanks quiz in order to check that the students understood the composition of the Jacobian Matrix specifically used in deriving the linearized functional model. This model is essential for accurately estimating values and assessing system behavior of complex processes that arent linear.
```{figure} figures/blanks1.PNG
---
width: 600
align: center
---
Answer Boxes
```{h5p} https://tudelft.h5p.com/content/1292064774866067777/embed
```
As you can see, the precision of the answer sought for is specified and the figure below shows again the incorporation of feedback.
@ -125,18 +93,24 @@ Wrong Answer + Feedback
**MUDE - Optimization**
Since the cells can be used to evaluate numerical answers, they are an easy way to quiz the student on matrices and evaluate the result of each position indidependently. The optimization team of MUDE took this a step further and used this set-up to quiz the students on the SIMPLEX method. This method automates the solving of the augmented form of a linear programing problem with continuous variables. It makes use of tables and the manipulation of equations to find the optimal vaues. Unfortunately, with a large number of variables this tables tend to get quite big and filling in the cells becomes laborous.
Since the cells can be used to evaluate numerical answers, they are an easy way to quiz the student on matrices and evaluate the result of each position independently. The optimization team of MUDE took this a step further and used this set-up to quiz the students on the SIMPLEX method. This method automates the solving of the augmented form of a linear programming problem with continuous variables. It makes use of tables and the manipulation of equations to find the optimal values. Unfortunately, with a large number of variables this tables tend to get quite big and filling in the cells becomes laborious.
```{figure} figures/blanks3.PNG
---
width: 600
align: center
---
SIMPLEX Method
```{h5p} https://tudelft.h5p.com/content/1292131432784432037/embed
```
**Try it out!**
**Truss structure**
<iframe src="https://tudelft.h5p.com/content/1292010272694757307/embed" aria-label="Example MUDE" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
Truss structures are modelled as rigid bars (so elements which cannot deform) connected by hinges (so elements can rotate with respect to one each other). In our model, hinges are indicate with a circle, and bars with a line. For example, the structure you've seen in the second example (with two diagonal bars removed) is modelled as follows:
```{figure} ../images/Truss1.svg
:name: truss structure
Bars and hinges in truss structure
```
Now that you've been introduced to truss structures, answer the following question:
```{h5p} https://tudelft.h5p.com/content/1291910926067816717/embed
```
## True or False
@ -154,18 +128,15 @@ align: center
Problem Statement
```
```{figure} figures/truefalse1.PNG
---
width: 600
align: center
---
True or False
The small circles below the question indicates that there are more questions in this series which can be viewed by clicking on the blue arrow pointing towards the left or right. Open the second, fourth and fifth question:
```{h5p} https://tudelft.h5p.com/content/1292120485436114287/embed
```
The small circles below the question indicates that there are more questions in this series which can be viewed by clicking on the blue arrow pointing towards the left or right.
**Try it out!**
<iframe src="https://tudelft.h5p.com/content/1292061623388939257/embed" aria-label="quiz_blue_vs_LS" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script>
```{h5p} https://tudelft.h5p.com/content/1292061623388939257/embed
```
## Drag and Drop
@ -173,16 +144,15 @@ Drag and Drop questions are useful to make the distinction between different con
**MUDE - Optimization**
In this chapter, it was important that the students made the distinction between the terminology and mathematical meaning between different elements of the graphical solution method. A drag and drop question was used to link the term to its definition. The answer boxes can be dragged to the correct title in a playful manner.jup
In this chapter, it was important that the students made the distinction between the terminology and mathematical meaning between different elements of the graphical solution method. A drag and drop question was used to link the term to its definition. The answer boxes can be dragged to the correct title in a playful manner.
```{figure} figures/drag1.PNG
---
width: 600
align: center
---
Drag and Drop
The fourth question in this question set is a drag and drop question:
```{h5p} https://tudelft.h5p.com/content/1292121213033110307/embed
```
The correct answer leads to:
```{figure} figures/drag2.PNG
---
width: 600

@ -1 +1 @@
Subproject commit f69e970a8da7d85e5473c7e5f58299a2ee3cf331
Subproject commit 6318fd9db4b465bf56b06085ca55c79a8a818471

View file

@ -1 +0,0 @@
3a1ed3738693931fb735810cbc7a9a5734e85788

1
book/external/JupyterBook-Patches vendored Submodule

@ -0,0 +1 @@
Subproject commit 8346c8c3c8be3d221a62a2f18c4ee1d4570ee003

@ -1 +1 @@
Subproject commit a8e57da25302d47806ad1fe4288950c438562199
Subproject commit 70dfd28f5f288118bb75d219b809f03474aa89a2

@ -1 +1 @@
Subproject commit f4eff8d1565eaf127898f2fe216cf5208684fb27
Subproject commit ce057a20bb234006ddebc80c9894842d125a5b1b

@ -1 +1 @@
Subproject commit 250103c723aa782bcec785ae3d241cb1ffebd3d0
Subproject commit 573bb66332f682bdfe1d7936048780199e4a0e2d

@ -1 +1 @@
Subproject commit 191c2f4ac1755d3b50c6a63950eb6c2e5c035d75
Subproject commit b4b1a2e5d087336108bc15b176af1999b61dc86a

@ -1 +1 @@
Subproject commit 43ea44ccdc917234513fcd0ea1b9d5159a7dc81f
Subproject commit 14dc36bfdbf89d2d363ea2bdcbc30a64c0f7b00f

@ -1 +1 @@
Subproject commit e4b71f810a66e302243377876f39e1dc4c4a8a6b
Subproject commit 103caecd4844353c68c166fa6ebed24a868c848c

@ -1 +1 @@
Subproject commit ccec26fd77d3b6f1bb3415b5eb824b3155a397f1
Subproject commit e6070ded6ca77662a3a951893cafe265fa333e5e

@ -1 +1 @@
Subproject commit 7fbdbbf720c27112fb58bcf7826225197e39357b
Subproject commit 81e923516e06441fb0c04f4946819f5dae9b0a68

@ -1 +1 @@
Subproject commit 9340b4e2856b6f2de331c31d2b74bd9dc286d276
Subproject commit d1f41f93ffe87a305956de405dac47daaad3bc69

@ -1 +1 @@
Subproject commit b9c76239ed042eb5befb6fa47f14d44de5113c51
Subproject commit ea450f3c0c4f9aba6438333c122543fca02c472d

@ -1 +1 @@
Subproject commit 077ba23fa29ef1f0dd454f2ebf93c107923d1068
Subproject commit 062c54a679c6dd44b948549498e755c7c5df1d73

@ -1 +1 @@
Subproject commit 338ad14d39115c620c57476931ce8fa177cf20d8
Subproject commit e4166e1389ab48ea9059e6576e56d270e66199dd

@ -1 +1 @@
Subproject commit a8958fe48c839729226e1d1765dbf26617cf6c59
Subproject commit 17b99b2de4edbcbf4d8a92fed52c3d335431699b

View file

@ -1,4 +1,4 @@
# Interactive HTML/JavaScript elements
````{margin}
```{admonition} User types
:class: tip
@ -6,6 +6,9 @@ This section is useful for user type 5.
```
{bdg-danger}`iframe`
````
# Interactive HTML/JavaScript elements
In this section, we will discuss how to [create](creating_basic_HTML_elements.md) and [embed](adding_HTML_elements.md) interactive HTML/Javascript elements created in HTML/JavaScript in a TeachBook. These HTML/Javascript element work very fluently and don't require a python kernel running in the background.

View file

@ -1,6 +1,8 @@
# Adding interactive HTML/JavaScript elements
````{margin}
{bdg-danger}`iframe`
````
# Adding interactive HTML/JavaScript elements
In this section, we will discuss how to embed interactive elements created in HTML/JavaScript in a TeachBook. If you are interested in learning how to create these elements yourself, we will discuss an example in the [next article](creating_basic_HTML_elements.md). As an example, let us discuss how to embed an interactive 3D model of a subsurface environment I created:

View file

@ -1,12 +1,14 @@
(apa)=
# APA References
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4 and 5.
```
{bdg-primary}`(To be converted into) Sphinx Extension`
````
(apa)=
# APA References
```{note}
This feature is stable but because it relies on a local extension that is part of your book files and _not_ managed as part of a computing environment (e.g., `pip` or `conda`), unknown issues may arise. We would like to convert this feature into an independent Sphinx extension and/or Pybtext plugin. Visit the [project page on GitHub](https://github.com/orgs/TeachBooks/projects/17) to learn more.

View file

@ -1,11 +1,13 @@
# Multilingual book
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4 and 5.
```
{bdg-primary}`Sphinx Extension`
````
# Multilingual book
The custom launch button extension allows you to create a customizable button in the top right of your jupyter book.
This may have many applications, one of them being that you can create different language versions of the book available for the user.

View file

@ -0,0 +1,22 @@
import os
import json
def list_file_types(directory):
file_types = set()
for root, _, files in os.walk(directory):
for file in files:
_, ext = os.path.splitext(file)
if ext: # Only include files with extensions
file_types.add(ext)
return sorted(file_types)
def format_file_types(file_types):
formatted = [f"**/*{ext}" for ext in file_types]
return formatted
if __name__ == "__main__":
book_directory = r"c:\Users\tomvanwoudenbe\Git\book\book"
file_types = list_file_types(book_directory)
formatted_file_types = format_file_types(file_types)
print("File types in the directory (formatted):")
print(json.dumps(formatted_file_types))

View file

@ -1,5 +1,6 @@
(draft-release)=
# Draft-Release Workflow
````{margin}
```{admonition} User types
:class: tip
@ -9,6 +10,12 @@ This page is useful for user type 3-5.
{bdg-link-secondary}`Python Package: teachbooks <./overview#teachbooks-python-package>`
Often it is necessary to prepare, review and edit materials in parallel to material that is currently being used by students, or another target audience. This workflow enables an author to easily maintain separate versions of a book without having to repeatedly comment out lines of a table of contents or page when building different versions. It is also easy to implement in CI/CD settings (it is already implemented in the {ref}`Deploy Book Workflow <deploy-book-workflow>`, which builds our TeachBooks).
````
(teachbooks-package)=
# Draft-Release Workflow
Often it is necessary to prepare, review and edit materials in parallel to material that is currently being used by students, or another target audience. This workflow enables an author to easily maintain separate versions of a book without having to repeatedly comment out lines of a table of contents or page when building different versions. It is also easy to implement in CI/CD settings (it is already implemented in the {ref}Deploy Book Workflow <deploy-book-workflow>`, which builds our TeachBooks).
```{admonition} Why is this useful?
:class: tip

View file

@ -1,8 +1,10 @@
# Easy Editing Process
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 3-5.
```
````
# Easy Editing Process
The following tools are created by TeachBooks to ease the process of making books. We acknowledge that making books is a difficult process; it requires advanced knowledge on CLI, python packages, html-files, data-storage and website hosting. The tools in this chapter are intended for those users who lack knowledge on these topics (which includes most of the TeachBooks' community members itself).

View file

@ -1,12 +1,14 @@
(external-toc)=
# Sharing content between books in table of contents
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 3-5.
```
{bdg-link-secondary}`Python Package: teachbooks <./overview#teachbooks-python-package>`
````
(external-toc)=
# Sharing content between books in table of contents
## Introduction

File diff suppressed because one or more lines are too long

View file

@ -1,11 +1,13 @@
# H5p interactive elements
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 3-5.
```
{bdg-danger}`iframe`
````
# H5p interactive elements
## Instruction
H5p elements are interactive HTML-blocks which can be embedded in a Jupyter Book using an iframe. An H5p element can be created in the [TU Delft portal on the H5p website](https://tudelft.h5p.com/content) (sign in via Brightspace to H5p required first). The iframe code can be copied at Edit - Publish - Public - Embed code. This html code can be directly added to your markdown file using [](../external/sphinx-iframes/README.md):
@ -27,18 +29,14 @@ A full list of all available interactive elements is available on the website of
- Interactive video
- Image hotspot
More information on H5p: [Teaching Support - Educational Tools - H5P](https://www.tudelft.nl/teaching-support/educational-tools/h5p)
Some best-practices on the use of H5p:
- H5p requires its own hosting. TU Delft provides this for TU Delft employees.
- To startup your H5p-account, first login to H5p via Brightspace. You can follow instructions as under [https://www.tudelft.nl/teaching-support/educational-tools/h5p](https://www.tudelft.nl/teaching-support/educational-tools/h5p).
- After that, direct login is possible via [tudelft.h5p.com](https://tudelft.h5p.com)
- Place your H5p-elements in a shared folder in H5p.
- Disable the display options "Toolbar Below Content" and "Display author's name to public (anonymous users) (only relevant when content's status is set to Public )" for each element for a smooth experience. On the other hand, the options 'Toolbar below content' in combination with 'Allow users to download content' allow people to reuse your questions, making them more open.
- Use it in combination with [](../external/sphinx-iframes/README.md) to allow for a proper dark mode, dynamic scaling and a transparent background.
## Example
Truss structures are modelled as rigid bars (so elements which cannot deform) connected by hinges (so elements can rotate with respect to one each other). In our model, hinges are indicate with a circle, and bars with a line. For example, the structure you've seen in the second example (with two diagonal bars removed) is modelled as follows:
In the next subpage, these exampled are shown.
```{figure} ../images/Truss1.svg
:name: truss structure
Bars and hinges in truss structure
```
Now that you've been introduced to truss structures, answer the following question:
```{h5p} https://tudelft.h5p.com/content/1291910926067816717/embed
```
More information on H5p using the TU Delft provided hosting: [Teaching Support - Educational Tools - H5P](https://www.tudelft.nl/teaching-support/educational-tools/h5p)

View file

@ -7,6 +7,15 @@
"hidePrompt": true
},
"source": [
"````{margin}\n",
"```{admonition} User types\n",
":class: tip\n",
"This section is useful for user type 4-5.\n",
"```\n",
"\n",
"{bdg-secondary}`Python Package: jupyterquiz`\n",
"````\n",
"\n",
"# JupyterQuiz\n",
"\n",
"JupyterQuiz is a code-based implementation of multiple-choiche questions and numerical answer questions. This is a basic open course tool which requires you to write your quiz questions in Python language as a `dict` or to a `.json` file. An example is given below:\n",

View file

@ -4,12 +4,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interactive content: Run Python inside your book\n",
"\n",
"````{margin}\n",
"```{admonition} User types\n",
":class: tip\n",
"This section is useful for user type 5.\n",
"```\n",
"```` \n",
"\n",
"# Interactive content: Run Python inside your book\n",
"\n",
"{bdg-primary}`Sphinx Extension`\n",
"\n",
@ -85,7 +87,7 @@
"The `html_js_files` link calls for some required javascript files. `use_thebe_lite` makes sure you initiate our adapted sphinx thebe extensions. The `exclude_patterns` makes sure you import all files so that they can be accessed from your code, except for the files matching the patterns shown.\n",
"\n",
":::{note}\n",
"If you've a lot of big files which are not used by the code, the build book repository might grow a lot in size. Include unnecessary filetypes like images (i.e. `\"**/*.png`) to `exclude_patterns`. Make sure you use proper markdown or MyST syntax for referencing to images. Using HTML code might lead to figures not being available in the final book.\n",
"If you've a lot of big files which are not used by the code, the build book repository might grow a lot in size. Include unnecessary filetypes like images (i.e. `\"**/*.png`) to `exclude_patterns`. Make sure you use proper markdown or MyST syntax for referencing to images. Using HTML code might lead to figures not being available in the final book. You can use [this python script](./directories.py) to list all filetypes in your book.\n",
":::\n",
"\n",
"By `launch_buttons` you initiate the {fa}`rocket` --> {guilabel}`Live Code` on the top right corner of every page generated from a `.ipynb` file. \n",

View file

@ -1,12 +1,14 @@
(setup-local-server)=
# Local Server to view interactive elements locally
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 4-5.
```
{bdg-link-secondary}`Python Package: teachbooks <./overview#teachbooks-python-package>`
````
(setup-local-server)=
# Local Server to view interactive elements locally
Perhaps you have already noticed that when building a book and testing it locally on your computer, some features do not work the way you expect, or worse---do not work at all! This is because many interactive features rely on browser functionality to work properly, for example: Grasple/H5p iframe exercises, Sphinx-Thebe Python interactivity and HTML/Javascript elements. Although the website is _static_ (i.e., there is no code running on a webserver that generates the content), modern web browsers have their own internal computing environments that run processes to deliver the rich content we desire in our books.

View file

@ -1,3 +1,4 @@
(feature_overview)=
# Overview
As TeachBooks, we collect a suite of existing open-source software so you don't have to! Some of the software is developed with our TA's to improve the learning experience of our students and ease the book-development process for our teachers. As the open-source software landscape changes rapidly, it is essential to keep in contact and share resources amongst ourselves to minimize maintenance and downtime for our book websites and focus on what really matters: teaching!

View file

@ -7,6 +7,13 @@
"hidePrompt": true
},
"source": [
"````{margin}\n",
"```{admonition} User types\n",
":class: tip\n",
"This section is useful for user type 5.\n",
"```\n",
"````\n",
"\n",
"# Interactive plots: plotly\n",
"\n",
"The use of the [plotly](https://plotly.com/python/getting-started/) package is an example which allows you to create HTML/Javascript widgets from python code without any knowledge on HTML/Javascript."

View file

@ -1,9 +1,11 @@
# Build pull requests from forks
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 3-5.
```
````
# Build pull requests from forks
When writing a TeachBook it is useful to automatically build and view these changes online. This exactly why we designed and build the [deploy-book-workflow](../external/deploy-book-workflow/README.md) tool, which also allows for multiple versions of your book to exist at any time with customizable URL's. However, it doesn't cover all use cases. Luckily, **Read the Docs** is a free tool that can easily be used for this purpose. It also provides a very easy way to view differences between versions on each page!

View file

@ -1,8 +1,10 @@
# Additional functionality
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 4-5.
```
````
# Additional functionality
This sections includes the features developed by TeachBooks which add functionality to the book. Most of them are implemented as sphinx extensions {bdg-primary}`Sphinx Extension`, which are plugins developed for the Sphinx documentation ecosystem (which Jupyter Book is built upon). They extend or modify Sphinx’s capabilities. Since Sphinx extensions are not an integral part of jupyter-book, as opposed to original jupyter-book features, they must be installed and configured explicitly, for example in the `_config.yml` and `requirements.txt` files.

View file

@ -1,8 +1,11 @@
# TeachBooks Student-view Features
````
```{admonition} User types
:class: tip
This section is useful for user type 1-5.
```
````
# TeachBooks Student-view Features
This chapter includes some TeachBooks features which aim to improve the way students can use TeachBooks. These tools are fully student-side, they don't influence the book website and the author doesn't have to setup anything. Nevertheless, the author could point the students to the availability of these tools and use it as part of the didactical approach. These tools could also be useful for other users.

View file

@ -1,11 +1,13 @@
# Auto-updating packages
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4-5.
```
{bdg-dark}`Git Workflow`
````
# Auto-updating packages
When building your book, your making use of packages: the teachbooks and jupyterbook packages themselves, but also packages for extensions. These are regularly updated, while those updates are not necessarily taken into your book. This is all defined in the `requirements.txt` file, which is provided as part of the [template](../external/template/README.md). There are three options:
1. `requirements.txt` only contains names of packages like: `download_link_replacer`. In that case, your [deploy-book-workflow](../external/deploy-book-workflow/README.md) will take the most up-to-date version when making your book website once a week (as the chache will be cleared once a week). This might lead to unexpected changes when new version come out, although new version are in general backwards compatible.

View file

@ -1,6 +1,10 @@
# TeachBooks Versioning
````{margin}
```{attributiongrey} Attribution
:class: attribution
This page reuses adapted CC BY 3.0 content from Tom Preston-Werner {cite:t}`semver`. {fa}`quote-left`{ref}`Find out more here.<external_resources>````
````
> This page reuses adapted CC BY 3.0 content from Tom Preston-Werner {cite:t}`semver`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
# TeachBooks Versioning
Inspired by versioning systems in software management (i.e. semantic and CalVer versioning) TeachBooks suggests a versioning guideline in which the version number tells the reader about the impact of the change. This might more suitable for your online books than the more traditional way of versioning paper books (version 1, 2, etc.), because of the amount of edits which online books allow. We recommend TeachBooks versioning, which comes in two flavors:

View file

@ -1,8 +1,10 @@
# Book styling
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 1-5.
```
````
# Book styling
TeachBooks developed a few improvements of the book which improve the visual book styling.

View file

@ -6,7 +6,7 @@
"source": [
"# Ipywidgets\n",
"\n",
"If you publish widgets in a jupyter book they might (depending on your implementation) require an active python kernel for the output to be interactive. Using the [thebe-integration](../examples/live_code.md), this is possible. Note: You can circumvent the use of a kernel by using packages which don't need such a kernel, for example the [non-kernel-based widgets using Plotly](interactive_element).\n",
"If you publish widgets in a jupyter book they might (depending on your implementation) require an active python kernel for the output to be interactive. Using the [thebe-integration](../examples/live_code.md), this is possible. Note: You can circumvent the use of a kernel by using packages which don't need such a kernel, for example the [non-kernel-based widgets using Plotly](./plotly.ipynb).\n",
"\n",
"## `matplotlib` widgets\n",
"When you'd like to use `ipywidgets` in combinations with a `matplotlib` figure, import the following packages:\n",

View file

@ -0,0 +1,3 @@
# Move images to separate hosting
Storing big binary files like images in your git repository and book is not good practice: diffs on binary files don't make sense and blow up the size of your repository. Furthermore, the size of your book website blows up too. Therefore, you can consider hosting your binary files on a different server, as explained [here in an example for the MUDE-book](https://tudelft-mude.github.io/teacher/FTP.html). To take all the images of your existing book and update the relative links, [a Python script](./parse_images.py) has been developed. This script processes Markdown (`.md`) and Jupyter Notebook (`.ipynb`) files listed in a `_toc.yml` file. It identifies local image references (including MyST `figure` syntax) in these files, copies the images to a specified folder (`new_images`), and replaces the local image paths with a public URL (e.g., `https://files.mude.citg.tudelft.nl/<image_name>`).

View file

@ -0,0 +1,207 @@
"""
Script: parse_images.py
Description:
This script processes Markdown (.md) and Jupyter Notebook (.ipynb) files listed in a `_toc.yml` file.
It identifies local image references (including MyST `figure` syntax) in these files, copies the images
to a specified folder (`new_images`), and replaces the local image paths with a public URL
(e.g., `https://files.mude.citg.tudelft.nl/<image_name>`).
Key Features:
- Parses `_toc.yml` to extract all Markdown and Notebook files.
- Detects image references in Markdown files (e.g., `![alt text](image.png "title")`).
- Detects MyST `figure` syntax (e.g., `{figure} /path/to/image.png`).
- Resolves image paths relative to the file or project root.
- Handles image paths with optional titles (e.g., `"title"`) in Markdown and Notebook files.
- Skips processing images that are already converted to the public URL.
- Copies images to the `new_images` folder.
- Updates the files to replace local image paths with public URLs.
How to Use:
1. Place this script in the root directory of your project (where `_toc.yml` is located).
2. Ensure `_toc.yml` contains the list of files to process.
3. Run the script using Python: python parse_images.py
4. The script will:
- Copy referenced images to the `new_images` folder.
- Update the Markdown and Notebook files with the new image URLs.
Dependencies:
- Python 3.x
- PyYAML (install using `pip install pyyaml`)
Notes:
- Ensure the script is run from the project root directory.
- The `base_url` variable should be updated to match your desired public URL prefix.
- The script handles image paths in the following formats:
- Relative paths (e.g., `image.png`, `./image.png`).
- Absolute paths (e.g., `/path/to/image.png`).
- Paths with optional titles (e.g., `![alt text](image.png "title")`).
"""
import os
import re
import shutil
import yaml
import json
# Define the folder where images will be copied
output_folder = "new_images"
base_url = "https://files.mude.citg.tudelft.nl/"
# Ensure the output folder exists
os.makedirs(output_folder, exist_ok=True)
# Function to parse the _toc.yml file and extract all Markdown and Notebook files
def get_files_from_toc(toc_file):
files = []
with open(toc_file, "r", encoding="utf-8") as f:
toc = yaml.safe_load(f)
# Recursive function to extract file paths
def extract_files(item):
if isinstance(item, dict):
if "file" in item:
# Add the file with the appropriate extension
file_path = item["file"]
if not file_path.endswith((".md", ".ipynb")):
if os.path.isfile(file_path + ".md"):
file_path += ".md"
elif os.path.isfile(file_path + ".ipynb"):
file_path += ".ipynb"
files.append(file_path)
if "sections" in item:
for section in item["sections"]:
extract_files(section)
if "chapters" in item:
for chapter in item["chapters"]:
extract_files(chapter)
elif isinstance(item, list):
for sub_item in item:
extract_files(sub_item)
# Start extracting files from the "parts" section
extract_files(toc.get("parts", []))
return files
# Function to normalize image paths
def normalize_image_path(file_dir, image_path):
# Check if the path starts with a `/` (absolute path relative to the project root)
if image_path.startswith("/"):
# Resolve the path relative to the project root
project_root = os.getcwd() # Assuming the script is run from the project root
resolved_path = os.path.join(project_root, image_path.lstrip("/"))
else:
# Resolve the path relative to the file's directory
resolved_path = os.path.normpath(os.path.join(file_dir, image_path))
return resolved_path
# Function to find and replace local image references
def process_file(file_path):
if file_path.endswith(".md"):
process_markdown(file_path)
elif file_path.endswith(".ipynb"):
process_notebook(file_path)
# Process Markdown files
def process_markdown(file_path):
file_dir = os.path.dirname(file_path) # Get the directory of the file
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
# Find all standard Markdown image references (e.g., ![alt text](path "title"))
matches = re.findall(r"!\[.*?\]\((.*?)(?:\s+\".*?\")?\)", content)
# Find all MyST figure syntax references (e.g., {figure} path)
# Handles cases where the `---` block is missing or caption follows directly
myst_matches = re.findall(r"\{figure\}\s+(.*?)\s*(?:\n|$)", content)
matches.extend(myst_matches)
for match in matches:
# Skip if the image path is already converted to the public URL
if match.startswith(base_url):
continue
# Normalize and resolve the image path
image_path = normalize_image_path(file_dir, match)
if os.path.isfile(image_path):
print(f"Image found: {image_path}") # Debugging output
# Copy the image to the output folder
image_name = os.path.basename(image_path)
new_path = os.path.join(output_folder, image_name)
shutil.copy(image_path, new_path)
# Replace the local URL with the new URL
new_url = base_url + image_name
content = content.replace(match, new_url)
else:
print(f"Warning: Image not found: {image_path}") # Debugging output
# Write the updated content back to the file
with open(file_path, "w", encoding="utf-8") as f:
f.write(content)
# Process Jupyter Notebook files
def process_notebook(file_path):
file_dir = os.path.dirname(file_path) # Get the directory of the file
with open(file_path, "r", encoding="utf-8") as f:
notebook = json.load(f)
updated = False
for cell in notebook.get("cells", []):
if cell.get("cell_type") == "markdown":
# Join all lines in the cell into a single string
cell_content = "".join(cell.get("source", []))
# Find all standard Markdown image references (e.g., ![alt text](path "title"))
matches = re.findall(r"!\[.*?\]\((.*?)(?:\s+\".*?\")?\)", cell_content)
# Find all MyST figure syntax references (e.g., {figure} path)
myst_matches = re.findall(r"\{figure\}\s+(.*?)\s*(?:\n|$)", cell_content)
matches.extend(myst_matches)
for match in matches:
# Skip if the image path is already converted to the public URL
if match.startswith(base_url):
continue
# Normalize and resolve the image path
image_path = normalize_image_path(file_dir, match)
if os.path.isfile(image_path):
print(f"Image found: {image_path}") # Debugging output
# Copy the image to the output folder
image_name = os.path.basename(image_path)
new_path = os.path.join(output_folder, image_name)
shutil.copy(image_path, new_path)
# Replace the local URL with the new URL
new_url = base_url + image_name
cell_content = cell_content.replace(match, new_url)
updated = True
else:
print(f"Warning: Image not found: {image_path}") # Debugging output
# Split the updated content back into lines and update the cell
cell["source"] = cell_content.splitlines(keepends=True)
# Write the updated notebook back to the file if changes were made
if updated:
with open(file_path, "w", encoding="utf-8") as f:
json.dump(notebook, f, indent=2)
# Main function
def main():
toc_file = "_toc.yml" # Replace with the path to your _toc.yml file
files = get_files_from_toc(toc_file)
print("Files extracted from TOC:", files) # Debugging output
for file_path in files:
# Ensure the file has the correct extension and exists
if os.path.isfile(file_path):
print(f"Processing file: {file_path}") # Debugging output
process_file(file_path)
else:
print(f"Warning: File {file_path} not found or unsupported.")
if __name__ == "__main__":
main()

View file

@ -1,9 +1,11 @@
# Managing code-related software: Anaconda
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 5.
```
````
# Managing code-related software: Anaconda
Before you can start using python in your book, you need Anaconda. 'Anaconda's conda tool simplifies package and environment management across operating systems' (Anaconda.com), such as windows or MacOS. It makes getting started with python a lot easier because it already has a lot of useful python packages pre-installed. Unfortunately, each of these packages are themselves require a number of different packages to function properly. Do you like installing all of them? You shouldn't---but where do you get them come from? Many of those packages are packages required by only a few specific packages. These packages are called _dependencies_, and are necessary to make your Python packages function as expected. When you run install a specific package, `conda` (part of Anaconda) checks all of the dependent packages that are needed and makes sure they are also provided in the `environment` (collection of software with a specific version) that is being created. In reality, this is simply a folder on your computer with all of the `*.py` files stored in it. This _package management_ is what `conda` and `pip` are really doing when you use them to install a package. It also checks that it has a suitable _version_ of each dependency; this is why it sometime takes a long time to install a package Unfortunately, this means that as you add more packages to a particular environment, it gets more and more difficult to make sure everything works well together. Luckily, there is a practical solution: create new environments for specific projects to make sure the proper packages can function properly!

View file

@ -1,9 +1,11 @@
# Organize editing team, collaboration and visibility
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4-5.
```
````
# Organize editing team, collaboration and visibility
## Roles and responsibilities
To ensure smooth collaboration, it is essential to define the roles and responsibilities within your team. Firstly, designate who will be in charge of team organization ('administrators') who should be at least user type 4. Additionally, assign 'maintainers' responsible for combining content, also requiring at least user type 4. 'Editors' should be identified for editing and reviewing content, requiring at least user type 3.
@ -13,7 +15,7 @@ Finally, ensure that team members identify themselves according to the user type
## Review process
Furthermore, establish a clear editing and review process.
For the editing process, establish some practical rules on whether to use issues, branches and forks for adding content, fixing typos or making other changes. Furthermore, it can help to write down when you expect (draft) merge/pull requests and how to use the assign and review options in GitHub/GitLab. It is advisable to have at least a maintainer review each piece of content to maintain quality and consistency. Provide explanation on how you organize the book-editing and how you'd like to receive feedback in both the readme as the published book. The use of the [repository button {fa}`fa-github`, suggest edit {fa}`pencil` and issue button {fa}`lightbulb`](https://jupyterbook.org/en/stable/basics/repository.html) is advised.
For the editing process, establish some practical rules on whether to use issues, branches and forks for adding content, fixing typos or making other changes. Furthermore, it can help to write down when you expect (draft) merge/pull requests and how to use the assign and review options in GitHub/GitLab. It is advisable to have at least a maintainer review each piece of content to maintain quality and consistency. Provide explanation on how you organize the book-editing and how you'd like to receive feedback in both the readme as the published book. The use of the [repository button {fa}`github`, suggest edit {fa}`pencil` and issue button {fa}`lightbulb`](https://jupyterbook.org/en/stable/basics/repository.html) is advised.
(draft_book)=
## Define draft version of book
@ -46,4 +48,4 @@ Additionally, it is advisable to document the branch protection strategy and the
- Block force pushes
## Private, internally or public
Choose whether you want to share your source code and built book privately, internally or publicly. In any case, you need to obey copyright-rules. We advise public repositories and books in line with a vision on open education.
Choose whether you want to share your source code and built book privately, internally or publicly. In any case, you need to obey copyright-rules. We advise public repositories and books in line with a vision on open education.

View file

@ -1,12 +1,18 @@
(copyright)=
# Copyright and Licenses checklist
> This page reuses adapted CC BY content from the TU Delft Library. {cite:p}`tud_cip_24`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
````{margin}
```{attributiongrey} Attribution
:class: attribution
This page reuses adapted CC BY content from the TU Delft Library. {cite:p}`tud_cip_24`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
```
```{admonition} User types
:class: tip
This page is useful for all user types.
```
````
(copyright)=
# Copyright and Licenses checklist
The previous sections have familiarized you with the necessary software for your user type, the basics of Git, and how to collaborate with your team using Git. Now it's time to create your own content. This section will provide an overview of the copy right laws which need to be taking into account when creating and including content at TU Delft!

View file

@ -1,7 +1,14 @@
````{margin}
```{attributiongrey} Attribution
:class: attribution
This page reuses adapted CC BY content from {cite:t}`tud_cip_24`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
```
````
(copyright_considerations)=
# Copyright Considerations
> This page reuses adapted CC BY content from {cite:t}`tud_cip_24`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
Copyright law dictates how online book material can and should be created, maintained and shared. An author should understand a few key concepts, as well as best practices, in order to create a book that not only is a useful resource, but, also fairly reuses the work of others and, if provided with an open license, enables original content to also be reused.

View file

@ -1,8 +1,13 @@
````{margin}
```{attributiongrey} Attribution
:class: attribution
This page reuses adapted CC BY content from {cite:t}`hall21`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
```
````
(copyright_licenses)=
# Licenses
> This page reuses adapted CC BY content from {cite:t}`hall21`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
Here we present an overview of various license types, with a particular focus on the preference of TeachBooks to use Permissive Open Licenses, regardless of whether material is _content, code or data_ (described below).
```{admonition} Why permissive open licenses?
@ -72,11 +77,12 @@ The "ND" license prohibits derivative works: in other words, the material cannot
The "NC" license prohibits commercial use. It sounds nice, right?
> Great, I can guarantee that big for-profit companies can't use my work for their own gain. This is important to me at a public or non-profit institution.
To be honest, it is more trouble than it's worth, primarily because the law seems to be vague on what constitutes commercial use. Many universities require tuition to cover operating expenses, which is often broken down into by nubmer of students, credits, courses, etc. This could be interpreted as a form of commercial use and thus prevent other educators from using your work, which is precisely the opposite of what you were trying to facilitate!
To be honest, it is more trouble than it's worth, primarily because the law seems to be vague on what constitutes commercial use. Many universities require tuition to cover operating expenses, which is often broken down into by number of students, credits, courses, etc. This could be interpreted as a form of commercial use and thus prevent other educators from using your work, which is precisely the opposite of what you were trying to facilitate!
### Why is SA not preferred?
The "SA" license requires that any derivative works be released under the same license. If you have two sources, each of which has a different SA license, how can you include your work that incorporates that content under the same license? You can't! Once again, if your goal is to convince others to share your work in a responsible way, your effort is thwarted. As with NC, this type of license seems to be more trouble than it's worth.
A similar story holds for the other 'copyleft' lincenses, as all copyleft licences require that the original license is perserved in derivative work to some degree.
### Summary of License Type Compatibility
@ -104,4 +110,4 @@ What if your _content_ includes code. This happens in many science and engineeri
For example, the [MUDE Team](https://mude.citg.tudelft.nl) is working towards releasing the files associated with assignments under an open license. Since the majority of the content is written in a storytelling style in Jupyter notebooks, a CC BY license is probably the best choice if only one license is applied to a single file. However, if released in bulk it may be better to follow the advice of [Matt Hall](https://agilescientific.com/blog/2021/2/17/which-open-licence-should-i-choose):
> You have to be practical; maybe it depends on whether you consider your notebooks to be 'content' or 'source code'. I sometimes put at the bottom of a notebook something like **Open source content. Text is CC-BY, code is Apache 2.0** and I think this makes my intent clear.
> You have to be practical; maybe it depends on whether you consider your notebooks to be 'content' or 'source code'. I sometimes put at the bottom of a notebook something like **Open source content. Text is CC-BY, code is Apache 2.0** and I think this makes my intent clear.

View file

@ -52,20 +52,53 @@ Note that there are several types of pages and files that can be incorporated in
(copyright_recc_content)=
### Content Pages
Make sure you show the source of your content where it is provided. We adopt a standard icon and link to help readers recognize this: {fa}`quote-left`{ref}`Find out more here.<external_resources>`
Make sure you show the source of your content where it is provided. We adopt a standard icon and link to help readers recognize this: {fa}`quote-left`{ref}`Find out more here.<external_resources>`. This can be used to provide attribution to authors for specific pages too
#### How to implement this in your book
Copy the following line into your content file
```md
> This page reuses <license> content from {cite:t}`bib_id`. {fa}`quote-left`{ref}`Find out more here.<link to external resources section on credits and license page>`
```
Some examples can be found in this manual:
- [](../../external/deploy-book-workflow/README.md): a content page which is taken fully from another repository
- Figure {ref}`fig_license_types`: a single licensed figure added to a page taken from another website
- [](../copyright.md): a content page which adapts material from another website
##### Format as citation
Copy the following line into your content file
```md
> Written by `<author(s)>`
> This page reuses <license> content from {cite:t}`bib_id`. {fa}`quote-left`{ref}`Find out more here.<link to external resources section on credits and license page>`
```
This produces
> This page reuses CC BY content from {cite:t}`jason_moore`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
##### Format as custom admonition
The previous syntax might be used for other purposes as well. An alternative is a custom attribution admonition:
````{margin}
```{attributiongrey} Attribution
:class: attribution
Written by <author(s)>
This page reuses CC BY 4.0 licensed content from {cite:t}`jason_moore`. {fa}`quote-left`{ref}`Find out more here.<external_resources>`
```
````
Therefore, use the following syntax:
`````md
````{margin}
```{attributiongrey} Attribution
:class: attribution
Written by <author(s)>
This page reuses <license> content from {cite:t}`bib_id`. {fa}`quote-left`{ref}`Find out more here.<link to external resources section on credits and license page>`
```
````
`````
To make this possible we use the custom admonitions of [the custom named colors sphinx extension](https://teachbooks.io/manual/external/Sphinx-Named-Colors/README.html#admonitions) in combination with a [custom css file](../../_static/attribution.css) in `book/_static/` and the line `named_colors_custom_colors: {'attributiongrey':[150,150,150]}` in `book/_config.yml` under `sphinx: config: `
(copyright_recc_credits)=
### Credits and License Page

View file

@ -1,9 +1,11 @@
# Git: GitHub Desktop / Git in VS Code
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4 and 5.
```
````
# Git: GitHub Desktop / Git in VS Code
In this section you will learn how to install Git locally. Courses on Git usually make use of the command line interface to do run Git, but this introduces a steep learning curve. Instead, using Git from VS Code / GitHub Desktop is much more visual (i.e., more "clicky"), and therefore easier to use for those inexperienced with the command line.

View file

@ -1,9 +1,11 @@
# Collaboration tool: Git
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 3-5.
```
````
# Collaboration tool: Git
You will need to interact with Git to collaborate on a TeachBook, even if you are working by yourself! You've been introduced to it in the [exercises in the template](../intro/template.md) and you'll be guided through all of the steps in detail in [](../workflows/collaboration.md), but what is this "thing" that sounds suspiciously like something only a computer scientist would want to use?

View file

@ -1,9 +1,11 @@
# Combining Git Bash, VS Code and Conda
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 5.
```
````
# Combining Git Bash, VS Code and Conda
## Conda in Git Bash
Git Bash is a shell (also referred to as "the terminal") that is automatically installed with git. It provides Unix-like commands on a Windows OS, and is recommended for working with open source projects like Jupyter (for example `pip install`, building Jupyter books, using Git Bash in VS Code, etc). To do this, `conda` needs to be setup properly; this is described here:

View file

@ -1,9 +1,11 @@
# Build your book: JupyterBook
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 5.
```
````
# Build your book: JupyterBook
<a href="https://jupyterbook.org/"><img style="display:inline-block; height:1.5em; width:auto; transform:translate(0, -0.15em)" src="../images/logo-wide.svg" alt="Jupyter book"></a> is a regular Python package which converts our content into a website. It's part of all of the `requirements.txt` files for a book repository. At TeachBooks we developed a Python package called `teachbooks` which takes over the these features and adds [additional features](../features/overview.md). One of those additional features, for example, is the workflow to GitHub Pages.

View file

@ -1,9 +1,11 @@
# Install & authenticate required software
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4-5.
```
````
# Install & authenticate required software
Now that the types of users have been explained, you might have an idea which type corresponds to you!

View file

@ -1,9 +1,11 @@
# Which git provider to choose
````
```{admonition} User types
:class: tip
This page is useful for user type 4-5.
```
````
# Which git provider to choose
The setup of tools and URLs is dependent on agreements you've made on [collaboration](./collab.md).

View file

@ -1,9 +1,11 @@
# Versioning and URLs
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4-5.
```
````
# Versioning and URLs
Online books can be easily updated, however, this might confuse readers. Therefore, it's good practice to be aware of this and, where needed, provide an explicit version to the readers.

View file

@ -6,7 +6,7 @@ If you plan on maintaining only one public version, it is advisable to set `BEHA
To share the built book / website of old versions for your book on GitHub you have a few options:
- Create a branch for each version. When doing this, [the GitHub workflow](../external/deploy-book-workflow/README.md) will build it on GitHub pages. Here's a few tips:
- It's advised to use the version as branch name. In case of versions per academic year, you can just name each branch to the current academic year, this leads to the URL with the same name. In that case.
- It's advised to use the version as branch name. In case of versions per academic year, you can just name each branch to the current academic year, this leads to the URL with the same academic year..
- It is recommended to update the primary branch as the `PRIMARY BRANCH` when using the [GitHub workflow](gh-workflow-settings) whenever a new version is considered to be the most primary one. This ensures that readers are redirected to a consistent URL, even when new versions of the book are added later.
- Eventually, you can add old branches to the list of `BRANCHES_ARCHIVED` when using the [GitHub workflow](gh-workflow-settings) to include a banner on the page indicating its archived state. Alternatively, you can add a banner manually to `_config.yml`, as explained [here](../basic-features/banner.md).
- If you're using tags (as will be explained in [later](./versioning_changelog.md)), you can create a branch from a tag locally by running: `git branch <new_branch name> <tag/version>`.

View file

@ -1,9 +1,11 @@
# Editing text: VS Code
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 4 and 5.
```
````
# Editing text: VS Code
VS Code is a text editor with some extra features, such as integrated source control and a file browser. Moreover, extensions are available to add functionality to VS Code.

View file

@ -16,4 +16,4 @@ There are several "parts" to the manual:
- The **Features** part describes a suite of tools that are useful for teachers, many of which are developed by TeachBooks contributors specifically for use in education. Many of these tools are illustrated in the **Examples**.
- A few special tools are included in the **Editing Tools** that are useful when writing content.
See the final chapters of this book (under **Miscellaneous**) for additional information about References, Credits, etc.
See the final chapters of this book (under **Miscellaneous**) for additional information about References, Credits, etc.

View file

@ -142,3 +142,19 @@
year = {2025},
note = {Retrieved February 2025. CC BY 3.0.}
}
@misc{sphinx-iframes,
author = {{TeachBooks}},
title = {Sphinx iframes},
url = {https://github.com/TeachBooks/sphinx-iframes},
year = {2025},
note = {Retrieved April 2025. MIT.}
}
@misc{sphinx-prime-applets,
author = {{TeachBooks}},
title = {Sphinx PRIME applets},
url = {https://github.com/TeachBooks/Sphinx-PRIME-applets},
year = {2025},
note = {Retrieved April 2025. MIT.}
}

View file

@ -1,9 +1,11 @@
# Figure syntax maker
````{margin}
```{admonition} User types
:class: tip
This section is useful for user type 3-5.
```
````
# Figure syntax maker
One might quickely forget the code for making figures, here is a useful tool to make your figures, just specify all information and the code is produced for you:

View file

@ -1,9 +1,11 @@
# Collaborative book-editing
````{margin}
```{admonition} User types
:class: tip
This page is useful for user type 3, 4 and 5.
```
````
# Collaborative book-editing
A jupyter book is composed out of many files which contain the educational content produced by you. Through the use of branches it is possible to work on the book at the same time as your team-members. Working on content for the book is mainly individual work, the beauty of Git comes in when everybody's changes are merged into the main branch.

View file

@ -1,14 +1,14 @@
teachbooks == 0.1.0
sphinx-inline-tabs == 2023.4.21
jupyterbook_patches==1.3.0
jupyterbook_patches==1.4.4
download_link_replacer == 1.0.4
teachbooks-sphinx-grasple == 1.0.5
sphinx-image-inverter == 1.1.2
sphinx-exercise == 1.0.1
sphinx-proof == 0.2.0
sphinx-proof == 0.2.1
sphinx-named-colors == 1.0.1
sphinx-iframes == 1.0.5
sphinx-prime-applets == 1.0.1
sphinx-prime-applets == 1.0.2
git+https://github.com/TeachBooks/Sphinx-Thebe