Introduction
This web page provides a full step-by-step guide for converting math notes in the form of markdown (.md) into HTML, CSS and JavaScript, and publishing them with MathML output. Non-technical users should be able to follow along procedurally without knowing the deeper mechanisms of the system. An understanding of the web, HTML and Git will be helpful but not necessary.
Technical Overview
Here we show a high level overview of the different parts of the system and how they fit together. Non-technical readers with no desire to fully understand our solution, or technical users with prior experience in web development may skip forward, but reading through this section is highly recommended to help solidify knowledge. This section is framed to provide users with little or no web experience a conceptual framework that will assist them in the remainder of the tutorial. To properly break down the system we will go through each tool and its function.
Quartz
Quartz is an open source project that takes markdown files and translates them into a publishable collection of HTML, JavaScript and CSS files. Essentially, this means that your markdown and LaTeX is converted into a web-friendly format. When Quartz does this conversion it is called “building”. The specifics of how Quartz builds your website may be interesting for software/web developers and can be read about in more depth here.
GitHub and Git
Git and GitHub are software solutions for version control and hosting of code in the cloud. Version control means that you can save at a certain point and revert to that point if you find a mistake later. With Git version control these save points are called “commits”. GitHub also allows you to store local files, like the files associated with Quartz, remotely in the cloud. Here the term local indicates that the files are stored on the disk in your personal machine. The term remote indicates that GitHub is storing those files on their own servers. Having your files and changes stored in the cloud makes version control easier, and allows your content to be easily accessible by other services (i.e. Cloudflare). When you make a change to your content, you can then commit, and upload those changes to GitHub. When an upload like this occurs it is referred to as a “push”. More information can be found here.
Cloudflare
Cloudflare is a large company that handles a variety of internet services. The service we are concerned with is Cloudflare Pages which allows users to take collections of HTML, CSS and JavaScript files, like the ones that Quartz produces, and publish them as a publicly accessible website with a URL. Cloudflare tracks the cloud hosted code stored in GitHub repositories and will rebuild your site when it sees that new changes have been pushed. Much more can be read about Cloudflare Pages here, but for the purposes of this paper it is enough to understand its essential function as a connector between GitHub and the internet.
Obsidian
Obsidian is a popular tool for managing and viewing markdown files. It essentially functions as a text editor that properly renders markdown for easy viewing and editing. Obsidian allows software developers to create “plugins” which add functionality to the app. One of these plugins is called Obsidian Git, and allows you to execute git commands (like commit and push) inside of Obsidian with ease. Find out more about Obsidian here.
VSCode
Visual Studio Code is a text editor that makes navigating folders, the command line, and viewing files much easier. It also has helpful integrations with other tools like Git. VSCode is not required to follow this tutorial, but often it can simplify much of the process.
Setup
This section will walk through the installation, and account creation for every service necessary in the tutorial.
Installing Obsidian
- Navigate to https://obsidian.md/download
- Click on the download link corresponding to your operating system
- After the download is complete open the executable file
- Select “Next” and then “Install” to complete the installation
Installing VSCode
- Navigate to https://code.visualstudio.com/download
- Click on the download link corresponding to your operating system
- After the download is complete open the executable file
- Select “I accept the agreement” and then “Next”
- If you would like VSCode to have a desktop icon check the “Create a desktop icon” box
- Click “Next” and then “Install” to complete the installation
Installing NodeJS
- Navigate to https://nodejs.org/en/download
- Scroll down until you see “Or get a prebuilt Node.js…”
- On that line ensure that the selected operating system and architecture are correct (they will be automatically set for your system by default)
- Download the corresponding installer for your operating system by clicking the green button below that reads “[OS] Installer”
- After the download is complete open the executable file
- Select “Next”
- Agree to the license agreement and select “Next”
- Select “Next” and then “Next” again
- Check the box that reads “Automatically install the necessary tools…” and then select “Next”
- Click “Install” and wait for the installation process to complete
Creating a GitHub Account
- Navigate to https://github.com/
- Select “Sign Up” in the top right corner
- Enter an email, password and username, or continue with Apple or Google
- Click “Create account”
Creating a Cloudflare Account
- Navigate to https://dash.cloudflare.com/sign-up
- Click “Continue with GitHub” using your previously created GitHub credentials
- OR Enter an email and password to create an account
(We recommend using your GitHub account as it will simplify processes later on)
Installing Git
- Navigate to https://git-scm.com/install/
- Select your operating system
- Click “Click here to download”
- After the download is complete open the executable file and complete the installation process
Creating a Quartz Instance
To begin with Quartz, the first step is to get some files and code imported onto your local machine so you can edit them and make them your own. This is done by copying code hosted in GitHub, and putting it somewhere on your machine. With Git, this process is called cloning.
Cloning the Quartz Repository
To begin, first open VSCode (or your text editor of choice) and open a new empty folder. First create an empty folder in your desktop or file explorer. Then in VSCode you can select “File” in the top right and “Open Folder” to search through and choose any empty folder on your machine you wish to use.
Now that you have your folder open, click “Terminal” and then “New Terminal” in the navbar at the top of the application. This will open a command line at the bottom of your screen. Now enter the following commands one by one:
git clone https://github.com/jackyzha0/quartz.git
cd quartz
npm i
npx quartz createIf something goes wrong with command 1, then there is likely either a problem with your internet connection or your Git installation. If something goes wrong with commands 3 or 4 then there is likely a problem with your NodeJS installation.
After you execute the fourth command you should see a series of setup questions for initialization. For these select:
- Empty Quartz
- Treat links as shortest path ((default))
Important Settings
Now that you have Quartz set up on your local machine, it’s important to set some preliminary settings. Settings for a Quartz site are handled in a file called “quartz.config.ts”. To find out more about this method of customization you can read the official docs here. For our purposes there are two extra features enabled in this configuration file that make Quartz especially useful for math education. To begin applying these changes, first use the file explorer in your text editor (found on the left in VSCode) to open the quartz directory and find the quartz.config.ts file. Double click this file to view it in your editor.
Enabling MathML Output
Quartz processes LaTeX with a plugin that is already included by default. To read more about how plugins work see Quartz Plugin Docs. To ensure that the output is parsable by a screen reader it must be in a MathML format. By default on line 74 of quartz.config.ts you should see the below plugin.
Plugin.Latex({ renderEngine: "katex" }),To change this to render MathML, add the options as shown below.
Plugin.Latex({ renderEngine: "katex", katexOptions: { output: "mathml" } }),Adding Hidden Folders and Files
Many times you may want to restrict access to certain files, but still want to store them near your other published notes. To achieve this functionality we recommend using the Quartz ignore patterns feature to create “hidden” folders to store content that will be ignored during the build process and therefore never published. Adding these folders requires finding line 20 in quartz.config.ts shown below.
ignorePatterns: ["private", "templates", ".obsidian"],And changing it to ignore all files inside of any folder named “hidden” by adding a Regex pattern to the end of the list.
ignorePatterns: ["private", "templates", ".obsidian", "**/hidden/**"],There are other options for creating hidden files such as Quartz’s ExplicitPublish and RemoveDrafts plugins that may suit your situation better. However, using hidden folders uniquely allows for easy removal and unlocking of multiple files at once.
Adding Content
To add content to the website, you will need to place your markdown notes inside a folder that Quartz can access. By default this folder is the quartz\content directory. Inside this folder create a file called “index.md” and place some markdown/LaTeX content inside. The index.md file will function as the landing page for your site, but for now inserting some placeholder content is appropriate.
Here is some viable placeholder content in markdown format you’re welcome to use:
---
title: Welcome to Quartz
---
Let $\sigma=(i_1\; i_2\;\cdots \;i_k)$ be a $k$-cycle, for some $k\leq n$. Show that $(i_1\; i_2\;\cdots \;i_k)=(i_1\; i_2\;\cdots \;i_{k-1})(i_{k-1}\;i_{k})$.All of the markdown notes you want to make public will need to be placed inside of this content directory. You can organize your notes just as you would on a computer (with subfolders and sub-subfolders etc.) and Quartz will reflect this in the builded site. For example, a file located at content\calcII\notes\notes1.md will appear at the URL mysite.com/calcII/notes/notes1 once your site is published.
Later you can customize your home page to link to different sections of your content and notes. You can also change the title of the home page, styling, and layout in the customization section.
Users who already have an Obsidian vault to store their notes in may want to avoid the trouble of moving the entire vault manually into the content directory. In this scenario we recommend following this tutorial, which details how one can use Obsidian to publish a vault located outside of the default content directory.
Building and Viewing Previews
To see what your site currently looks like, without publishing it to the wider internet, it is extremely useful to build and serve the site locally. To do this open a new terminal, and ensure you’re in the “quartz” directory. Next run the command
npx quartz build --serveThis command breaks down into a few important parts:
npx quartz build
This command tells Quartz to build the site, transforming the markdown files into HTML, JavaScript, and CSS.
--serve
This command tells Quartz to serve the site locally. This means that after build, a preview of the website can be found on localhost:8080. To view this preview, open any browser and simply type in localhost:8080 as the URL.
- (optional)
-d [path/to/folder]
This option can be added to the end of any build command, and tells Quartz that instead of looking into the default quartz\content directory to find markdown files, we want it to look into a separate directory specified by [path/to/folder]. We will revisit this later as it can be useful if you want to rename folders for easier management with Obsidian.
Try going to localhost:8080 in your browser now and check that the site is rendering. You should see something like this:
Pushing to a Remote GitHub Repository
Navigate to https://github.com/ and login to your account. On the home page click the green “New” button to create a new repository. Give this repository a name and a description, and then set the visibility to Private. Ensure that Add README is off, Add .gitignore is set to “No .gitignore” and Add license is set to “No license”. Then scroll down and click “Create repository”.
Now, at the top of your newly created repository page, you should see a box that looks like this.
Click the clipboard to copy this link and then perform the following commands while in the “quartz” directory replacing [copied-url]:
git remote -v
git remote set-url origin [copied-url]The first command lists all of the remote repositories currently tracked. If you do not see
upstream https://github.com/jackyzha0/quartz.git (fetch)
upstream https://github.com/jackyzha0/quartz.git (push)When this command is run, you will need to run the following command to add an upstream repository.
git remote add upstream https://github.com/jackyzha0/quartz.git
This extra remote tracking will allow you to update your Quartz instance when patches and newer versions are released. Updating can easily be done by running npx quartz update inside of the “quartz” directory.
During this process you may be prompted to enter your login information to authenticate in the browser, this is normal and necessary to complete the git syncing process, and should only be required once.
Warning
Windows users may find that their credentials have been corrupted after a period of time. To fix this go to Credential Manager > Windows Credentials and delete any credentials saved for github.com.
Now that you have your remote repository set up, you can perform your first push by running
npx quartz sync --no-pullLater pushes should be done by running the same command and omitting the “—no-pull” flag. Although if you choose to manage your files with Obsidian we will show a simple way to sync files without needing to interact with the command line at all.
Publishing with Cloudflare
Now that GitHub is tracking your local files it’s a relatively simple process to publish the content generated by Quartz as a website with a public domain. While there are many services for publishing (GitHub Pages, Vercel, Netlify) and also self-hosting options with Nginx or Apache one of the simplest and most performant is publishing with Cloudflare Pages. We will be walking through content publishing with Cloudflare Pages, but you are welcome to follow any of the other options with tutorials located here.
First, navigate to https://dash.cloudflare.com/ and login to your account. Once inside your Account Home, select the + in the top right corner of the dashboard. This will open a dropdown menu, where you should click “Pages”.
Next, under “Import an existing Git repository” press the “Get started” button. If you have your GitHub account already synced with Cloudflare then you should see all of your repositories listed. If not you may be prompted to add a GitHub account. Once your account is added, select the repository you created in the previous steps, and then click “Begin setup”.
Now fill out the following options as follows:
Project name: Any name you wish to use for your project, this name will appear in the default URL given to you by Cloudflare.
Production branch: v4
Framework present: None
Build command: npx quartz build
Note that users who are not utilizing the default quartz/content directory will need to add the -d [path/to/folder] argument. Also make sure to omit the --serve flag, as it is only used for viewing previews of the site locally.
Build output directory: public
Next click “Save and deploy” and wait for Cloudflare to handle the deployment process. Upon a successful deployment you should see this message, indicating the public URL of your Quartz site.
Click this link to ensure your site is working correctly. You should see the same output found when serving the site locally, this time with a different URL. This URL is officially public, and can be accessed by anyone with a browser and internet connection.
After continuing to your project home page you can view settings, previous deployments and set up a custom domain. By default Cloudflare will automatically deploy the site each time there is a new push to your remote GitHub repository. This means changes can easily be made, pushed, and published in a process that lasts on average less than a minute.
Management with Obsidian
Obsidian is a great way to manage and view your markdown files that will be published with Quartz. Obsidian also allows users to install plugins that make certain processes easier to complete. Using Obsidian greatly simplifies the editing process and removes the need to open a text editor, deal with code, or run commands in a terminal in most cases.
Collections of Obsidian markdown notes are referred to as vaults, and the first step in setting up Obsidian will be creating a vault for your notes.
Creating a Vault
Open Obsidian on your computer and Select “Open” under the “Open folder as vault” option. If you already have a vault open, you’ll need to click the vault name in the bottom left corner, and then select “Manage vaults…” to see the correct screen.
Next navigate to the directory you set up your quartz files in, and open the quartz/content folder. This step will initialize a vault in that folder and allow you to view the markdown files in more user friendly format.
Reference to Obsidian Syntax
For those unfamiliar with markdown or Obsidian syntax it will be useful to review Obsidian’s basic formatting documentation. For math content specifically, it’s important to note that inline math (written in LaTeX) must appear in single $, and block math must appear inside double $$, with each $$ on its own line. We already have some inline math rendering in the placeholder index.md file and below is an example of block math.
$$
f(x) = \int_{-\infty}^\infty
f\hat(\xi),e^{2 \pi i \xi x}
\,d\xi
$$This example will be rendered as below on the quartz website.
Failing to place $$ on their own line as shown in the example can result in rendering errors when your site is built.
Obsidian Git
One extremely useful plugin for Obsidian is simply called “Git” and is known as Obsidian Git. It allows you to push and pull updates from your remote GitHub repository directly in Obsidian, without needing to interact with the command line.
To begin the installation process open your content vault and click on the setting gear icon in the bottom left of the screen. Then navigate to the Community plugins tab and press “Turn on community plugins”. Next, click the purple “Browse” button and type “Git” into the search bar. The first result should be a plugin called Git By Vinzent (Denis Olehov).
Click on this plugin and then click “Install” and “Enable”. With the plugin installed and enabled, you can now access all of the commands that Git offers by pressing Ctrl/Cmd+P to open the command panel in Obsidian, and typing “Git” to search for commands installed by the plugin. The most helpful command will most likely be “Git: Commit-and-sync” as it automatically pulls and pushes new content to the remote repository, which will then be published by Cloudflare in a matter of minutes.
To test the system make an edit to the sample index.md file, and then open the command panel with Ctrl/Cmd+P and select the Commit-and-sync command. Then wait a minute or two and check that the changes appear on the public version of your site.
Remember that as soon as content is pushed to the remote repository, it will be made automatically public by Cloudflare unless it is hidden in some manner (refer to the Adding Hidden Folders and Files section for more information on how to hide content). For this reason it is always recommended that you build and view your site locally before deployment to check that everything is working as intended.
Customization
One of the main features of a Quartz deployment is the level and ease of customization. There are a number of ways you can customize your site, from creating your own components and plugins, to simple changes of fonts and colors. We will go through three common and useful methods of customization that require minimal effort.
Quartz Configuration
Mentioned earlier in the Important Settings section, Quartz offers a common place to set certain parameters for how your site is rendered and built. This file is quartz.config.ts and can be found inside the quartz directory. The file allows you to easily adjust the site title, site suffix, font faces, color schemes (for dark and light mode) and, for slightly more advanced users, the specific plugins used during the build process. Full documentation for configuration can be found here.
Most users will never need to handle Quartz plugins, however, for users with large amounts of markdown files and a desire for faster build times, removing the CustomOgImages plugin at the bottom of the quartz.config.ts is recommended.
Developers may be interested in further customization by creating their own plugins.
Layouts
Quartz also offers a central location for customizing the layout and components included in a site: the quartz.layout.ts file. This file includes all of the components (search bar, darkmode toggle, title, file explorer etc.) and their location on the site. Components are placed in one of six common locations.
For instance, the PageTitle component is placed in the left location, and this is reflected in the quartz.layout.ts file. You will also notice components such as ConditionalRender or Flex which take in other components as parameters. These components alter the rendering of content further and are referred to as Higher-Order Components. More on these features can be read here.
// components for pages that display a single page (e.g. a single note)
export const defaultContentPageLayout: PageLayout = {
beforeBody: [
Component.ConditionalRender({
component: Component.Breadcrumbs(),
condition: (page) => page.fileData.slug !== "index",
}),
Component.ArticleTitle(),
Component.ContentMeta(),
Component.TagList(),
],
left: [
Component.PageTitle(), // ←— Page title is placed on the left
Component.MobileOnly(Component.Spacer()),
Component.Flex({
components: [
{
Component: Component.Search(),
grow: true,
},
{ Component: Component.Darkmode() },
{ Component: Component.ReaderMode() },
],
}),
Component.Explorer(),
],
right: [
// Component.Graph(), ←— Remove by commenting out, or delete the entire line
Component.DesktopOnly(Component.TableOfContents()),
Component.Backlinks(),
],
}Adjusting this file can quickly become a technical task requiring a deeper understanding of TypeScript and the function of Quartz components. Most users will find it useful simply for removing unwanted components, which can be done by commenting out or deleting the entire line. However, for those interested, there is extensive documentation provided by Quartz covering the layout, built-in components, and creation of your own components.
Custom CSS
Developers may also want to further customize their site with added CSS, this can be easily done with a custom SCSS file located at quartz/quartz/styles/custom.scss. Placing in your custom styles here will have them automatically injected during build.
Obsidian Customization
Obsidian also provides numerous options for customizing appearance including the addition of custom CSS snippets. Full documentation for these features can be found here.
Example Workflows
To conclude the tutorial we would like to offer some example walkthroughs for how to complete common tasks including adding, removing, hiding, revealing and linking to content. These sections are meant to function as a quick reference, for users who have already completed the above setup and understand the system well.
Note
We’ve created this section as a separate page so that it can be easily bookmarked and used by instructors. If you’re reading this from the main tutorial, then this is a lovely example of a transclusion!
Adding and Removing Content
- To add completely new pages to your site, open your content vault with Obsidian and in the file explorer on the left, right click and select “New Note”. Fill in the page with any content you wish to include referencing the Obsidian basic formatting documentation as necessary.
- Making edits or adding to existing pages can simply be done by editing the markdown file in Obsidian. Deleting content can be done by deleting the entire file, or removing the content from the file just as you would in any text editor.
- Once complete, you can view your site locally to check everything looks right before a deployment (see Building and Viewing Previews).
- To publish press Ctrl/Cmd+P and select the “Git: Commit-and-sync” command. Within a few minutes you should see the changes on your public site. Optionally you can login to Cloudflare to view the build process, monitor for errors and troubleshoot if problems occur.
Hiding and Revealing Content
- To hide content first ensure you have followed the instructions from the Adding Hidden Folders section. Then add a folder simply called “hidden”. Place the content you would not like published inside of this folder.
- Revealing content is as simple as removing it from the hidden folder.
- View the site locally (see Building and Viewing Previews) and ensure that your hidden content cannot be reached by directly typing in the URL. Also confirm that unhidden content is accessible as desired.
- To publish press Ctrl/Cmd+P and select the “Git: Commit-and-sync” command. Within a few minutes you should see the changes on your public site. Optionally you can login to Cloudflare to view the build process, monitor for errors and troubleshoot if problems occur.
Linking and Embedding Content
- Linking to content can be done by using the wikilinks or markdown format although Quartz only supports embedding content in wikilinks format, and external links must be written in markdown format. Below is a quick reference for using wikilinks and markdown links formats.
Wikilinks Syntax
[[Path to file]]: produces a link to Path to file.md (or Path-to-file.md) with the text Path to file[[Path to file | Here’s the title override]]: produces a link to Path to file.md with the text Here’s the title override[[Path to file#anchor|Anchor]]: produces a link to the anchor Anchor in the file Path to file.md[[Path to file#^block-ref|^block-ref]]: produces a link to the specific block-ref in the file Path to file.mdEmbeds
![[Path to image]]: embeds an image into the page![[Path to image|100x145]]: embeds an image into the page with dimensions 100px by 145px![[Path to file]]: transclude an entire page![[Path to file#anchor|Anchor]]: transclude everything under the header Anchor![[Path to file#^b15695|^b15695]]: transclude block with ID^b15695Sourced from https://quartz.jzhao.xyz/features/wikilinks#syntax
Markdown Syntax
[Here’s the title override](Path to file): produces a link to Path to file.md with the text Here’s the title override[Here’s the title override](www.example.com): produces a link to www.example.com with the text Here’s the title overrideLink to original
- View the site locally (see Building and Viewing Previews) and ensure that your or embeds are working correctly.
- To publish press Ctrl/Cmd+P and select the “Git: Commit-and-sync” command. Within a few minutes you should see the changes on your public site. Optionally you can login to Cloudflare to view the build process, monitor for errors and troubleshoot if problems occur.