Skip to content

Instantly share code, notes, and snippets.

@dcode
Last active October 17, 2025 12:30
Show Gist options
  • Save dcode/0cfbf2699a1fe9b46ff04c41721dda74 to your computer and use it in GitHub Desktop.
Save dcode/0cfbf2699a1fe9b46ff04c41721dda74 to your computer and use it in GitHub Desktop.
Demo of some useful tips for using Asciidoc on GitHub

SSH Proxy Setup

Overview

I think most people use Markdown when creating documentation on GitHub. Markdown is great and easy, but I often create technical documentation or training material where some of the additional semantics of Asciidoc are really helpful.

:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:

= Asciidoc on GitHub

[NOTE]
====
A sample note admonition.
We can use gemoji icons in the Asciidoctor markup.
We assign an icon name to the document
attributes `tip-caption`, `note-caption` and `important-caption`.
====

TIP: It works!

IMPORTANT: Asciidoctor is awesome, don't forget!

CAUTION: Don't forget to add the `...-caption` document attributes in the header of the document on GitHub.

WARNING: You have no reason not to use Asciidoctor.

Generate & Load Keys

First things first, you’re going to need some crypto keys.

OpenSSH (Linux or Mac)

If you do not already have RSA (or EC) keys, you can generate the default key path using the following command in a terminal.

ssh-keygen -t rsa

This will store the key in ${HOME}/.ssh/id_rsa by default and prompt you for a passphrase. On both a Mac and Linux graphical desktops, this passphrase can be managed by the desktop keyring, so go ahead and make it a strong one. Either way, you only have to enter it once per user session.

Your public key is stored in ${HOME}/.ssh/id_rsa.pub. This is the file that you will need to copy to remote systems, and as the name implies, is safe to freely share to authenticate yourself.

Finally, you want to load it into your SSH key agent. First, test that you have an SSH agent loaded by trying to list your current keys.

ssh-add -l

If this states that you cannot connect to an agent, we’ll need to start one.

eval $(ssh-agent)

Now add your key (it will prompt you for your key passphrase)

ssh-add ${HOME}/.ssh/id_rsa

You should now be able to view your identity

ssh-add -l
2048 14:7b:4f:f9:0d:19:26:bb:b5:6f:bf:10:0f:df:90:5b /home/luser/.ssh/id_rsa (RSA)

Putty Key Generation

While PuTTY is a client program for SSH (in addition to Telnet and Rlogin), it is not a port of or otherwise based on OpenSSH. Consequently, PuTTY does not have native support for reading OpenSSH’s SSH-2 private key files. However, PuTTY does have a companion named PuTTYgen (an RSA and DSA key generation utility), that can convert OpenSSH private key files into PuTTY’s format; allowing you to connect to your cloud server from a Windows machine, with the added security that SSH keys provide.

PuTTYgen is a (free) open-source utility and can be downloaded from the maintainer’s website. PuTTYgen is what you will use to generate your SSH keys for use in PuTTY. To start, all you need to do is download the exectuable files (.exe) and save them on the computer that you’ll use to connect to your VPS, e.g. on the desktop. You will not need to "install" PuTTYgen, because it is a standalone application.

Generating OpenSSH-compatible Keys for Use with PuTTY

To generate a set of RSA keys with PuTTYgen:

  1. Start the PuTTYgen utility, by double-clicking on its .exe file;

  2. For Type of key to generate, select SSH-2 RSA;

  3. In the Number of bits in a generated key field, specify either 2048 or 4096 (increasing the bits makes it harder to crack the key by brute-force methods);

  4. Click the Generate button;

  5. Move your mouse pointer around in the blank area of the Key section, below the progress bar (to generate some randomness) until the progress bar is full;

  6. A private/public key pair has now been generated;

  7. In the Key comment field, enter any comment you’d like, to help you identify this key pair, later (e.g. your e-mail address; home; office; etc.) — the key comment is particularly useful in the event you end up creating more than one key pair;

  8. You should type a passphrase in the Key passphrase field & re-type the same passphrase in the Confirm passphrase field. Since we’ll be using an agent to load the keys, you’ll only have to type this once per session. Make it a strong passphrase.

  9. Click the Save public key button & choose whatever filename you’d like (some users create a folder in their computer named my_keys);

  10. Click the Save private key button & choose whatever filename you’d like (you can save it in the same location as the public key, but it should be a location that only you can access and that you will NOT lose! If you lose your keys and have disabled username/password logins, you will no longer be able log in!);

  11. Right-click in the text field labeled Public key for pasting into OpenSSH authorized_keys file and choose Select All;

  12. Right-click again in the same text field and choose Copy. Use this to setup the Public Key on the Remote Server(s) after we setup your ssh agent using Pageant.

