Skip to content

Writing tips for MkDocsλ︎

Making the docs more engaging using the mkdocs-material theme reference guide

Configuring Colors

Material for MkDocs - Changing the colors lists the primary and accent colors available.

HSL Color Picker for codes to modify the theme style, overriding colors in docs/assets/stylesheets/extra.css

Links open in the same browser window/tab by default.

Add {target=_blank} to the end of a link to configure opening in a new tab

[link text](url){target=_blank}

Buttonsλ︎

Convert any link into a button by adding {.md-button} class names to end of the markdown for a link, which uses .md-button-primary by default. Include target=_blank for buttons with links to external sites.

[link text](http://practical.li/blog){.md-button target=_blank}

Or specify a different class

[link text](http://practical.li/blog){.md-button .md-button-primary}

Add an icon to the button

Practicalli Issues Practicalli Blog

[:fontawesome-brands-github: Practicalli Issues](http://practical.li/blog){ .md-button .md-button-primary }
[:octicons-heart-fill-24: Practicalli Blog](http://practical.li/blog){ .md-button .md-button-primary }

Search all supported icons

YouTube videoλ︎

Use an iframe element to include a YouTube video, wrapping in a paragraph tag with center alignment to place the video in a centered horizontal position

<p style="text-align:center">
<iframe width="560" height="315" src="https://www.youtube.com/embed/rQ802kSaip4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</p>

mkdocs material does not have direct support for adding a YouTube video via markdown.

Admonitionsλ︎

Supported admonition types

Note

Use !!! followed by NOTE

Adding a title

Use !!! followed by NOTE and a "title in double quotes"

Shh, no title bar just the text... Use !!! followed by NOTE and a "" empty double quotes

Abstract

Use !!! followed by ABSTRACT

Info

Use !!! followed by INFO

Tip

Use !!! followed by TIP

Success

Use !!! followed by SUCCESS

Question

Use !!! followed by QUESTION

Warning

Use !!! followed by WARNING

Failure

Use !!! followed by FAILURE

Danger

Use !!! followed by DANGER

Bug

Use !!! followed by BUG

Example

Use !!! followed by EXAMPLE

Quote

Use !!! followed by QUOTE

Collapsing admonitionsλ︎

Note

Collapse those admonitions using ??? instead of !!!

Replace with a title

Use ??? followed by NOTE and a "title in double quotes"

Expanded by default

Use ???+, note the + character, followed by NOTE and a "title in double quotes"

Inline blocksλ︎

Inline blocks of text to make a very specific callout within text

Info

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Adding something to then end of text is probably my favourite

Info

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Code blocksλ︎

Code blocks include a copy icon automatically

Syntax highlighting in code blocks

(defn my-function  ; Write a simple function
  "With a lovely doc-string"
  [arguments]
  (map inc [1 2 3]))

Give the code block a title using title="" after the backtics and language name

src/practicalli/gameboard.clj
(defn my-function
  "With a lovely doc-string"
  [arguments]
  (map inc [1 2 3]))

We all like line numbers, especially when you can set the starting line

src/practicalli/gameboard.clj
(defn my-function
  "With a lovely doc-string"
  [arguments]
  (map inc [1 2 3]))

Add linenums=42 to start line numbers from 42 onward

clojure linenums="42" title="src/practicalli/gameboard.clj"

Annotationsλ︎

Annotations in a code block help to highlight important aspects. Use the comment character for the language followed by a space and a number in brackets

For example, in a shell code block, use # (1) where 1 is the number of the annotation

Use a number after the code block to add the text for the annotation, e.g. 1.. Ensure there is a space between the code block and the annotation text.

ls -la $HOME/Downloads  # (1)
  1. 🙋‍♀️ I'm a code annotation! I can contain code, formatted text, images, ... basically anything that can be written in Markdown.

Code blocks with annotation, add ! after the annotation number to suppress the # character

(defn helper-function
  "Doc-string with description of function purpose" ; (1)!
  [data]
  (merge {:fish 1} data)
  )
  1. Always include a doc-string in every function to describe the purpose of that function, identifying why it was added and what its value is.

GitHub action example with multiple annotations

name: ci # (1)!
on:
  push:
    branches:
      - master # (2)!
      - main
permissions:
  contents: write
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v4
        with:
          python-version: 3.x
      - run: pip install mkdocs-material # (3)!
      - run: mkdocs gh-deploy --force
  1. You can change the name to your liking.

  2. At some point, GitHub renamed master to main. If your default branch is named master, you can safely remove main, vice versa.

  3. This is the place to install further [MkDocs plugins] or Markdown extensions with pip to be used during the build:

    pip install \
      mkdocs-material \
      mkdocs-awesome-pages-plugin \
      ...
    

Highlight lines in code blocksλ︎

Add highlight line meta data to a code block after the opening backticks and code block language.

hl_lines="2" highlights line 2 in the codeblock

(defn my-function
  "With a lovely doc-string"
  [arguments]
  (map
   inc
   [1 2 3]))

Embed external filesλ︎

--8<-- in a code block inserts code from a source code file or other text file, e.g.

--8<-- "https://github.com/practicalli/project-templates/blob/main/deps.edn?raw=true"

| NOTE: For GitHub, add ?raw=true on the end of the url to the GitHub file or use the raw code link, i.e. https://raw.githubusercontent.com/...

Practicalli Project Templates
Emacs project configuration - .dir-locals.el
{:paths ["src" "resources"]

 :deps
 {org.clojure/clojure {:mvn/version "1.11.3"}}

 :aliases
 {;; Add libraries and paths to support additional test tools
  :test/env
  {:extra-paths ["test"]
   :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
                ;; https://github.com/seancorfield/deps-new/
                io.github.seancorfield/deps-new
                {:git/tag "v0.8.0" :git/sha "2f96530"}}}

  ;; Test runner - local and CI
  ;; call with `:watch? true` argument to start file watcher and re-run tests on saved changes
  :test/run
  {:extra-paths ["test"]
   :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}}
   :main-opts   ["-m" "kaocha.runner"]
   :exec-fn kaocha.runner/exec-fn
   :exec-args {:randomize? false
               :fail-fast? true}}}}

Specifying a local file from the root of the book project (the directory containing mkdocs.yml) only seems to work when running the server locally, e.g. --8<-- ".github/workflows/scheduled-version-check.yaml"

LOCAL File: Only works when running mkdocs server locally
scheduled version check

FULL URL: Always works correctly
scheduled version check
---
# ------------------------------------------
# Scheduled check of versions
# - use as non-urgent report on versions
# - Uses POSIX Cron syntax
#   - Minute [0,59]
#   - Hour [0,23]
#   - Day of the month [1,31]
#   - Month of the year [1,12]
#   - Day of the week ([0,6] with 0=Sunday)
#
# Using liquidz/anta to check:
# - GitHub workflows
# - deps.edn
# ------------------------------------------

name: "Scheduled Version Check"
on:
  schedule:
    # - cron: "0 4 * * *" # at 04:04:04 ever day
    # - cron: "0 4 * * 5" # at 04:04:04 ever Friday
    - cron: "0 4 1 * *" # at 04:04:04 on first day of month
  workflow_dispatch: # Run manually via GitHub Actions Workflow page

jobs:
  scheduled-version-check:
    name: "Scheduled Version Check"
    runs-on: ubuntu-latest
    steps:
      - run: echo "🚀 Job automatically triggered by ${{ github.event_name }}"
      - run: echo "🐧 Job running on ${{ runner.os }} server"
      - run: echo "🐙 Using ${{ github.ref }} branch from ${{ github.repository }} repository"

      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          sparse-checkout: |
            .github
      - run: echo "🐙 ${{ github.repository }} repository sparse-checkout to the CI runner."
      - name: "Antq Check versions"
        uses: liquidz/antq-action@main
        with:
          excludes: ""
          skips: "boot clojure-cli pom shadow-cljs leiningen"

      # Summary
      - run: echo "🎨 library versions checked with liquidz/antq"
      - run: echo "🍏 Job status is ${{ job.status }}."

Code example reuse

Use an embedded local or external file (URL) when the same content is required in more than one place in the book.

An effective way of sharing code and configuration mutliple times in a book or across multiple books.

Content tabsλ︎

Create in page tabs that can also be

Setting up a project

clojure -T:project/new :template app :name practicalli/gameboard
lein new app practicalli/gameboard

Or nest the content tabs in an admonition

Run a terminal REPL

clojure -T:repl/rebel
lein repl

Diagramsλ︎

Neat flow diagrams

Diagrams - Material for MkDocs

graph LR
  A[Start] --> B{Error?};
  B -->|Yes| C[Hmm...];
  C --> D[Debug];
  D --> B;
  B ---->|No| E[Yay!];

UML Sequence Diagrams

sequenceDiagram
  Alice->>John: Hello John, how are you?
  loop Healthcheck
      John->>John: Fight against hypochondria
  end
  Note right of John: Rational thoughts!
  John-->>Alice: Great!
  John->>Bob: How about you?
  Bob-->>John: Jolly good!

state transition diagrams

stateDiagram-v2
  state fork_state <<fork>>
    [*] --> fork_state
    fork_state --> State2
    fork_state --> State3

    state join_state <<join>>
    State2 --> join_state
    State3 --> join_state
    join_state --> State4
    State4 --> [*]

Class diagrams - not needed for Clojure

Entity relationship diagrams are handy though

erDiagram
  CUSTOMER ||--o{ ORDER : places
  ORDER ||--|{ LINE-ITEM : contains
  LINE-ITEM {
    customer-name string
    unit-price int
  }
  CUSTOMER }|..|{ DELIVERY-ADDRESS : uses

Keyboard keysλ︎

Represent key bindings with Keyboard keys. Each number and alphabet character has their own key.

  • 1 ++1++ for numbers
  • l ++"l"++ for lowercase character
  • U ++u++ for uppercase character or ++"U"++ for consistency

Punctionation keys use their name

  • Space ++spc++
  • , ++comma++
  • Left ++arrow-left++

For key sequences, place a space between each keyboard character

  • Space g s ++spc++ ++"g"++ ++"s"++

For key combinations, use join they key identifies with a +

  • Meta+X ++meta+x++
  • Ctrl+Alt+Del ++ctrl+alt+del++

MkDocs keyboard keys reference

Imagesλ︎

Markdown images can be appended with material tags to set the size of the image, whether to appear on light or dark theme and support lazy image loading in browsers

{style="height:150px;width:150px"} specifies the image size

![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-light.png#only-dark){style="height:150px;width:150px"}

Kitty Logo

{loading=lazy} specifies an image should lazily load in the browser

![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-light.png){loading=lazy}

{aligh=left} or {aligh=right} specifies the page alignment of an image.

![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-light.png#only-dark){align=right}
![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-dark.png#only-light){align=right}

Kitty Logo Kitty Logo Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

![Kitty Logo](image/kitty-light.png#only-dark) or ![Kitty Logo](image/kitty-light.png#only-light) specifies the theme the image should be shown, allowing different versions of images to be shown based on the theme.

![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-light.png#only-dark){style="height:150px;width:150px"}
![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-dark.png#only-light){style="height:150px;width:150px"}
Use the theme toggle in the top nav bar to see the icon change between light and dark. Kitty Logo Kitty Logo

Requires the color pallet toggle

Alight right, lazy load and set image to 150x150

![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-light.png#only-dark){align=right loading=lazy style="height:64px;width:64px"}
![Kitty Logo](https://raw.githubusercontent.com/practicalli/graphic-design/live/icons/kitty-dark.png#only-light){align=right loading=lazy style="height:64px;width:64px"}

Kitty Logo Kitty Logo Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor massa, nec semper lorem quam in massa.

Listsλ︎

Task lists

  • Lorem ipsum dolor sit amet, consectetur adipiscing elit
  • Vestibulum convallis sit amet nisi a tincidunt
    • In hac habitasse platea dictumst
    • In scelerisque nibh non dolor mollis congue sed et metus
    • Praesent sed risus massa
  • Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque

Task List example

- [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit
- [ ] Vestibulum convallis sit amet nisi a tincidunt
    * [x] In hac habitasse platea dictumst
    * [x] In scelerisque nibh non dolor mollis congue sed et metus
    * [ ] Praesent sed risus massa
- [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque

Tooltipsλ︎

The humble tool tip

Hover me

with references

Hover me

Icon tool tip with a title

Abreviationsλ︎

The HTML specification is maintained by the W3C.

[HTML]: Hyper Text Markup Language [W3C]: World Wide Web Consortium

MagicLink can auto-link HTML, FTP, and email links. It can auto-convert repository links (GitHub, GitLab, and Bitbucket) and display them in a more concise, shorthand format.

Email Practicalli

Practicalli Neovim