Using Quarto in my website
Jorge Martínez Garrido
September 16, 2023
Some time ago, I shared a post on my website detailing the fascinating fusion of Hugo and Jupyter Notebooks, which you can explore here. This unique combination has proven to be a game-changer for me, enabling me to tackle my astronomy assignments while effortlessly generating content for my website, all within the seamless confines of Jupyter Lab.
However, this innovative approach is not without its challenges. I’ve encountered several issues along the way, including:
Absence of Captions for Figures and Tables: The integration lacks support for captions accompanying figures and tables, which hampers the overall readability and comprehension of my content.
Inadequate Cross-Referencing for Figures and Tables: The cross-referencing mechanism for linking to figures and tables is not as robust as I’d like it to be, making navigation and comprehension less user-friendly.
While I considered mentioning PDF generation as an issue, it’s worth noting that nbconvert does support PDF generation. However, I’ve found the resulting PDFs to be less aesthetically pleasing.
To address this, I’ve resorted to using wkhtmltopdf for converting a webpage from my website into a PDF. Yet, this alternative approach comes with its own set of challenges:
Inclusion of Website Banner: The PDFs generated with this method include my website’s banner, necessitating the removal, redeployment, rendering, and subsequent re-addition of the banner, which is a cumbersome and time-consuming process.
Code Snippet Display Issues: Code snippets often get cropped or appear in unexpected locations within the PDF, compromising their readability and effectiveness.
Limited Customization Options: The customization possibilities with this approach are disappointingly limited, leaving much to be desired in terms of tailoring the PDF output to my preferences.
Fortunately, my fortunes changed during SciPyConf 2023 when I stumbled upon a booth showcasing a remarkable tool known as Quarto. After an enlightening conversation with the staff, I couldn’t resist the temptation to give it a whirl!
In this post, I won’t delve into the specifics of what Quarto can do, its capabilities, or other related aspects. Instead, the focus of this text is to explore the integration of Quarto with Jupytext, Jupyter Lab, and Hugo. Through this exploration, I aim to gauge how seamlessly Quarto can be incorporated into my workflow and how it contributes to the final rendering of content, see figure Figure 1.
Note that there is a dedicated section in the official documentation on how to use Quarto with Hugo.
Jupytext markdown notebook for testing Quarto rendering
Let us generate some Python code for computing an approximate value of $\pi$ using the Montecarlo method. The value of the popular constant can be computed as:
$$ \pi = \frac{\text{Number of points inside}}{\text{Number of points generated}} $$
The following cell generates a collection of random points. Next, it classifies which points are inside and which are outside the unitary circle:
import numpy as np
N_POINTS = 35_000
points = np.random.rand(2, N_POINTS)
points_norm = np.sqrt(np.sum(points ** 2, axis=0))
inside = points_norm <= 1.00
points_inside = points[:, inside]
points_outside = points[:, ~inside]
Once all points have been classified, it is possible to visualize them. The following cell contains a comment syntax that is interpreted by Quarto. These comments are only visible when editing the notebook but not when rendering it. They allow to create a label or reference to the output of the cell and include the desired caption for it.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(points_inside[0,:], points_inside[1,:], "ro", markersize=0.5, label="Inside points")
ax.plot(points_outside[0,:], points_outside[1,:], "bo", markersize=0.5, label="Outside points")
ax.set_title("Points distribution")
ax.set_xlabel("X axis")
ax.set_ylabel("Y axis")
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.set_aspect("equal")
ax.legend(shadow=True, loc="lower left")
plt.show()
Finally, this line also contains a reference syntax interpreted by Quarto, allowing me to reference figure Figure 1.
The language used by the referencing system can be modified using the language
key in the metadata section. For example, to select Spanish, the metadata must be language: es
.
Back to the computation of number $\pi$ using previous points:
pi = 4 * points_inside.size / points.size
print(f"Computed value of {pi = }")
Computed value of pi = 3.1405714285714286