Add Your Key to Pageant

If you installed the full distribution of PuTTY, you will have a number of utilities in the same directory as putty.exe. Namely, pageant.exe, plink.exe, and others. Launch Pageant. It will start minimized to the system tray by default. Right-click on the icon and select View Keys.

pageant 1

Click the Add Key button. This will open the file explorer, wher eyou can choose one or more keys at a time to load. You should select files with .ppk extension, which is the PuTTY key format.

pageant 2

If the key is passphrase-protected, Pageant will ask for your passphrase for that key. Once your key is loaded, you will no longer be prompted for the passphrase.

pageant 3

Once successfully loaded, you will see it listed in the Pageant Key List window.

pageant 4

Setup Your Public Key on the Remote Server(s)

Now it’s time to setup the remote server. You will want to do this on the jump box and the final endpoint.

  1. SSH to the system and ensure your .ssh is set up. SSH requires read and write privileges to only your user account. Without this, it will fail.

mkdir -p ${HOME}/.ssh
chmod 0700 ${HOME}/.ssh

Now add your public key to the file ${HOME}/.ssh/authorized_keys. This is from id_rsa.pub on your local system (or the key we copied from PuTTY).

cat <<eof | tee -a ${HOME}/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDR3vzk//b72jiwReXjK/AKycn2UQMNm3H3GR2OS0nsudHA5hfyl9PsoyZWpQFdrt0Q5Caz7LszBjBm1qS1EEnE4fQa2qXLnNj3LI0r+hRhvonKJnDuTgaTkmVYfD2fcLWA718u5y2/TTStAC1xdcb+4T3vmVHvysWL08wEHa8TQT5woLgHufnFmRQs6Z+L0En2uaTeEFFVQMpo4z0eF2fXuy3XJXk71cghHsUJk7H/3jbo19NtORR23dNQMwwJLBodEoX95M2ruVyCWFnP356T02T9WkKpoTUdZY5UKQq+I3Ad0GTFoG2hKRuDbqrYVTw8dQUPUfh4Lfc/O+iHp8lR luser
eof

After you’ve done this on the jump box, try logging in again. If everything is setup correctly, you shouldn’t be prompted for a password.

From the jumpbox, ssh to your next hop and repeat the process. To test your keys on the next hop, connect to the jumpbox with the option to Forward SSH Agent. This is ssh -A user@jumpbox using OpenSSH. It is in the SSH options in PuTTY.

Setup the Proxy (Show me the magic!)

OpenSSH

On your local workstation, edit the file (or create if needed) ${HOME}/.ssh/config. This file lets us set per-host preferences for SSH.

Excerpt from ${HOME}/.ssh/config
Host jumpbox
    Hostname 10.5.3.4

Host endpoint (1)
    User            my-username (2)
    Hostname        192.168.3.2 (3)
    ForwardAgent    yes (4)
    ProxyCommand    ssh -q -x jumpbox -W %h:%p (5)
  1. This is the hostname, IP address, or alias that SSH will match on

  2. The User option is only needed if it differs from your local username

  3. This is the hostname that SSH will actually try to connect to. It can be a DNS resolvable name or an IP address

  4. This tells SSH to forward your agent socket to the remote systems so you can authenticate to other systems

  5. This is what tells SSH how to connect to this system through another system. In this case, we use the alias jumpbox which is also defined in this file.

