Documentation With Any Editor
Christoph Stoettner
1 @stoeps #FrOSCon14 #DocumentationWithAnyEditor 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
2 @stoeps #FrOSCon14 #DocumentationWithAnyEditor My history of documentation 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
3 @stoeps #FrOSCon14 #DocumentationWithAnyEditor My needs 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
4 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Why did I switch the tools? 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
5 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Why not using a wiki? Edit from mobile o en a pain Documenting the Wiki itself? Not accessible when down Syntax different from one wiki to another Customer / PM o en needs something printed / printer friendly AND manual copy&paste
6 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Markdown and rst I started writing in Markdown Some so ware 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
7 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Asciidoc / Asciidoctor 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 https://github.com/asciidoctor/asciidoctor.org/blob/master/docs/_includes/asciidoc- vs-markdown.adoc
8 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Doctypes :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
9 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Syntax - Headings
:numbered: 1 1 Headings numbered
2 == H2 Headings without numbers === H3 ==== H4
:!numbered: 2
== H2 === H3 ==== H4
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
10 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Headings of blocks and images Can be used with images and all kind of blocks, no TOC entry
.Heading 1 1 Heading above Code block [source] 2 ---- Image heading ls -al ----
.Image 2 image::test.png[]
11 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Syntax - Lists === 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
12 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Links
https://www.stoeps.de[] 1 https://www.stoeps.de[Stoeps] 2
1 Shows just the link 2 Link text in brackets
13 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Images 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 a er image → inline image, double colon → figure double :
single :14 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Use Inline Icons You can add any Font Awesome Icon Enable in document header
:icons: font Some Examples
icon:twitter[] Twitter https://twitter.com[@stoeps] icon:linux[] Linux Icon icon:windows[] Windows Icon
15 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Admonition Blocks 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
16 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Admonition Blocks in Html and PDF NOTE: A note
TIP: Here is a tip
IMPORTANT: That's important
WARNING: Warning message
CAUTION: Caution, be careful
17 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Menus, Keys and Buttons
:experimental: 1
1 Following features need experimental set Menu, Button, Keys
.Copy Text menu:Edit[Copy Special > Text]
.Button Press kbd:[OK]
.Keyboard kbd:[Ctrl+C] to stop this.
18 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Sourcecode 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
19 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Including Files 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
20 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Example Include ...
Test
... Include in our asciidoc source[source, indent=0] ---- include::test.html[tags=stoeps] ---- Included source
Test
21 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Callouts in Sources [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
22 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Variables Definition
:variable: content 1 1 Generic definition :OS: Linux 2 2 Variable OS set to Linux :SLASH: / 3 3 Variable SLASH set to / Windows Version
:OS: Windows Server 2016 Datacenter Edition :SLASH: \ :VERSION: 0.8 Linux Version
:OS: Linux :SLASH: / :VERSION: 8.5.5.4
23 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Add Variables to extra file Include into main document (main.adoc) Use generic variable file for example to store OS differences Add additional one for project specific paths, hostnames
. 1 Main document ├── _attributes.asciidoc 2 ├── images Variables for Linux OS installations ├── include 3 Variables for Windows installations ├── main.adoc 1 4 Project specific variables ├── more.asciidoc ├── _variables-linux.asciidoc 2 ├── _variables_project.asciidoc 4 └── _variables-win.asciidoc 3
24 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Conditional Directives Within main document show different informations based on variables
:OS: Linux 1 1 Set OS = Linux ifeval::["{OS}" == "Linux"] 2 2 icon:linux[] rocks! If OS = Linux endif::[] 3 Set OS = Windows 4 If OS = Windows :OS: Windows 3 ifeval::["{OS}" == "Windows"] 4 icon:windows[] really? endif::[] :OS: Linux
25 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Including Diagrams https://asciidoctor.org/docs/asciidoctor-diagram/ Asciidoctor supports a lot of different formats ditaa plantuml O en enough to show a network or infrastructure overview Like Asciidoctor human readable
26 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Diagram - ditaa [ditaa] .... +------+ | Asciidoctor |------+ | diagram | | +------+ | PNG out ^ | | ditaa in | | v +------+ +------+----+ /------\ |c9CF | --+ Asciidoctor +--> |c9CC | |Document| +------+ | Beautiful | | {d}| | !magic! | | Output | +---+----+ +------+ \------/ ....
27 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Plantuml
[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 ....
28 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Plantuml Simple Flowdiagram [plantuml] .... start
if (Graphviz installed?) then (yes) :process all\ndiagrams; else (no) :process only __sequence__ and __activity__ diagrams; endif
stop ....
29 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Tables .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
30 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Putting everything together 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 https://gitlab.com/stoeps/gpn19-documentation
31 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Main document (main.adoc) - header
= Example Project Documentation 1 1 Document title :author: Christoph Stoettner 2 :email: [email protected] Language :revnumber: 1.0 3 Enable experimental features :revdate: 2018-08-24 4 Title logo (for pdf title page) :revremark: Froscon 2018 :encoding: utf-8 5 Create table of contents :lang: en 2 6 Default images directory :experimental: 3 7 Use Font Awesome Icons :title-logo-image: image::logo.png[] 4 8 :toc: 5 Use rouge for Syntax Highlighting :imagesdir: images 6 9 Headings numbered :doctype: article 10 Translation file for built-in labels, so the labels for :icons: font 7 language used in (2) will be inserted :source-highlighter: rouge 8 :quick-uri: https://www.stoeps.de :numbered: 9 include::_variables-linux.asciidoc[] include::_variables-project.asciidoc[] include::_attributes.asciidoc[] 10
32 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Attribute (translation of built-in labels) Example for german labels
// 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::[]
33 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Preface First paragraph a er 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
34 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Conditions to show updated informations === 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::[]
35 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Different Operating Systems 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
36 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Including Configuration Files Working to get customers to commit configuration to internal git servers Adding these repositories to documentation repository Git Submodules
git add submodule https://internal.gitserver.example.org/appserver/mainconfig.git
Git directories within repositories
37 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Build Outputs Lots of different Outputs Html 5 PDF ePub Docbook Confluence Wiki Reveal JS Presentation A huge amount of outputs: https://doctoolchain.github.io/docToolchain/
38 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Use Themes You can build your own themes PDF https://github.com/asciidoctor/asciidoctor- pdf/blob/master/docs/theming-guide.adoc HTML CSS https://themes.asciidoctor.org
39 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Editors Best: you can use any editor on any device Syntax Highlighting in the most important ones VIM Emacs Notepad++ VSCode|VSCodium, Atom Documentation on editors
On Windows, stay away from Notepad and Wordpad because they produce plain text which is not cross-platform friendly.
40 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Mobile I use git for all documents Version Control Good mobile clients (for small adjustments) Android Termux Vim Git Browser interface (Github, Gitlab)
41 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Preview (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 Makefile convert your documents with make Guardfile with Guard Run make everytime when file is saved Very powerful when you finalize documents or presentations
42 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Convert your documents 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
43 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Docker-Asciidoctor https://github.com/asciidoctor/docker-asciidoctor https://hub.docker.com/r/asciidoctor/docker-asciidoctor/ 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
44 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Docker command explained # 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 a er 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!
45 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Different Outputs with Docker container Html
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor main.adoc Html with Diagram
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor -r asciidoctor-diagram main.adoc PDF with Diagram
docker run --rm -v $(pwd):/documents/ asciidoctor/asciidoctor asciidoctor-pdf -r asciidoctor-diagram main.adoc Create page in Confluence Wiki
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
46 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Gradle https://github.com/asciidoctor/asciidoctor-gradle-examples 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
47 @stoeps #FrOSCon14 #DocumentationWithAnyEditor CI/CD with Gitlab 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
48 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Repository . ├── public ├── docker-asciidoctor (submodule) │ ├── html-personal ├── documents-personal │ ├── html-work │ ├── basic-example.adoc │ ├── images ├── documents-work │ ├── pdf-personal │ ├── basic-example.adoc │ ├── pdf-work ├── images │ └── presentations │ └── logo.png ├── README.adoc ├── LICENSE ├── scripts ├── pdftheme │ ├── create-index.sh │ ├── logo.png │ ├── html-conversion.sh │ ├── personal-theme.yml │ ├── html-work-conversion.sh │ └── work-theme.yml │ ├── pdf-conversion.sh ├── presentations │ ├── pdf-work-conversion.sh │ └── slidedeck.adoc │ └── reveal-conversion.sh └── wiki-articles
49 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (1)
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:
50 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (2)
- 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:
51 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (3)
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/ - 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
52 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (4)
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/ $CONTAIN - 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 - 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/ - cp documents-personal/*.html public/html-personal artifacts: name: "html-$CI_COMMIT_TAG" paths: - public/html-work - public/html-personal
53 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (5)
- 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/revea - 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
54 @stoeps #FrOSCon14 #DocumentationWithAnyEditor .gitlab-ci.yml (6)
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
55 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Example conversion script #!/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
56 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Gitlab Pipeline
1 Build pipeline ran successful 2 Failed execution 3 Download artifacts (Output formats)
57 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Demo
58 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Additional informations 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
59 @stoeps #FrOSCon14 #DocumentationWithAnyEditor Links https://gitlab.com/stoeps/gpn19-documentation Asciidoc Syntax Quick Reference https://doctoolchain.github.io/docToolchain/ Asciidoc Cheatsheet Using AsciiDoc and Asciidoctor to write documentation Mr. Haki Blog
60 @stoeps #FrOSCon14 #DocumentationWithAnyEditor