H1 only appears once in Asciidoctor article
There can be multiple toplevel headings in
:doctype: book
numbered can be set in document header for all headings
Christoph Stoettner
Application Servers
Installation, Configuration
Performance Optimization, Stresstesting
Started with Linux / OSS around 1994/1995
Linux Kernel < 1.0
Slackware
VIM lover
maybe too stupid for Emacs
I’m mainly Administrator using Developer tools |
Content of most of my documentations
Config options (XML, GUI)
Screenshots (GUI)
Parts of Property Files
Used tools
MS Excel / Libreoffice (with Dropbox)
MS Word / Libreoffice with Sharepoint or Mail
Several Wiki engines, Evernote
LaTex and Docbook
Searchable documentation
Editing on mobile, tablet, notebook, customer computer, server (ssh)
Output formats depend on customer and project
Offline support
Version Control
Include config settings of *.xml, *.properties
No manual task to update output format |
Evernote
Linux client long time a problem
New license limits device count
No markdown support
Office
Compatibility
Edit on different devices, versions
Sometimes switching printer is enough to flip images around
Copy&Paste of screenshots and config file settings
Edit from mobile often a pain
Documenting the Wiki itself?
Not accessible when down
Syntax different from one wiki to another
Customer / PM often needs something printed / printer friendly
AND manual copy&paste
I started writing in Markdown
Some software supports markdown directly
Cool WYSIWIG editors
Great for typing notes (Still using it on mobile)
But a little bit too simple
including source files missing
Asciidoc: language definition
Asciidoctor: Ruby project to convert asciidoc source to * output
Text only, Human readable
Version Control with GIT
Only some short syntax tips
More automation later
Differences to Markdown
:doctype: article|book|manpage|inline
Article (article) default
One level 0 heading
Book (book)
Additional top-level title as part titles
Man page (manpage)
roff or HTML-formatted man page
Inline (inline)
Use within source-code, e.g. javadoc
:numbered: (1)
== H2
=== H3
==== H4
:!numbered: (2)
== H2
=== H3
==== H4
1 | Headings numbered |
2 | Headings without numbers |
H1 only appears once in Asciidoctor article
There can be multiple toplevel headings in :doctype: book
numbered can be set in document header for all headings
Can be used with images and all kind of blocks, no TOC entry
.Heading (1)
[source]
----
ls -al
----
.Image (2)
image::test.png[]
1 | Heading above Code block |
2 | Image heading |
=== Bullet Points
* Bullet Points
** Sub Bullet Point
=== Numbered Lists
. Numbered List
.. Sub 1
.. Sub 2
. Numbered 2
=== Definition Lists
CPU:: The brain of the computer.
Hard drive:: Permanent storage for operating system...
https://www.stoeps.de[] (1)
https://www.stoeps.de[Stoeps] (2)
1 | Shows just the link |
2 | Link text in brackets |
image::sunset.jpg[]
image::sunset.jpg[role=right] (1)
image:sunset.jpg[] (2)
1 | You can add roles to all elements and use CSS for formatting |
2 | One colon after image → inline image, double colon → figure |
:
<div class="imageblock" style=""><img src="images/sunset.jpg" alt="sunset"></div>
<div class="imageblock right" style=""><img src="images/sunset.jpg" alt="sunset"></div>
:
<div class="paragraph"><p><span class="image"><img src="images/sunset.jpg" alt="sunset"></span></p></div>
You can add any Font Awesome Icon
Enable in document header
:icons: font
icon:twitter[] Twitter https://twitter.com[@stoeps]
icon:linux[] Linux Icon
icon:windows[] Windows Icon
Admonition blocks (Warning, Caution, Important, Note, Tip)
Font-Awesome Icons with :icons: font
WARNING: This is a warning
This is a warning |
CAUTION: This is a caution
This is a caution |
IMPORTANT: This is important
This is important |
NOTE: A note
TIP: Here is a tip
IMPORTANT: That's important
WARNING: Warning message
CAUTION: Caution, be careful
:experimental: (1)
1 | Following features need experimental set |
.Copy Text
menu:Edit[Copy Special > Text]
.Button
Press kbd:[OK]
.Keyboard
kbd:[Ctrl+C] to stop this.
Adding [source]
.A Python function
[source,python]
----
def function():
var x = 10
return x
----
Syntax Highlighting with Pygments, Highlightjs or Rouge
:source-highlighter: pygments|highlightjs|rouge
Split longer documents and include Asciidoc Source
Include any type of files in [source]
Powerful
Include complete files
Include only parts
include::path/filename[] (1)
include::path/filename[lines=10..15] (2)
include::path/filename[tags=mytag] (3)
1 | Include entire file |
2 | Include lines 10-15 |
3 | Include area between mytag tags tag::mytag, end::mytag |
...
<title>example</title>
<!-- tag::stoeps[] -->
<!-- even comments -->
</head><body>
<h1>Test</h1>
<!-- end::stoeps[] -->
</body>
...
[source, indent=0]
----
include::test.html[tags=stoeps]
----
<!-- even comments -->
</head>
<body>
<h1>Test</h1>
[source]
----
def function:
x = 'secret' # <1>
print(secret)
return 0
----
<1> Hardcoded variable
def function:
x = 'secret' (1)
print(secret)
return 0
1 | Hardcoded variable |
:variable: content (1)
:OS: Linux (2)
:SLASH: / (3)
1 | Generic definition |
2 | Variable OS set to Linux |
3 | Variable SLASH set to / |
:OS: Windows Server 2016 Datacenter Edition
:SLASH: \
:VERSION: 0.8
:OS: Linux
:SLASH: /
:VERSION: 8.5.5.4
Include into main document (main.adoc
)
Use generic variable file for example to store OS differences
Add additional one for project specific paths, hostnames
.
├── _attributes.asciidoc
├── images
├── include
├── main.adoc (1)
├── more.asciidoc
├── _variables-linux.asciidoc (2)
├── _variables_project.asciidoc (4)
└── _variables-win.asciidoc (3)
1 | Main document |
2 | Variables for Linux OS installations |
3 | Variables for Windows installations |
4 | Project specific variables |
Within main document show different informations based on variables
:OS: Linux (1)
ifeval::["{OS}" == "Linux"] (2)
icon:linux[] rocks!
endif::[]
:OS: Windows (3)
ifeval::["{OS}" == "Windows"] (4)
icon:windows[] really?
endif::[]
:OS: Linux
1 | Set OS = Linux |
2 | If OS = Linux |
3 | Set OS = Windows |
4 | If OS = Windows |
Asciidoctor supports a lot of different formats
ditaa
plantuml
Often enough to show a network or infrastructure overview
Like Asciidoctor human readable
[ditaa]
....
+-------------+
| Asciidoctor |-------+
| diagram | |
+-------------+ | PNG out
^ |
| ditaa in |
| v
+--------+ +--------+----+ /---------------\
|c9CF | --+ Asciidoctor +--> |c9CC |
|Document| +-------------+ | Beautiful |
| {d}| | !magic! | | Output |
+---+----+ +-------------+ \---------------/
....
[plantuml]
....
title Network Plan
actor user [
User
]
actor admin [
Administrator
]
node http [
HTTP Server
connect.example.com
]
node dmgr [
WebSphere Deployment Manager
dmgr.example.com
]
database db2 [
DB2 Database Server
db2.example.com
]
user -down-> http:443/tcp
admin -right-> dmgr:9043/tcp
admin -down-> db2:50000/tcp
dmgr -up-> http
dmgr -down-> db2
center footer Connections 6.0 Deployment
....
[plantuml]
....
start
if (Graphviz installed?) then (yes)
:process all\ndiagrams;
else (no)
:process only
__sequence__ and __activity__ diagrams;
endif
stop
....
.Hostnames
[%header, cols=3]
|===
|Hostname
|IP
|Function
|www.example.com
|192.168.1.100
|Webserver
|dmgr.example.com
|192.168.2.100
|Application Server
|db.example.com
|192.168.2.101
|Database Server
Let’s have a look at a simple document with the main parts
Automate with Gitlab and CI/CD
It’s also possible with Travis CI or Jenkins
Just to have a working example
Asciidoctor gradle
Git (with GitLab)
Gitlab CI/CD functionality
= Example Project Documentation (1)
:author: Christoph Stoettner
:email: christoph.stoettner@stoeps.de
:revnumber: 1.0
:revdate: 2018-08-24
:revremark: Froscon 2018
:encoding: utf-8
:lang: en (2)
:experimental: (3)
:title-logo-image: image::logo.png[] (4)
:toc: (5)
:imagesdir: images (6)
:doctype: article
:icons: font (7)
:source-highlighter: rouge (8)
:quick-uri: https://www.stoeps.de
:numbered: (9)
include::_variables-linux.asciidoc[]
include::_variables-project.asciidoc[]
include::_attributes.asciidoc[] (10)
1 | Document title |
2 | Language |
3 | Enable experimental features |
4 | Title logo (for pdf title page) |
5 | Create table of contents |
6 | Default images directory |
7 | Use Font Awesome Icons |
8 | Use rouge for Syntax Highlighting |
9 | Headings numbered |
10 | Translation file for built-in labels, so the labels for language used in (2) will be inserted |
// German translation, courtesy of Florian Wilhelm
ifeval::["{lang}" == "de"]
:appendix-caption: Anhang
:caution-caption: Achtung
:chapter-label: Kapitel
:example-caption: Beispiel
:figure-caption: Abbildung
:important-caption: Wichtig
:last-update-label: Zuletzt aktualisiert
//:listing-caption: Listing
:manname-title: BEZEICHNUNG
:note-caption: Anmerkung
//:preface-title: Vorwort
:table-caption: Tabelle
:tip-caption: Hinweis
:toc-title: Inhalt
:untitled-label: Ohne Titel
:version-label: Version
:warning-caption: Warnung
endif::[]
First paragraph after header section
include::_attributes.asciidoc[]
Get tough with it, get strong.
This is the way you take out your flustrations.
Go out on a limb - that's where the fruit is.
If we're gonna walk though the woods, we need a little path.
Trees live in your fan brush, but you have to scare them out.
== Networkplan
It’s Asciidoc best practise to write each sentence into one line |
Paragraph until first blank line
In chapter Networkplan I include a plantuml file
=== Software Updates
Here we check the `VERSION` from our variables doc.
When we update the main document, it can happen that we adjust the version numbers,
then new generated documents show this warning.
ifeval::["{VERSION}" >= "8.5.5.7"]
INFO: No updates needed!
endif::[]
ifeval::["{VERSION}" < "8.5.5.6"]
WARNING: Update needed!
endif::[]
Documention is splitted into generic parts
Differences
Slash or Backslash
.bat or .sh
Paths
Small differences I handle with
ifeval::["{variable}" == "OS Type"]
Paths and hostnames are stored in _variables-xxx.asciidoc
So moving to a new version only needs adjustments in main.adoc
Working to get customers to commit configuration to internal git servers
Adding these repositories to documentation repository
git add submodule https://internal.gitserver.example.org/appserver/mainconfig.git
Git directories within repositories
Lots of different Outputs
Html 5
ePub
Docbook
Confluence Wiki
Reveal JS Presentation
A huge amount of outputs:
You can build your own themes
HTML
Best: you can use any editor on any device
Syntax Highlighting in the most important ones
VIM
Emacs
Notepad++
VSCode|VSCodium, Atom
On Windows, stay away from Notepad and Wordpad because they produce plain text which is not cross-platform friendly. |
I use git for all documents
Version Control
Good mobile clients (for small adjustments)
Android
Termux
Vim
Git
Browser interface (Github, Gitlab)
(in the beginning) you will ask for WYSIWIG or Preview
VS Codium has a built-in preview plugin
Browser Extension to render Asciidoc
Check whitelist or you won’t see Font Awesome icons
convert your documents with make
Run make everytime when file is saved
Very powerful when you finalize documents or presentations
Asciidoctor works on Windows, Linux or Mac
Installation https://asciidoctor.org/docs/install-toolchain/
Ruby Gems or Package Manager
Convert on the command line
# Creates HTML of yourfile.adoc, name: yourfile.html
asciidoctor yourfile.adoc
# Create PDF
asciidoctor-pdf yourfile.adoc
You need to install all dependencies |
Easy to use
Runs on all OS which supports Docker
Windows, Linux & Mac OS
All dependencies already included
Fits perfectly into CI/CD scenarios
# convert main.doc to html
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor main.adoc
# Run this in the folder with your asciidoc files
docker run \
--rm \ (1)
-v $(pwd):/documents/ \ (2)
asciidoctor/asciidoctor \ (3)
asciidoctor \ (4)
main.adoc (5)
1 | delete container after run |
2 | Use Volume $(pwd) actual path in Linux and Mac OS as /documents in container |
3 | Image name (template for container) |
4 | Run command asciidoctor in that container |
5 | On document main.adoc |
Special command line options can be added! |
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor main.adoc
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor -r asciidoctor-diagram main.adoc
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor-pdf -r asciidoctor-diagram main.adoc
asciidoctor-confluence --host HOSTNAME --spaceKey KEY --title TITLE \
--username USER --password PASSWORD [--update] sample.adoc (1)
1 | With --update the page gets updated, without created |
A full integrated Gradle implementation is used by docToolchain
Check it out, if you need a full featured solution
Advantage
Downloads all dependencies
Works with DevOps toolsets
Gradle can be used with Gitlab CI/CD, Travis CI and Jenkins
Best result
Hosted (https://gitlab.com) and Selfhosted
Converts on commit
Browse, publish or download results
Deploy the documents to webservers
How to:
Add CI/CD to your Gitlab project
Create .gitlab-ci.yml
.
├── docker-asciidoctor (submodule)
├── documents-personal
│ ├── basic-example.adoc
├── documents-work
│ ├── basic-example.adoc
├── images
│ └── logo.png
├── LICENSE
├── pdftheme
│ ├── logo.png
│ ├── personal-theme.yml
│ └── work-theme.yml
├── presentations
│ └── slidedeck.adoc
├── public
│ ├── html-personal
│ ├── html-work
│ ├── images
│ ├── pdf-personal
│ ├── pdf-work
│ └── presentations
├── README.adoc
├── scripts
│ ├── create-index.sh
│ ├── html-conversion.sh
│ ├── html-work-conversion.sh
│ ├── pdf-conversion.sh
│ ├── pdf-work-conversion.sh
│ └── reveal-conversion.sh
└── wiki-articles
image: docker:git
services:
- docker:dind
variables:
CONTAINER_TEST_IMAGE: registry.gitlab.com/stoeps/$CI_PROJECT_NAME:$CI_BUILD_REF_NAME
CONTAINER_RELEASE_IMAGE: registry.gitlab.com/stoeps/$CI_PROJECT_NAME:latest
before_script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com
- git submodule sync --recursive
- git submodule update --init --recursive
stages:
- build
- test
- release
- conversion
- deploy
build:
stage: build
script:
- docker build -t $CONTAINER_TEST_IMAGE docker-asciidoctor
- docker push $CONTAINER_TEST_IMAGE
only:
changes:
- docker-asciidoctor/Dockerfile
refs:
- master
variables:
- $BUILDCONTAINER
test 1:
stage: test
script:
- echo "Run tests here"
- docker run -t --rm $CONTAINER_TEST_IMAGE asciidoctor -v | grep "Asciidoctor"
only:
changes:
- docker-asciidoctor/Dockerfile
refs:
- master
variables:
- $BUILDCONTAINER
test 2:
stage: test
script:
- docker run -t --rm $CONTAINER_TEST_IMAGE asciidoctor-revealjs -v
only:
changes:
- docker-asciidoctor/Dockerfile
refs:
- master
variables:
- $BUILDCONTAINER
release-image:
stage: release
script:
- echo "Tag Image and push to registry"
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
only:
changes:
- docker-asciidoctor/Dockerfile
refs:
- master
variables:
- $BUILDCONTAINER
pdf:personal:
stage: conversion
script:
- echo "Start Asciidoctor conversion"
- echo $CONTAINER_IMAGE:$CI_COMMIT_SHA
- docker run -t --rm -v $(pwd)/documents-personal:/documents/ -v $(pwd)/images:/images -v $(pwd)/scripts:/scripts $CONTAINER_RELEASE_IMAGE /scripts/pdf-conversion.sh
- cp documents-personal/*.pdf public/pdf-personal
artifacts:
name: "pdf-personal-$CI_COMMIT_TAG"
paths:
- public/pdf-personal
expire_in: 2 hours
except:
variables:
- $BUILDCONTAINER
pdf:work:
stage: conversion
script:
- echo "Start Asciidoctor conversion"
- echo $CONTAINER_IMAGE:$CI_COMMIT_SHA
- docker run -t --rm -v $(pwd)/documents-work:/documents/ -v $(pwd)/images:/images -v $(pwd)/scripts:/scripts -v $(pwd)/pdftheme:/pdftheme/ $CONTAINER_RELEASE_IMAGE /scripts/pdf-work-conversion.sh
- cp documents-work/*.pdf public/pdf-work
artifacts:
name: "pdf-work-$CI_COMMIT_TAG"
paths:
- public/pdf-work
expire_in: 2 hours
except:
variables:
- $BUILDCONTAINER
html:
stage: conversion
script:
- echo "Start Asciidoctor conversion"
- echo $CONTAINER_IMAGE:$CI_COMMIT_SHA
- docker run -t --rm -v $(pwd)/documents-work:/documents/ -v $(pwd)/images:/images -v $(pwd)/scripts:/scripts $CONTAINER_RELEASE_IMAGE /scripts/html-work-conversion.sh
- cp documents-work/*.html public/html-work
- docker run -t --rm -v $(pwd)/documents-personal:/documents/ -v $(pwd)/images:/images -v $(pwd)/scripts:/scripts $CONTAINER_RELEASE_IMAGE /scripts/html-conversion.sh
- cp documents-personal/*.html public/html-personal
artifacts:
name: "html-$CI_COMMIT_TAG"
paths:
- public/html-work
- public/html-personal
- images
expire_in: 2 hours
except:
variables:
- $BUILDCONTAINER
reveal:
stage: conversion
script:
- echo "Start Asciidoctor conversion"
- echo $CONTAINER_IMAGE:$CI_COMMIT_SHA
- docker run -t --rm -v $(pwd)/presentations:/documents/ -v $(pwd)/images:/images -v $(pwd)/scripts:/scripts $CONTAINER_RELEASE_IMAGE /scripts/reveal-conversion.sh
- cp presentations/*.html public/presentations
artifacts:
name: "html-$CI_COMMIT_TAG"
paths:
- public/presentations
- images
expire_in: 2 hours
except:
variables:
- $BUILDCONTAINER
pages:
stage: deploy
dependencies:
- html
- reveal
- pdf:personal
- pdf:work
script:
- cp -arvf images/* public/images/
- sh scripts/create-index.sh
- chmod +r public -R
artifacts:
paths:
- public
expire_in: 1 hour
only:
refs:
- master # this job will affect only the 'master' branch
except:
variables:
- $BUILDCONTAINER
#!/usr/bin/env bash
#
# Author: Christoph Stoettner
#
for i in /documents/*.adoc
do
asciidoctor \
-r asciidoctor-pdf \
-r asciidoctor-diagram \
-r asciidoctor-mathematical \
-b pdf \
-a pdf-stylesdir=/pdftheme \
-a pdf-style=work \
-a media=prepress \
"$i"
done
1 | Build pipeline ran successful |
2 | Failed execution |
3 | Download artifacts (Output formats) |
This presentation is build with
Asciidoctor
Reveal.js
Fedora is using Asciidoc for
https://docs.fedoraproject.org/en-US/docs/
Based on Antora
Antora creates documentation from multiple git repositories