You should now be able to SSH directly to your endpoint! Try it out!

PuTTY

The concepts of the PuTTY configuration are similar. Create a connection entry as normal (specifying username in Data if needed), and select Connection → Proxy.

Specify the proxy type as local and put the jumpbox hostname as the Proxy Hostname. The equivalent to the ProxyCommand in OpenSSH is the lower box labelled Telnet command, or local proxy command. Enter the following:

plink %user@%proxyhost -nc %host:%port

Your configuration should look something like this:

putty proxy
ℹ️
Thats it! Get back to work!
@abelsromero
Copy link

@Sherspock

Is this supported somehow without making use of a process-and-commit pipeline, whether by workaround or not?

Not in GitHub, but they do work in Gitlab. But with GH-Actions the procres is made really easy.

I've also tried using the AsciiDoc chrome plugin in Brave with no luck properly rendering adocs with include directives in them on GitHub either.

Just guessing, but if you are using something like include::my-part.adoc[] I doubt the plugin is able get the path. Overall, I'd recomend not to try to get a 100% accurate local preview or repository UI preview, complex doc builds just will require doing a full conversion.
Said that, on the bright side, intellij plugin offers the best experience so far in local, with a decent preview, autocomplete and refactor features.

Does this work in GitLab? github/markup#1095 isn't stagnant, but I didn't see anything that looked especially promising at a glance.

Yes, not a rant, just facts. It's true that GitLab team has been more open to imprevements that GitHub, work with the later is slower.

@fsundermeyer
Copy link

I spent a little chunk of time trying to find your workaround in both the project you
mentioned and the project it was absorbed into. Naturally I had to backtrack a little
with SUSE. I couldn't actually find a single instance in either of an include rendering > properly in GitHub.

