In the following, I'll talk about how to make online books or online documentation using four different tools/frameworks: Hugo, VuePress, Jupyterbook, and the R pacakage of Bookdown. For each tool, I'll detail (1) installation, (2) usage, (3) content structure, (4) customization, and (5) publishing.
Table of contents generated with markdown-toc
-
Open access: empower people and extend the influence of your work
-
Open source: enable others to contribute!
-
A better way to learn: creating an online book helps you organize your knowledge and learn at a deeper level.
Hugo defines itself as "the world's fastest framework for building websites". It is essentially a static site generator written in Go. It is becoming increasingly popular partly because of its speed of rendering website pages.
Some useful links:
Whether your computer is running or macOS, Windows, or Linus, you can download the binary from the Hugo releases. Here is the official instruction. You can read my post on installing and upgrading Hugo on Mac as well.
If you are are Mac user and using Homebrew, you can install with:
brew install hugo
If you experience difficulties installing Hugo, please refer to the official guide on installation.
After installing Hugo, please open your terminal and test whether the installation is successful with hugo version
.
Now, we are going to generate a demo site. In your terminal, first change directory to where you want the demo site to sit.
Then, simply use
hugo new site demosite # You can change "demosite" to any other names you like.
You'll see a new folder named "demosite" generated.
To build a website with Hugo, you need to use a theme. It can be developed by others or yourself. You can find available themes here. Considering the purpose of this tutorial, I'll focus on Hugo themes suitable for making documentations.
Specifically, I chose five themes for books:
-
OpenGitDocs (not listed among the official themes)
One theme for long articles:
If you don't care about the look of a book or an article, you can apply any themes you like. For example, this is the demo site when I used the XMin theme.
To use a theme, you need to:
cd demosite/themes
git submodule add ThemeRepoRUL # e.g., git submodule add https://github.com/alex-shpak/hugo-book
Using git submodule
comes with the caveat that if you customize the theme, your customization might break if the original theme updates considerably.
To avoid this issue, I recommend using
cd demosite/themes
git clone ThemeRepoURL # e.g., git clone https://github.com/alex-shpak/hugo-book
cd RepoNmae # e.g., cd hugo-book
# git remote -v
git remote rm origin
cd .. # go back to themes
cd .. # go back to demosite
git remote rm origin
is necessary because if you don't run it, you'll probably see the below error message (I am taking hugo-creative-portfolio-theme as an example):
warning: adding embedded git repository: themes/hugo-creative-portfolio-theme
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: git submodule add <url> themes/hugo-creative-portfolio-theme
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: git rm --cached themes/hugo-creative-portfolio-theme
hint:
hint: See "git help submodule" for more information.
As commented, before running git remote rm origin
, you can use git remote -v
to check whether you should use rm origin
.
For example, after running git remote -v
, I saw
origin https://github.com/kishaningithub/hugo-creative-portfolio-theme (fetch)
origin https://github.com/kishaningithub/hugo-creative-portfolio-theme (push)
Obviously, I should use git remote rm origin
.
Most themes come with an exampleSite
which usually contains content
, static
and config.toml
. Please copy all the stuff in this exampleSite
and paste theme to the root directory of demosite
. If files already have some of the names, for example, config.toml
, just replace it with the new one (the one from exampleSite
).
CAUTION: This will eradicate all material within the content
folder at the root directory of demosite
. If you have important files in this content
folder, please make copies before move stuff in exampleSite
!
Another thing you need to take notice is that in config.toml
, make sure that the theme name, which you'll find in theme = "ThemeNmae"
, should be exactly the same as the folder name of the repo name you just git clone
d or git submodule
d.
Also note that you can put as many themes within the themes
folder as you like. Every time you want to change a theme, simply change the theme name in config.toml
's theme = "ThemeNmae"
However, you might need to copy and paste the exampleSite
of each theme every time. Be mindful of the caution I mentioned above.
To see the example site, at the root directory of demosite
:
hugo server -D
If everything goes well, open http://localhost:1313/ and you'll see the example site that you saw in the theme's repo.
To stop the local server, press Ctrl
+ C
.
After establishing the theme you want to use, you need to create your own content.
For books or documentation, the structure is central. To get the order of chapters and sections you desired, you need to specify weight
for each markdown
file.
Let's say your book has this structure:
├── _index.md
├── chapter01
│ ├── _index.md
│ ├── section01.md
│ └── section02.md
├── chapter02
│ ├── _index.md
│ ├── section01.md
│ ├── section02.md
│ └── section03.md
└── chapter03
└── _index.md
Since the number of sections seldom exceeds ten, the weight of each markdown
file can be set as the following:
├── _index.md # ---> weight: 1
├── chapter01
│ ├── _index.md # ---> weight: 10
│ ├── section01.md # ---> weight: 11
│ └── section02.md # ---> weight: 12
├── chapter02
│ ├── _index.md # ---> weight: 20
│ ├── section01.md # ---> weight: 21
│ ├── section02.md # ---> weight: 22
│ └── section03.md # ---> weight: 23
└── chapter03
└── _index.md # ---> weight: 30
You get the idea, right?
Customization of Hugo themes can be super easy or challenging, depending on how much you want to change.
To customize, you need a deeper understanding of HTML, CSS, and of course, Hugo, which is beyond the scope of this online book tutorial. That said, I'd like to point out some basic customization tips:
-
To customize the general look of the book's pages, you'll need to make changes within
themes/YourTheme/layouts
. You can find most default styling in_default
andpartials
. -
To customize the look a page more deeply, you'll need to go to
themes/YourTheme/static/css
. Some themes put the styling in lots of.scss
files within theassets
folder.
If you want to customize the theme more deeply, I highly recommend you to read the book of Blogdown by Yihui Xie.
You can find a complete list of ways to host a Hugo site on the official hugo site. I'll only talk how to publish via Netlify, which is free.
First of all, you need to create a GitHub repository for your book project and let's say you name it as book_project
.
Then, at the root directory of demosite
, create a file named netlify.toml
with the following content:
[build]
publish = "public"
command = "hugo --gc --minify"
[context.production.environment]
HUGO_VERSION = "0.80.0"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"
[context.split1]
command = "hugo --gc --minify --enableGitInfo"
[context.split1.environment]
HUGO_VERSION = "0.80.0"
HUGO_ENV = "production"
[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"
[context.deploy-preview.environment]
HUGO_VERSION = "0.80.0"
[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"
[context.branch-deploy.environment]
HUGO_VERSION = "0.80.0"
[context.next.environment]
HUGO_ENABLEGITINFO = "true"
The above came from Hugo's official instructions. Be sure to customize 0.80.0
if your Hugo version is different.
Then, open your Terminal:
cd demosite
git init
rm -rf public
hugo
git add .
git commit -m "my first commit."
git remote add origin https://github.com/UserName/book_project #Please replace UserNmae with your github username
git push -u origin master
Refresh the repo page book_project
. After making sure that all the stuff in demosite
is uploaded, open https://www.netlify.com/.
What you should do later can be found in Hugo's guide of Host on Netlify:
VuePress is a static site generator powered by Vue.js.
To be able to use VuePress, you need to make sure you've had Node.js installed.
The official guide had detailed instructions. I'll summarize in the following.
Open your terminal, change the directory to where you want the new project sit, and then
mkdir vuepress-starter
cd vuepress-starter
npm init
npm install -D vuepress
mkdir docs # All of the future content will be put in the folder of docs
echo '# Hello VuePress' > docs/README.md
mkdir .vuepress
If you are on macOS and cannot see the hidden folder of .vuepress
just created, press CMD
+ Shift
+ .
simultaneously.
Please take a look at the sample site I created using VuePress at https://vuepress-starter.hongtaoh.com/, whose GitHub Repo is at https://github.com/hongtaoh/vuepress-starter.
The structure of the book content is as follows:
├── 01-abstract
│ └── README.md
├── 02-motivation
│ └── README.md
├── 03-lit
│ ├── 01-lit-female.md
│ ├── 02-homefield.md
│ ├── 03-efficiency.md
│ ├── 04-ranking.md
│ └── README.md
├── 04-plans
│ ├── 01-plan-female.md
│ ├── 02-plan-homefield.md
│ ├── 03-plan-efficiency.md
│ ├── 04-plan-ranking.md
│ └── README.md
├── 05-plots
│ ├── 01-plots-female.md
│ ├── 02-plots-female-continent.md
│ ├── 03-plots-homefield.md
│ ├── 04-plots-efficiency.md
│ ├── 05-plots-ranking.md
│ └── README.md
├── 06-conclusion
│ └── README.md
├── 07-reference
│ └── README.md
└── README.md
The easiest way to make sure the order of chapters and sections is what you desired is to use numbers like I did.
To customize the sidebar and/or the navbar, first, you need to create a file named config.js
within the docs/.vuepress
folder:
> config.js
The Navbar is relatively easy to set, read the instructions here or look at the config.js of the example site.
The Sidebar is a little bit complicated. I chose to use vuepress-plugin-sidebar to generate the sidebar-manu automatically. Again, look at the config.js of the example site, or VuePress's instructions.
Before serving the site, you are encouraged to add the following to package.json
:
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
To serve the site locally, at the root directory of vuepress-starter
:
npm run docs:dev
Make relevant changes until you are satisfied with the look and structure.
Please refer to the Theme section of VuePress's official documentation for more information. If you don't like the default look, you change the theme or write your own theme.
First, as usual, you need to create a repository on GitHub (or similar platforms).
In case you are not familiar with Git, at the root directory of vuepress-starter
you just created:
git init
git add .
git commit -m "my first commit"
git remote add origin https://github.com/UserName/ProjectName
git push -u origin master
You can find the official instructions on publishing a VuePress project. Again, I recommend the Netlify option.
Jupyterbook is great if you have Jupyter Notebook (.ipynb
) files. Even if you have pure texts, the functions of Jupyterbook might interest you.
If you don't have Python yet, you need to first install it.
You can install Jupyterbook via pip:
pip install -U jupyter-book
You can create a sample book:
jupyter-book create samplebook/
Or you can git clone
the demo site I created:
git clone https://github.com/hongtaoh/olymvis-jupyterbook
Simply put all your content in the root directory of your book project. Take my demo site as an example:
├── 01-abstract
├── 03-lit
│ ├── 01-lit-female.md
│ ├── 02-lit-homefield.md
│ ├── 03-lit-efficiency.md
│ ├── 04-lit-ranking.md
│ └── index.md
├── 04-plans
│ ├── 01-plans-female.md
│ ├── 02-plans-homefield.md
│ ├── 03-plans-efficiency.md
│ ├── 04-plans-ranking.md
│ └── index.md
├── 05-plots
│ ├── 01-plots-female.md
│ ├── 02-plots-female-continent.md
│ ├── 03-plots-homefield.md
│ ├── 04-plots-efficiency.md
│ ├── 05-plots-ranking.md
│ └── index.md
├── _build
│ ... (lots of files after you serve the site locally)
├── _config.yml
├── _toc.yml -----> See ▼ below for details
├── abstract.md
├── conclusion.md
├── deploy.sh
├── intro.md
├── logo.png
├── motivation.md
├── olympics.png
├── ref.md
└── requirements.txt
Then, configure the structure in _toc.yml
:
- file: intro
- file: abstract
- file: motivation
- file: 03-lit/index
sections:
- file: 03-lit/01-lit-female
- file: 03-lit/02-lit-homefield
- file: 03-lit/03-lit-efficiency
- file: 03-lit/04-lit-ranking
- file: 04-plans/index
sections:
- file: 04-plans/01-plans-female
- file: 04-plans/02-plans-homefield
- file: 04-plans/03-plans-efficiency
- file: 04-plans/04-plans-ranking
- file: 05-plots/index
sections:
- file: 05-plots/01-plots-female
- file: 05-plots/02-plots-female-continent
- file: 05-plots/03-plots-homefield
- file: 05-plots/04-plots-efficiency
- file: 05-plots/05-plots-ranking
- file: conclusion
- file: ref
To build the book, first change directory to the directory one level higher than your book project (e.g., book_project
). For example, if the book project is sitting on your Desktop, then
cd Desktop
jupyter-book build book_project/ # Or: jb build book_project/
Open file://Users/my_path_to_book/_build/index.html
and you'll be able to see the site. See the output after you run jupyter-book build book_project/
for the exact address of file://...
.
For details on customization, and all the features enabled by MyST Markdown, please consult the official documentation of Jupyterbook.
You can publish your jupyterbook project with GitHub Pages and Actions. For consistency and simplicity, I'll talk about how publish via Netlify.
Again, you need to create a repository for your project. In case you are not familiar with Git, at the root directory of book_project
:
git init
git add .
git commit -m "my first commit"
git remote add origin https://github.com/UserName/ProjectName
git push -u origin master
To configure Netlify, refer to the relevant section in the Hugo tutorial above. In the last step of "Deploy site" on Netlify, I suggest that you leave "Build command" blank and input _build/html
for "Publish directory".
I tried the configuration mentioned in the section of Publish with Netlify on the official documentation. The Step 2 did not work for me. Therefore, I chose to leave "Build command" blank on Netlify. This means that you'll have to build the site (with jupyter-book build book_project/
mentioned above) before updating your content.
I personally recommend Bookdown because
- Simple but elegant look
- Easy to generate decent PDF and MS Word files
Since Yihui, the creator of Bookdown, has made detailed documentation in his bookdown: Authoring Books and Technical Documents with R Markdown, I will talk very briefly in the following and encourage you to consult the book when in doubt.
First, make sure you already have R and Rstudio IDE installed.
In R, to install the package of Bookdown:
install.packages("bookdown")
If you want an almost empty demo project, refer to the Get started section of the Bookdown official documentation.
Or you can git clone
the Repo of my example site:
git clone https://github.com/hongtaoh/olymvis-bookdown
I am familiar with my example, so I'll use it for illustration.
In my example, if you only want the book in HTML
format, not in PDF or MS Word, then in _output.yml
please comment out these lines:
bookdown::pdf_book:
includes:
in_header: preamble.tex
latex_engine: xelatex
citation_package: natbib
keep_tex: yes
bookdown::epub_book:
stylesheet: css/style.css
In index.Rmd
, comment out:
output:
bookdown::word_document2:
toc: true
If you wist to generate PDF, you need to install a LaTeX distribution. Yihui recommends installing TinyTex if you don't have one distribution installed already.
Each chapter should be a stand-alone .Rmd
file. You need to start the .Rmd
file with a chapter name using # Chapter Name
. If you don't want a certain chapter to be numbered, use # Chapter Name {-}
. To make the url of each chapter look decent, you can tag it as # Chapter Name {#WhateverTagYouLike}
.
Each chapter can have sections and subsections, which are set with second/third/fourth/fifth/sixth-level headings. Sections and Subsections can also be tagged.
Read here for more details.
Open your book_project.Rproj
with Rstudio, on the upper-right panel, click "Build" and then click "Build book".
Read Chapter 4 Customization for details.
Alongside the ease of creating an elegant-looking HTML online book, Bookdown makes it a trivia task to generate PDF, E-books (EPUB and MOBI), and even MS Word versions of the book. Very little customization is needed. For example, with fewer than 10 lines of LaTeX codes, I was able to generate this not-so-bad PDF output. The MS Word output looks pretty good to me.
You should configure the output formats in index.Rmd
and _output.yml
. See more details in Chapter 3 Output Formats.
Publishing through Netlify is an easy method. Create a GitHub Repo and configure Netlify as in 3.6 Publish of Jupyterbook. In the last step of Netlify configuration (i.e., before clicking "Deploy site"), leave the "Build command" blank and use _book
as the "Publish directory".
Read Chapter 6 Publishing for more options.