As far as I know including files in ASCIIDoc documents as well as resolving attributes is disabled for security reasons on GitHub.
However, it looks like a simple include statement at least results in a clickable link to the included document in the meantime, so the workaround I posted above is no longer needed (see https://github.com/SUSE/doc-caasp/blob/master/adoc/book_admin.adoc for an example).

Does this work in GitLab?

https://about.gitlab.com/releases/2019/06/22/gitlab-12-0-released/#support-for-asciidoc-include-directive
It at least works in an on premise Gitlab installation I am using (including resolving of attributes), haven't tested gitlab.com, though.

@yakryder
Copy link

@abelsromero
Thank you much! Without understanding it better or having some clear examples of how it might work in my specific context, the idea of allowing an action to commit changes makes me nervous. I appreciate the GitLab and plugin tip!

@fsundermeyer
Ah, thank you! It's clear to me now I didn't understand what that workaround was for.

Looks like a self-hosted instance of GitLab isn't necessary to make this work. I have confirmed that includes and attributes appear to work just fine on GitLab. At least in a simple test case including text and an attribute from a single document into another with a reference to that attribute.

@abelsromero
Copy link

@Sherspock

Thank you much! Without understanding it better or having some clear examples of how it might work in my specific context, the idea of allowing an action to commit changes makes me nervous. I appreciate the GitLab and plugin tip!

The publicaton in fact is trivial with https://github.com/JamesIves/github-pages-deploy-action. Here is an example of a GH-Action that publishes and Antora/Asciidoctor site on GH-Pages when a change on "main" branch is done, docs are in a folder called "docs" alongside the code. The tricky part is using upload-artifact and download-artifact to share the resulted converted docs in HTML between conversion and push steps.
The only thing to adapt is the "Generate site using antora site action", the rest is always the same.

To know more just drop by the asciidoctor gitter channels or the forum.

name: Build & publish docs
on:
  push:
    branches:
      - main

env:
  SITE_DIR: 'site'

jobs:
  build_site:
    name: "Build site with Antora"
    runs-on: [ubuntu-latest]
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: "Generate site using antora site action"
        uses: kameshsampath/antora-site-action@master
        with:
          antora_playbook: antora-playbook.yml
      - name: "Upload generated site"
        uses: actions/[email protected]
        with:
          name: site
          path: "${{ github.workspace }}/build/${{ env.SITE_DIR }}"
  deploy_site:
    runs-on: [ubuntu-latest]
    needs: [build_site]
    name: "Deploy GitHub Pages"
    steps:
      - name: Setup Node.js for use with actions
        uses: actions/[email protected]
        with:
          version: '14'
      - name: Checkout
        uses: actions/checkout@v2
      - name: Download generated site
        uses: actions/download-artifact@v1
        with:
          name: site
          path: "${{ github.workspace }}/${{ env.SITE_DIR }}"
      - name: Deploy to GitHub Pages
        uses: JamesIves/[email protected]
        with:
          GITHUB_TOKEN: "${{ github.token}}"
          FOLDER: "${{ env.SITE_DIR }}"
          BRANCH: 'gh-pages'
          COMMIT_MESSAGE: "[CI] Publish Documentation for ${{ github.sha }}"
          CLEAN: true

@mojavelinux
Copy link

As we work on revamping the docs site for Asciidoctor, I would love to see a section dedicated to succeeding with AsciiDoc on GitHub. There are certainly idiosyncrasies to understand and having a docs page on the topic will certainly help people who host their AsciiDoc files there. Perhaps consider submitting this to the new docs for Asciidoctor (which will live in the main asciidoctor repository).

My only objection is the term "GitHub Flavored AsciiDoc". There is no such thing. Please don't use this term as it suggests fragmentation that's simply not there (like there is with Markdown). There is only one AsciiDoc. The software GitHub uses to process it is the same software that's used throughout the ecosystem (Asciidoctor). What differs is how the rendered HTML is displayed. GitHub applies their own stylesheet to it, one that we have little control over. There is a somewhat unspoken API with the stylesheet in AsciiDoc that becomes visible when a different stylesheet is applied. I think those differences are certainly worth noting. GitHub also disables includes, but that is another matter.

(If any term applies here, it would be GitHub Limited AsciiDoc. But I'm concerned that would come across as unnecessarily critical.)

@mojavelinux
Copy link

In order for [images] to be rendered inline, you must provide an absolute path to the :imagesdir: directive.

This is not a true assertion. Relative image paths do work. If the document is nested in a different structure than the images, you may need to use a different value compared to your publishing environment. But relative paths work even in this scenario.

@siddjain
Copy link

what about math? math does not render for me on github.

@JoeArauzo
Copy link

Thanks for the tip on how to get admonitions with icons working on GitHub. Take a look at my AsciiDoc README Template.

@Jeeppler
Copy link

@mojavelinux thanks for pointing out that all includes are disabled in GitHub. Furthermore, the most important messages was, that there is no fragmentation and no GitHub Flavored Asciidoc (GFA).

@mojavelinux
Copy link

what about math? math does not render for me on github.

It's true that math (i.e., STEM) does not render on GitHub. Though there are workarounds we could still explore, like using their image service to generate an SVG (e.g., https://render.githubusercontent.com/render/math?math=\displaystyle \text{b} = V D) But just because GitHub won't render something doesn't make it not AsciiDoc. It just means GitHub is not providing a full fidelity experience. And there's literally nothing we can do about it*. We have offered to help. But at the end of the day, it's their platform and their choice. And they simply refuse to implement certain display features, despite countless pleas from the community.

Where you do see these display features implemented is on GitLab. I think, in many ways, they are leading the way on what it means to support AsciiDoc properly in a repository browser, and hopefully others will follow.

* Perhaps the AsciiDoc WG can play an arbitration role. We'll have to see.

@mojavelinux
Copy link

@JoeArauzo Nice!

@husam-e
Copy link

husam-e commented Mar 8, 2021

Thanks for this! Any tips on rendering mermaid diagrams in asciidoc READMEs?

@JoeArauzo
Copy link

Thanks for this! Any tips on rendering mermaid diagrams in asciidoc READMEs?

I see mention of mermaid diagrams at https://asciidoctor.org/docs/asciidoctor-diagram/.

@diguage
Copy link

diguage commented Mar 29, 2021

:toc:
:toc-placement!:

Here is my preamble paragraph, but I could really place the TOC anywhere! Lorem ipsum foo bar baz.

toc::[]

It's nice. Thank you!

@eshepelyuk
Copy link

eshepelyuk commented Mar 30, 2021

Does GitHub exposeb any other custom attributes except env-github ?
Or maybe there is a way to detect current repo name.

It could be extremely usuful for PR s.

@jlisee
Copy link

jlisee commented Jul 6, 2021

@dcode thanks for putting this out there, it's a great demo of what Asciidoc can do in GitHub. I did notice that all of your links are broken, for example the first link should be link:http://asciidoctor.org/[Asciidoctor] not link::http://asciidoctor.org/[Asciidoctor]. The issue is that you are using link:: instead of the normal link: macro to start your links.

@kspurgin
Copy link

It looks like it might not be possible to have inline rendered images in an AsciiDoc file in a private repo.

I think it assumes the <img src= value used to render the image will be base url from imagesdir + image file name from image reference

But in a private repo, there is a token on the end of the URL for any raw file.

@b-layer
Copy link

b-layer commented Oct 30, 2021

Anyone else notice that sidebars don't render well on GH? I tried using it here https://github.com/b-layer/musecnav#popup (it starts with the text "Numerical Selection in the Popup"). No visual delineation...looks terrible. Looks fine locally.

@abelsromero
Copy link

@b-layer There's not much tha can be done. This is GitHub-Flavored Asciidoc, not all features are allowed and there are some style modifications. Using GH preview is nice for simple things, but not something to consider for a professional result.

@b-layer
Copy link

b-layer commented Nov 4, 2021

@abelsromero Yes, thanks, I'm aware of all that but I hadn't seen any mention of this particular failing before (e.g. in the gist we're commenting on) and was wondering if perhaps I'd missed something, if there is any known workaround and if no to both of those at least to note it for any future readers wondering the same thing.

@theAkito
Copy link

theAkito commented Nov 9, 2021

I've tested using the .ad file name extension several times, already. It simply does not work!

@diguage
Copy link

diguage commented Feb 17, 2022

How to use asciidoc in the issue?

@JoeArauzo
Copy link

@theAkito You must use either .asciidoc, .adoc, or .asc, per https://github.com/github/markup/blob/master/README.md#markups.

@prudhomm
Copy link

nice doc!
it is a pity that Github does not have the same level of support for asciidoc as gitlab
in particular supporting math

@donnels
Copy link

donnels commented May 17, 2022

Nice if statement helps me a lot. thank you.

@pepa65
Copy link

pepa65 commented Jul 23, 2023

I just created a README.ad but it is not rendered at all...
Edit: Turns out .ad is not recognized, so use .adoc.

@dcode Please correct this gist by replacing .ad with .asc!

@abelsromero
Copy link

abelsromero commented Jul 24, 2023

Leaving the list of official file extensions here because it always takes me some time to find 👉 https://github.com/github/markup/blob/master/README.md#markups (.asciidoc, .adoc, .asc)

@dcode
Copy link
Author

dcode commented Jul 24, 2023

file extension updated. It did used to be .ad. I never intended this gist to be an authoritative documentation source, but I'm glad it's helped so many people! Sorry it took so long to get the file extension edited.

@dcode
Copy link
Author

dcode commented Jul 24, 2023

Fixed the links, as well.

@Fred-Vatin
Copy link

About

:toc:
:toc-placement!:

Here is my preamble paragraph, but I could really place the TOC anywhere! Lorem ipsum foo bar baz.

toc::[]

This is deprecated.
If you want to position toc::[] anywhere, now use:

:toc: macro

Here is my preamble paragraph, but I could really place the TOC anywhere! Lorem ipsum foo bar baz.

toc::[]

If you want to position it after a preamble, use this:

:toc: preamble

Here is my preamble.
The toc will be inserted after the ''' (this insert a line) and before the first section.
No need to use the macro toc::[] anymore.

'''

== First section

source

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment